00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "elfstruc.h"
00022 #include "log.h"
00023 #include "htelf.h"
00024 #include "htelfhd.h"
00025 #include "htelfshs.h"
00026 #include "htelfphs.h"
00027 #include "htelfsym.h"
00028 #include "htelfrel.h"
00029 #include "htelfimg.h"
00030 #include "htendian.h"
00031 #include "htexcept.h"
00032 #include "htiobox.h"
00033 #include "stream.h"
00034 #include "tools.h"
00035
00036 #include "elfstruc.h"
00037
00038 #include <stdlib.h>
00039
00040 static format_viewer_if *htelf_ifs[] = {
00041 &htelfheader_if,
00042 &htelfsectionheaders_if,
00043 &htelfprogramheaders_if,
00044 &htelfimage_if,
00045 0
00046 };
00047
00048 static ht_view *htelf_init(bounds *b, ht_streamfile *file, ht_format_group *format_group)
00049 {
00050 FILEOFS header_ofs = 0;
00051 ELF_HEADER header;
00052
00053 if (file->seek(header_ofs) != 0) return NULL;
00054 if (file->read(&header, sizeof header) != sizeof header) return NULL;
00055
00056 if ((header.e_ident[ELF_EI_MAG0]!=ELFMAG0) || (header.e_ident[ELF_EI_MAG1]!=ELFMAG1)
00057 || (header.e_ident[ELF_EI_MAG2]!=ELFMAG2) || (header.e_ident[ELF_EI_MAG3]!=ELFMAG3))
00058 return NULL;
00059 switch (header.e_ident[ELF_EI_DATA]) {
00060 case ELFDATA2LSB:
00061 case ELFDATA2MSB:
00062 break;
00063 default:
00064 LOG_EX(LOG_WARN, "File seems to be ELF. But byte-order"
00065 " (ELF_EI_DATA) 0x%02x is unsupported. (byte at offset=0x%x)",
00066 header.e_ident[ELF_EI_DATA], header_ofs+5);
00067 return NULL;
00068 }
00069 switch (header.e_ident[ELF_EI_CLASS]) {
00070 case ELFCLASS32:
00071 case ELFCLASS64:
00072 break;
00073 default:
00074 LOG_EX(LOG_WARN, "File seems to be ELF. But class-value"
00075 " (ELF_EI_CLASS) 0x%02x is unsupported. (byte at offset=0x%x)",
00076 header.e_ident[ELF_EI_CLASS], header_ofs+4);
00077 return NULL;
00078 }
00079
00080 try {
00081 ht_elf *g = new ht_elf();
00082 g->init(b, file, htelf_ifs, format_group, header_ofs);
00083 return g;
00084 } catch (ht_exception *x) {
00085 errorbox("error while reading ELF: %s", x->what());
00086 delete x;
00087 return NULL;
00088 }
00089 }
00090
00091 format_viewer_if htelf_if = {
00092 htelf_init,
00093 0
00094 };
00095
00096
00097 static int compare_keys_sectionAndIdx(Object *key_a, Object *key_b)
00098 {
00099 sectionAndIdx *a = (sectionAndIdx*)key_a;
00100 sectionAndIdx *b = (sectionAndIdx*)key_b;
00101 if (a->secidx == b->secidx) return a->symidx - b->symidx;
00102 return a->secidx - b->secidx;
00103 }
00104
00105 bool isValidELFSectionIdx(ht_elf_shared_data *elf_shared, int idx)
00106 {
00107 return (idx > 0) && (idx<(int)elf_shared->sheaders.count);
00108 }
00109
00110
00111
00112
00113 void ht_elf::init(bounds *b, ht_streamfile *f, format_viewer_if **ifs, ht_format_group *format_group, FILEOFS header_ofs)
00114 {
00115 ht_format_group::init(b, VO_SELECTABLE | VO_BROWSABLE | VO_RESIZE, DESC_ELF, f, false, true, 0, format_group);
00116 VIEW_DEBUG_NAME("ht_elf");
00117
00118 LOG("%s: ELF: found header at %08x", file->get_filename(), header_ofs);
00119
00120 ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)malloc(sizeof(ht_elf_shared_data));
00121
00122 shared_data = elf_shared;
00123 elf_shared->header_ofs = header_ofs;
00124 elf_shared->shnames = NULL;
00125 elf_shared->symtables = 0;
00126 elf_shared->reloctables = 0;
00127 elf_shared->v_image = NULL;
00128 elf_shared->shrelocs = NULL;
00129 elf_shared->fake_undefined_shidx = 0;
00130 elf_shared->undefined2fakeaddr = NULL;
00131
00132
00133 if (file->seek(header_ofs)) throw new ht_msg_exception("seek error");
00134 if (file->read(&elf_shared->ident, sizeof elf_shared->ident) != sizeof elf_shared->ident)
00135 throw new ht_msg_exception("read error");
00136 switch (elf_shared->ident.e_ident[ELF_EI_DATA]) {
00137 case ELFDATA2LSB:
00138 elf_shared->byte_order = little_endian;
00139 break;
00140 case ELFDATA2MSB:
00141 elf_shared->byte_order = big_endian;
00142 break;
00143 }
00144
00145 switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00146 case ELFCLASS32: {
00147 if (file->read(&elf_shared->header32, sizeof elf_shared->header32)
00148 != sizeof elf_shared->header32)
00149 throw new ht_msg_exception("read error");
00150 create_host_struct(&elf_shared->header32, ELF_HEADER32_struct, elf_shared->byte_order);
00151
00152 elf_shared->sheaders.count=elf_shared->header32.e_shnum;
00153 elf_shared->sheaders.sheaders32=(ELF_SECTION_HEADER32*)malloc(elf_shared->sheaders.count*sizeof *elf_shared->sheaders.sheaders32);
00154 if (file->seek(header_ofs+elf_shared->header32.e_shoff)) throw new ht_msg_exception("seek error");
00155 if (file->read(elf_shared->sheaders.sheaders32, elf_shared->sheaders.count*sizeof *elf_shared->sheaders.sheaders32)
00156 != elf_shared->sheaders.count*sizeof *elf_shared->sheaders.sheaders32)
00157 throw new ht_msg_exception("read error");
00158 for (uint i=0; i<elf_shared->sheaders.count; i++) {
00159 ELF_SECTION_HEADER32 a = elf_shared->sheaders.sheaders32[i];
00160 create_host_struct(elf_shared->sheaders.sheaders32+i, ELF_SECTION_HEADER32_struct, elf_shared->byte_order);
00161 }
00162
00163
00164 elf_shared->pheaders.count=elf_shared->header32.e_phnum;
00165 elf_shared->pheaders.pheaders32=(ELF_PROGRAM_HEADER32*)malloc(elf_shared->pheaders.count*sizeof *elf_shared->pheaders.pheaders32);
00166 if (file->seek(header_ofs+elf_shared->header32.e_phoff)) throw new ht_msg_exception("seek error");
00167 if (file->read(elf_shared->pheaders.pheaders32, elf_shared->pheaders.count*sizeof *elf_shared->pheaders.pheaders32)
00168 != elf_shared->pheaders.count*sizeof *elf_shared->pheaders.pheaders32)
00169 throw new ht_msg_exception("read error");
00170 for (uint i=0; i<elf_shared->pheaders.count; i++) {
00171 create_host_struct(elf_shared->pheaders.pheaders32+i, ELF_PROGRAM_HEADER32_struct, elf_shared->byte_order);
00172 }
00173
00174 if (elf_shared->header32.e_type == ELF_ET_REL) {
00175
00176 try {
00177 fake_undefined_symbols32();
00178 } catch (ht_exception *x) {
00179 errorbox("error while faking undefined ELF symbols: %s", x->what());
00180 delete x;
00181 }
00182
00183
00184 try {
00185 auto_relocate32();
00186 } catch (ht_exception *x) {
00187 errorbox("error while auto-relocating ELF symbols: %s", x->what());
00188 delete x;
00189 }
00190 }
00191 break;
00192 }
00193 case ELFCLASS64: {
00194 if (file->read(&elf_shared->header64, sizeof elf_shared->header64)
00195 != sizeof elf_shared->header64)
00196 throw new ht_msg_exception("read error");
00197 create_host_struct(&elf_shared->header64, ELF_HEADER64_struct, elf_shared->byte_order);
00198
00199 elf_shared->sheaders.count=elf_shared->header64.e_shnum;
00200 elf_shared->sheaders.sheaders64=(ELF_SECTION_HEADER64*)malloc(elf_shared->sheaders.count*sizeof *elf_shared->sheaders.sheaders64);
00201
00202 if (file->seek(header_ofs+elf_shared->header64.e_shoff.lo)) throw new ht_msg_exception("seek error");
00203 if (file->read(elf_shared->sheaders.sheaders64, elf_shared->sheaders.count*sizeof *elf_shared->sheaders.sheaders64)
00204 != elf_shared->sheaders.count*sizeof *elf_shared->sheaders.sheaders64)
00205 throw new ht_msg_exception("read error");
00206 for (uint i=0; i<elf_shared->sheaders.count; i++) {
00207 ELF_SECTION_HEADER64 a = elf_shared->sheaders.sheaders64[i];
00208 create_host_struct(elf_shared->sheaders.sheaders64+i, ELF_SECTION_HEADER64_struct, elf_shared->byte_order);
00209 }
00210
00211
00212 elf_shared->pheaders.count=elf_shared->header64.e_phnum;
00213 elf_shared->pheaders.pheaders64=(ELF_PROGRAM_HEADER64*)malloc(elf_shared->pheaders.count*sizeof *elf_shared->pheaders.pheaders64);
00214
00215 if (file->seek(header_ofs+elf_shared->header64.e_phoff.lo)) throw new ht_msg_exception("seek error");
00216 if (file->read(elf_shared->pheaders.pheaders64, elf_shared->pheaders.count*sizeof *elf_shared->pheaders.pheaders64)
00217 != elf_shared->pheaders.count*sizeof *elf_shared->pheaders.pheaders64)
00218 throw new ht_msg_exception("read error");
00219 for (uint i=0; i<elf_shared->pheaders.count; i++) {
00220 create_host_struct(elf_shared->pheaders.pheaders64+i, ELF_PROGRAM_HEADER64_struct, elf_shared->byte_order);
00221 }
00222
00223
00224
00225
00226
00227 break;
00228 }
00229 }
00230
00231 ht_format_group::init_ifs(ifs);
00232 while (init_if(&htelfsymboltable_if)) elf_shared->symtables++;
00233 while (init_if(&htelfreloctable_if)) elf_shared->reloctables++;
00234 }
00235
00236 void ht_elf::done()
00237 {
00238 ht_format_group::done();
00239 ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)shared_data;
00240 if (elf_shared->shnames) {
00241 for (uint i=0; i < elf_shared->sheaders.count; i++)
00242 free(elf_shared->shnames[i]);
00243 free(elf_shared->shnames);
00244 }
00245 if (elf_shared->shrelocs) free(elf_shared->shrelocs);
00246 switch (elf_shared->ident.e_ident[ELF_EI_CLASS]) {
00247 case ELFCLASS32:
00248 if (elf_shared->sheaders.sheaders32) free(elf_shared->sheaders.sheaders32);
00249 if (elf_shared->pheaders.pheaders32) free(elf_shared->pheaders.pheaders32);
00250 break;
00251 case ELFCLASS64:
00252 if (elf_shared->sheaders.sheaders64) free(elf_shared->sheaders.sheaders64);
00253 if (elf_shared->pheaders.pheaders64) free(elf_shared->pheaders.pheaders64);
00254 break;
00255 }
00256 if (elf_shared->undefined2fakeaddr) {
00257 elf_shared->undefined2fakeaddr->destroy();
00258 delete elf_shared->undefined2fakeaddr;
00259 }
00260 free(elf_shared);
00261 }
00262
00263 uint ht_elf::find_reloc_section_for(uint si)
00264 {
00265 ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)shared_data;
00266
00267 ELF_SECTION_HEADER32 *s=elf_shared->sheaders.sheaders32;
00268 for (uint i=0; i<elf_shared->sheaders.count; i++) {
00269 if (((s->sh_type==ELF_SHT_REL) || (s->sh_type==ELF_SHT_RELA)) &&
00270 (s->sh_info==si)) {
00271 return i;
00272 }
00273 s++;
00274 }
00275 return 0;
00276 }
00277
00278 #define INVENT_BASE 0x100000
00279 #define INVENT_STEPPING 0x100000
00280 #define INVENT_LIMIT 0xffffffff
00281
00282 static elf32_addr elf32_invent_address(uint si, ELF_SECTION_HEADER32 *s, uint scount, elf32_addr base = INVENT_BASE)
00283 {
00284 elf32_addr a = base;
00285 assert(s[si].sh_addr == 0);
00286 while (a<INVENT_LIMIT-s[si].sh_size) {
00287 bool ok = true;
00288 for (uint i=0; i<scount; i++) {
00289 if ((a >= s[i].sh_addr)
00290 && (a < s[i].sh_addr+s[i].sh_size)) {
00291 ok = false;
00292 break;
00293 }
00294 }
00295 if (ok) return a;
00296 a += INVENT_STEPPING;
00297 }
00298 return 0;
00299 }
00300
00301 void ht_elf::relocate_section(ht_reloc_file *f, uint si, uint rsi, elf32_addr a)
00302 {
00303
00304 ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)shared_data;
00305 ELF_SECTION_HEADER32 *s=elf_shared->sheaders.sheaders32;
00306
00307 FILEOFS relh = s[rsi].sh_offset;
00308
00309 uint symtabidx = s[rsi].sh_link;
00310 if (!isValidELFSectionIdx(elf_shared, symtabidx)) throw new ht_msg_exception("invalid symbol table index %d", symtabidx);
00311 FILEOFS symh = elf_shared->sheaders.sheaders32[symtabidx].sh_offset;
00312
00313 if (s[rsi].sh_type != ELF_SHT_REL) throw new ht_msg_exception(
00314 "invalid section type for section %d (expeecting %d)",
00315 rsi, ELF_SHT_REL);
00316
00317 uint relnum = s[rsi].sh_size / sizeof (ELF_REL32);
00318 for (uint i=0; i<relnum; i++) {
00319
00320 ELF_REL32 r;
00321 if (file->seek(relh+i*sizeof r)) throw new ht_msg_exception("seek error");
00322 if (file->read(&r, sizeof r) != sizeof r)
00323 throw new ht_msg_exception("read error reading relocations for section %d [REL32]", si);
00324 create_host_struct(&r, ELF_REL32_struct, elf_shared->byte_order);
00325
00326
00327 uint symbolidx = ELF32_R_SYM(r.r_info);
00328 ELF_SYMBOL32 sym;
00329 if (file->seek(symh+symbolidx*sizeof (ELF_SYMBOL32))) throw new ht_msg_exception("seek error");
00330 if (file->read(&sym, sizeof sym) != sizeof sym)
00331 throw new ht_msg_exception("read error reading relocations for section %d [SYM-LOOKUP]", si);
00332 create_host_struct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order);
00333
00334
00335 uint32 A = 0;
00336 uint32 P = r.r_offset+s[si].sh_addr;
00337 uint32 S;
00338 if ((sym.st_shndx > 0) && (sym.st_shndx < elf_shared->sheaders.count)) {
00339 S = sym.st_value + elf_shared->shrelocs[sym.st_shndx].relocAddr;
00340 } else if (elf_shared->fake_undefined_shidx >= 0) {
00341 sectionAndIdx s(symtabidx, symbolidx);
00342 ht_data_uint32 *addr = (ht_data_uint32 *)elf_shared->undefined2fakeaddr->get(&s);
00343 if (addr) {
00344 S = addr->value;
00345 } else continue;
00346 } else {
00347
00348
00349 continue;
00350 }
00351 Object *z = new ht_elf32_reloc_entry(
00352 ELF32_R_TYPE(r.r_info), A, P, S);
00353 f->insert_reloc(r.r_offset+s[si].sh_offset, z);
00354 }
00355 }
00356
00357 #define FAKE_SECTION_BASEADDR 0x4acc0000
00358
00359 void ht_elf::fake_undefined_symbols32()
00360 {
00361 ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)shared_data;
00362
00363 elf_shared->fake_undefined_shidx = elf_shared->sheaders.count;
00364 elf_shared->sheaders.count++;
00365 elf_shared->sheaders.sheaders32 = (ELF_SECTION_HEADER32*)
00366 realloc(elf_shared->sheaders.sheaders32, sizeof (ELF_SECTION_HEADER32)* elf_shared->sheaders.count);
00367
00368 ELF_SECTION_HEADER32 *s = elf_shared->sheaders.sheaders32;
00369 s[elf_shared->fake_undefined_shidx].sh_name = 0;
00370 s[elf_shared->fake_undefined_shidx].sh_type = ELF_SHT_NOBITS;
00371 s[elf_shared->fake_undefined_shidx].sh_flags = ELF_SHF_WRITE | ELF_SHF_ALLOC;
00372 s[elf_shared->fake_undefined_shidx].sh_addr = 0;
00373 s[elf_shared->fake_undefined_shidx].sh_offset = 0;
00374 s[elf_shared->fake_undefined_shidx].sh_size = 0;
00375 s[elf_shared->fake_undefined_shidx].sh_link = 0;
00376 s[elf_shared->fake_undefined_shidx].sh_info = 0;
00377 s[elf_shared->fake_undefined_shidx].sh_addralign = 0;
00378 s[elf_shared->fake_undefined_shidx].sh_entsize = 0;
00379 elf32_addr a = elf32_invent_address(elf_shared->fake_undefined_shidx,
00380 s, elf_shared->sheaders.count, FAKE_SECTION_BASEADDR);
00381 s[elf_shared->fake_undefined_shidx].sh_addr = a;
00382 LOG("fake section %d", elf_shared->fake_undefined_shidx);
00383
00384 elf_shared->undefined2fakeaddr = new ht_stree();
00385 ((ht_stree*)elf_shared->undefined2fakeaddr)->init(compare_keys_sectionAndIdx);
00386 uint32 nextFakeAddr = FAKE_SECTION_BASEADDR;
00387 for (uint secidx = 0; secidx < elf_shared->sheaders.count; secidx++) {
00388 if (elf_shared->sheaders.sheaders32[secidx].sh_type == ELF_SHT_SYMTAB) {
00389 FILEOFS symh = elf_shared->sheaders.sheaders32[secidx].sh_offset;
00390 uint symnum = elf_shared->sheaders.sheaders32[secidx].sh_size / sizeof (ELF_SYMBOL32);
00391 for (uint symidx = 1; symidx < symnum; symidx++) {
00392 ELF_SYMBOL32 sym;
00393 if (file->seek(symh+symidx*sizeof (ELF_SYMBOL32))) throw new ht_msg_exception("seek error");
00394 if (file->read(&sym, sizeof sym))
00395 throw new ht_msg_exception("read error [looking up symbol]");
00396 create_host_struct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order);
00397 if (sym.st_shndx == ELF_SHN_UNDEF) {
00398 elf_shared->undefined2fakeaddr->insert(
00399 new sectionAndIdx(secidx, symidx),
00400 new ht_data_uint32(nextFakeAddr));
00401 nextFakeAddr += 4;
00402 }
00403 }
00404 }
00405 }
00406 elf_shared->fake_undefined_size = nextFakeAddr-FAKE_SECTION_BASEADDR;
00407 s[elf_shared->fake_undefined_shidx].sh_size = elf_shared->fake_undefined_size;
00408 }
00409
00410 void ht_elf::auto_relocate32()
00411 {
00412 ht_elf32_reloc_file *rf = new ht_elf32_reloc_file();
00413 rf->init(file, false, (ht_elf_shared_data*)shared_data);
00414
00415 bool reloc_needed = false;
00416
00417 ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)shared_data;
00418
00419 ELF_SECTION_HEADER32 *s=elf_shared->sheaders.sheaders32;
00420
00421 elf_shared->shrelocs = (ht_elf_reloc_section32*)malloc(elf_shared->sheaders.count * sizeof (ht_elf_reloc_section32));
00422
00423
00424 for (uint i=0; i<elf_shared->sheaders.count; i++) {
00425 elf_shared->shrelocs[i].relocAddr = 0;
00426 if ((s[i].sh_type == ELF_SHT_PROGBITS) && (s[i].sh_addr == 0)) {
00427 uint j = find_reloc_section_for(i);
00428 if (j) {
00429 elf32_addr a = elf32_invent_address(i, s, elf_shared->sheaders.count);
00430 if (a) {
00431 reloc_needed = true;
00432
00433 s[i].sh_addr = a;
00434 elf_shared->shrelocs[i].relocAddr = a;
00435 elf_shared->shrelocs[i].relocShIdx = j;
00436 }
00437 }
00438 }
00439 }
00440
00441
00442 for (uint i=0; i<elf_shared->sheaders.count; i++) {
00443 if (elf_shared->shrelocs[i].relocAddr) {
00444
00445 try {
00446 relocate_section(rf, i, elf_shared->shrelocs[i].relocShIdx, elf_shared->shrelocs[i].relocAddr);
00447 } catch (ht_exception *x) {
00448 LOG("error while relocating section %d: %s", i, x->what());
00449 delete x;
00450 }
00451 }
00452 }
00453
00454 if (reloc_needed) {
00455 rf->finalize();
00456 own_file = true;
00457 file = rf;
00458 LOG("%s: ELF: relocation layer enabled (invented relocation addresses)", file->get_filename());
00459 } else {
00460 free(elf_shared->shrelocs);
00461 elf_shared->shrelocs = NULL;
00462 rf->done();
00463 delete rf;
00464 }
00465 }
00466
00467 bool ht_elf::loc_enum_next(ht_format_loc *loc)
00468 {
00469 ht_elf_shared_data *sh = (ht_elf_shared_data*)shared_data;
00470 if (loc_enum) {
00471 loc->name = "elf";
00472 loc->start = sh->header_ofs;
00473 loc->length = file->get_size()-loc->start;
00474
00475 loc_enum = false;
00476 return true;
00477 }
00478 return false;
00479 }
00480
00481 void ht_elf::loc_enum_start()
00482 {
00483 loc_enum = true;
00484 }
00485
00486
00487
00488
00489 bool elf_phys_and_mem_section(elf_section_header *sh, uint elfclass)
00490 {
00491 switch (elfclass) {
00492 case ELFCLASS32: {
00493 ELF_SECTION_HEADER32 *s = &sh->sheaders32;
00494 return (s->sh_type == ELF_SHT_PROGBITS) && s->sh_addr;
00495 }
00496 case ELFCLASS64: {
00497 ELF_SECTION_HEADER64 *s = &sh->sheaders64;
00498 return ((s->sh_type==ELF_SHT_PROGBITS) && ((s->sh_addr.lo!=0) || (s->sh_addr.hi!=0)));
00499 }
00500 }
00501 return false;
00502 }
00503
00504 bool elf_valid_section(elf_section_header *sh, uint elfclass)
00505 {
00506 switch (elfclass) {
00507 case ELFCLASS32: {
00508 ELF_SECTION_HEADER32 *s = &sh->sheaders32;
00509 return (((s->sh_type==ELF_SHT_PROGBITS) || (s->sh_type==ELF_SHT_NOBITS)) && (s->sh_addr!=0));
00510 }
00511 case ELFCLASS64: {
00512 ELF_SECTION_HEADER64 *s = &sh->sheaders64;
00513 return (((s->sh_type==ELF_SHT_PROGBITS) || (s->sh_type==ELF_SHT_NOBITS)) && ((s->sh_addr.lo!=0) || (s->sh_addr.hi!=0)));
00514 }
00515 }
00516 return false;
00517 }
00518
00519 bool elf_addr_to_ofs(elf_section_headers *section_headers, uint elfclass, ELFAddress addr, dword *ofs)
00520 {
00521 switch (elfclass) {
00522 case ELFCLASS32: {
00523 ELF_SECTION_HEADER32 *s = section_headers->sheaders32;
00524 for (uint i=0; i < section_headers->count; i++) {
00525 if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && (addr.a32 >= s->sh_addr) && (addr.a32 < s->sh_addr+s->sh_size)) {
00526 *ofs = addr.a32 - s->sh_addr + s->sh_offset;
00527 return true;
00528 }
00529 s++;
00530 }
00531 break;
00532 }
00533 case ELFCLASS64: {
00534 ELF_SECTION_HEADER64 *s = section_headers->sheaders64;
00535 for (uint i=0; i < section_headers->count; i++) {
00536 if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && (qword_cmp(addr.a64, s->sh_addr) >= 0) && (addr.a64 < s->sh_addr + s->sh_size)) {
00537 qword qofs = addr.a64 - s->sh_addr + s->sh_offset;
00538 *ofs = qofs.lo;
00539 return true;
00540 }
00541 s++;
00542 }
00543 break;
00544 }
00545 }
00546 return false;
00547 }
00548
00549 bool elf_addr_to_section(elf_section_headers *section_headers, uint elfclass, ELFAddress addr, int *section)
00550 {
00551 switch (elfclass) {
00552 case ELFCLASS32: {
00553 ELF_SECTION_HEADER32 *s = section_headers->sheaders32;
00554 for (uint i = 0; i < section_headers->count; i++) {
00555 if ((elf_valid_section((elf_section_header*)s, elfclass)) && (addr.a32 >= s->sh_addr) && (addr.a32 < s->sh_addr + s->sh_size)) {
00556 *section = i;
00557 return true;
00558 }
00559 s++;
00560 }
00561 break;
00562 }
00563 case ELFCLASS64: {
00564 ELF_SECTION_HEADER64 *s = section_headers->sheaders64;
00565 for (uint i = 0; i < section_headers->count; i++) {
00566 if ((elf_valid_section((elf_section_header*)s, elfclass)) && (qword_cmp(addr.a64, s->sh_addr) >= 0) && (addr.a64 < s->sh_addr + s->sh_size)) {
00567 *section = i;
00568 return true;
00569 }
00570 s++;
00571 }
00572 break;
00573 }
00574 }
00575 return false;
00576 }
00577
00578 bool elf_addr_is_valid(elf_section_headers *section_headers, uint elfclass, ELFAddress addr)
00579 {
00580 switch (elfclass) {
00581 case ELFCLASS32: {
00582 ELF_SECTION_HEADER32 *s = section_headers->sheaders32;
00583 for (uint i=0; i<section_headers->count; i++) {
00584 if ((elf_valid_section((elf_section_header*)s, elfclass)) && (addr.a32 >= s->sh_addr) && (addr.a32 < s->sh_addr + s->sh_size)) {
00585 return true;
00586 }
00587 s++;
00588 }
00589 break;
00590 }
00591 case ELFCLASS64: {
00592 ELF_SECTION_HEADER64 *s = section_headers->sheaders64;
00593 for (uint i=0; i<section_headers->count; i++) {
00594 if ((elf_valid_section((elf_section_header*)s, elfclass)) && (qword_cmp(addr.a64, s->sh_addr) >= 0) && (addr.a64 < s->sh_addr + s->sh_size)) {
00595 return true;
00596 }
00597 s++;
00598 }
00599 break;
00600 }
00601 }
00602 return false;
00603 }
00604
00605 bool elf_addr_is_physical(elf_section_headers *section_headers, uint elfclass, ELFAddress addr)
00606 {
00607 return false;
00608 }
00609
00610
00611
00612
00613
00614
00615 bool elf_ofs_to_addr(elf_section_headers *section_headers, uint elfclass, dword ofs, ELFAddress *addr)
00616 {
00617 switch (elfclass) {
00618 case ELFCLASS32: {
00619 ELF_SECTION_HEADER32 *s = section_headers->sheaders32;
00620 for (uint i = 0; i < section_headers->count; i++) {
00621 if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && (ofs>=s->sh_offset) && (ofs<s->sh_offset+s->sh_size)) {
00622 addr->a32 = ofs - s->sh_offset + s->sh_addr;
00623 return true;
00624 }
00625 s++;
00626 }
00627 break;
00628 }
00629 case ELFCLASS64: {
00630 ELF_SECTION_HEADER64 *s = section_headers->sheaders64;
00631 qword qofs = to_qword(ofs);
00632 for (uint i = 0; i < section_headers->count; i++) {
00633 if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && (qword_cmp(qofs, s->sh_offset)>=0) && (qofs < s->sh_offset + s->sh_size)) {
00634 addr->a64 = qofs - s->sh_offset + s->sh_addr;
00635 return true;
00636 }
00637 s++;
00638 }
00639 break;
00640 }
00641 }
00642 return false;
00643 }
00644
00645 bool elf_ofs_to_section(elf_section_headers *section_headers, uint elfclass, dword ofs, int *section)
00646 {
00647 switch (elfclass) {
00648 case ELFCLASS32: {
00649 ELF_SECTION_HEADER32 *s=section_headers->sheaders32;
00650 for (uint i=0; i<section_headers->count; i++) {
00651 if ((elf_valid_section((elf_section_header*)s, elfclass)) && (ofs >= s->sh_offset) && (ofs<s->sh_offset+s->sh_size)) {
00652 *section = i;
00653 return true;
00654 }
00655 s++;
00656 }
00657 break;
00658 }
00659 case ELFCLASS64: {
00660 ELF_SECTION_HEADER64 *s = section_headers->sheaders64;
00661 qword qofs;
00662 qofs.hi = 0; qofs.lo = ofs;
00663 for (uint i=0; i < section_headers->count; i++) {
00664 if ((elf_valid_section((elf_section_header*)s, elfclass)) && (qword_cmp(qofs, s->sh_offset)>=0) && (qofs < s->sh_offset + s->sh_size)) {
00665 *section = i;
00666 return true;
00667 }
00668 s++;
00669 }
00670 break;
00671 }
00672 }
00673 return false;
00674 }
00675
00676 bool elf_ofs_to_addr_and_section(elf_section_headers *section_headers, uint elfclass, dword ofs, ELFAddress *addr, int *section)
00677 {
00678 return false;
00679 }
00680
00681
00682
00683
00684
00685 ht_elf32_reloc_entry::ht_elf32_reloc_entry(uint t, uint32 A, uint32 P, uint32 S)
00686 {
00687 type = t;
00688 switch (type) {
00689 case ELF_R_386_32:
00690 relocs.r_32 = S+A;
00691 break;
00692 case ELF_R_386_PC32:
00693 relocs.r_pc32 = S+A-P;
00694 break;
00695 }
00696 }
00697
00698
00699
00700
00701
00702 void ht_elf32_reloc_file::init(ht_streamfile *s, bool os, ht_elf_shared_data *d)
00703 {
00704 ht_reloc_file::init(s, os);
00705 data = d;
00706 }
00707
00708 void ht_elf32_reloc_file::reloc_apply(Object *reloc, byte *buf)
00709 {
00710 ht_elf32_reloc_entry *e=(ht_elf32_reloc_entry*)reloc;
00711
00712 switch (e->type) {
00713 case ELF_R_386_32: {
00714 uint32 v = create_host_int(buf, 4, data->byte_order);
00715 v += e->relocs.r_32;
00716 create_foreign_int(buf, v, 4, data->byte_order);
00717 break;
00718 }
00719 case ELF_R_386_PC32: {
00720 uint32 v = create_host_int(buf, 4, data->byte_order);
00721 v += e->relocs.r_pc32;
00722 create_foreign_int(buf, v, 4, data->byte_order);
00723 break;
00724 }
00725 }
00726 }
00727
00728 bool ht_elf32_reloc_file::reloc_unapply(Object *reloc, byte *data)
00729 {
00730 return false;
00731
00732 }