diff --git a/libr/bin/format/elf/elf.c b/libr/bin/format/elf/elf.c index 73ff23a6eb12d0..64f46ea34449c8 100644 --- a/libr/bin/format/elf/elf.c +++ b/libr/bin/format/elf/elf.c @@ -5242,6 +5242,8 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { GotPltBounds ri = {0}; RBinElfSection *s; + ut64 di0 = UT64_MAX; + ut64 di1 = UT64_MAX; // find got/plt section bounadries r_vector_foreach (&eo->g_sections, s) { if (!strcmp (s->name, ".got")) { @@ -5249,8 +5251,14 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { ri.got_min = s->offset; ri.got_max = s->offset + s->size; ri.got_va = s->rva; - } - if (!strcmp (s->name, ".plt")) { +#if 1 + } else if (!strcmp (s->name, ".debug_info")) { + // di0 = s->rva; + // di1 = s->rva + s->size; + di0 = s->offset; + di1 = s->offset + s->size; +#endif + } else if (!strcmp (s->name, ".plt")) { ri.plt_min = s->offset; ri.plt_max = s->offset + s->size; ri.plt_va = s->rva; @@ -5261,7 +5269,9 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { } } if (!ri.got || !ri.plt) { - return false; + if (di0 == UT64_MAX) { + return false; + } } ut64 baddr = eo->user_baddr; // 0x10000; if (baddr == UT64_MAX) { @@ -5271,13 +5281,22 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { // resolve got and plt r_vector_foreach (&eo->g_relocs, reloc) { const ut64 raddr = reloc->offset; + if (!ri.got && !ri.plt) { + index++; + ut64 ra = baddr + di0 + (index * 4); + ra += 685182; + reloc->addend = 0; // index; + // reloc->rva = ra + baddr; // address to patch + reloc->laddr = ra; + continue; + } if (raddr < ri.got_min || raddr >= ri.got_max) { continue; } ut64 rvaddr = reloc->offset; // rva (eo, reloc->offset, reloc->rva); ut64 pltptr = 0; // relocated buf tells the section to look at #if R_BIN_ELF64 - r_buf_read_at (eo->b, rvaddr, (ut8*)&pltptr, 8); + r_buf_read_at (eo->b, rvaddr, (ut8*)&pltptr, 8); #else ut32 n32 = 0; r_buf_read_at (eo->b, rvaddr, (ut8*)&n32, 4); @@ -5301,7 +5320,6 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { #else index++; #endif - // TODO: if (reloc->type == 22) { // on arm! // extra check of bounds ut64 naddr = baddr + pltptr + (index * 12) + 0x20; if (reloc->type == 1026) { naddr = baddr + pltptr + (index * 16) + 64 - 16; @@ -5312,6 +5330,10 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { } else { R_LOG_DEBUG ("Cannot resolve reloc reference"); } + } else { + index++; + ut64 naddr = baddr + (index * 12) + 0x20; + reloc->laddr = naddr; } } } diff --git a/libr/bin/p/bin_elf.inc.c b/libr/bin/p/bin_elf.inc.c index 9656fd605c3669..064cb495545bc4 100644 --- a/libr/bin/p/bin_elf.inc.c +++ b/libr/bin/p/bin_elf.inc.c @@ -567,18 +567,18 @@ static RBinReloc *reloc_convert(ELFOBJ* eo, RBinElfReloc *rel, ut64 got_addr) { case R_ARM_GOTOFF: ADD(32,-(st64)G); break; case R_ARM_GOTPC: ADD(32, G - P); break; case R_ARM_CALL: // ADD(24, got_addr -P); - // eprintf ("CAL %llx\n", got_addr); - // eprintf ("CAL %llx\n", P); - // SET(24); - // P = address of bl instruction to patch r->type = R_BIN_RELOC_24; if (G == UT64_MAX) { r->addend = B-P; // 171295; - eprintf( "jeje 0x%x 0x%x\n", P, B); + eprintf( "jeje 0x%x 0x%x\n", P, got_addr); } else { + eprintf( "joje 0x%x 0x%x\n", P, got_addr); r->addend = got_addr -P; } - rel->addend = r->addend; + // r->addend = 0x08004dad; + r->addend = 0x00004dad; + // rel->laddr += 685182; + rel->addend = r->addend + rel->laddr; // rel->addend = 685182 /4; // 171295 r->additive = DT_RELA; return r; @@ -746,7 +746,13 @@ static RList* relocs(RBinFile *bf) { if (got_addr == UT64_MAX && eo->ehdr.e_type == ET_REL) { got_addr = Elf_(get_section_addr) (eo, ".got.r2"); } - +#if 0 + if (got_addr == UT64_MAX) { + // XXX + got_addr = Elf_(get_section_addr) (eo, ".debug_info"); + // got_addr = 0x08001e60; + } +#endif const RVector *relocs = Elf_(load_relocs) (eo); if (!relocs) { return ret; @@ -761,9 +767,9 @@ static RList* relocs(RBinFile *bf) { r_vector_foreach (relocs, reloc) { RBinReloc *already_inserted = ht_up_find (reloc_ht, reloc->rva, NULL); if (already_inserted) { + R_LOG_DEBUG ("Reloc already inserted at 0x%08"PFMT64x, reloc->rva); continue; } - RBinReloc *ptr = reloc_convert (eo, reloc, got_addr); if (ptr && ptr->paddr != UT64_MAX) { r_list_append (ret, ptr); @@ -795,23 +801,22 @@ static void _patch_reloc(ELFOBJ *bo, ut16 e_machine, RIOBind *iob, RBinElfReloc case EM_S390: switch (rel->type) { case R_390_GLOB_DAT: // globals - iob->overlay_write_at (iob->io, rel->rva, buf, 8); - break; - case R_390_RELATIVE: + case R_390_RELATIVE: // pic iob->overlay_write_at (iob->io, rel->rva, buf, 8); break; } break; case EM_ARM: if (rel->type == R_ARM_CALL) { + eprintf ("one\n"); // read original bytes of the "bl" instruction iob->read_at (iob->io, rel->rva, buf, 4); V = r_read_le32 (buf); int delta = A; - if (rel->rva == 0x08001ec8) { +// if (rel->rva == 0x08001ec8) { eprintf ("DELTA = %llx\n",A); - } +// } delta &= 0xfffff; #if 0 if (rel->rva == 0x08001ec8) { @@ -995,7 +1000,7 @@ static void _patch_reloc(ELFOBJ *bo, ut16 e_machine, RIOBind *iob, RBinElfReloc V = B + A; break; default: - //eprintf ("relocation %d not handle at this time\n", rel->type); + R_LOG_WARN ("relocation %d not handle at this time", rel->type); break; } switch (word) {