From 956ca7265c697107708468b7e1b2fd21f4185bae Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 25 Apr 2013 12:28:45 +0000 Subject: [PATCH] Clarify getRelocationAddress x getRelocationOffset a bit. getRelocationAddress is for dynamic libraries and executables, getRelocationOffset for relocatable objects. Mark the getRelocationAddress of COFF and MachO as not implemented yet. Add a test of ELF's. llvm-readobj -r now prints the same values as readelf -r. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180259 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELF.h | 49 +++++++++------------- include/llvm/Object/RelocVisitor.h | 4 +- lib/DebugInfo/DWARFContext.cpp | 2 +- lib/Object/COFFObjectFile.cpp | 3 +- lib/Object/MachOObjectFile.cpp | 16 +------ test/Object/Inputs/hello-world.elf-x86-64 | Bin 0 -> 4544 bytes test/Object/relocation-executable.test | 18 ++++++++ tools/llvm-objdump/MachODump.cpp | 2 +- tools/llvm-objdump/llvm-objdump.cpp | 8 ++-- tools/llvm-readobj/ELFDumper.cpp | 6 ++- tools/llvm-readobj/llvm-readobj.cpp | 4 +- 11 files changed, 54 insertions(+), 58 deletions(-) create mode 100755 test/Object/Inputs/hello-world.elf-x86-64 create mode 100644 test/Object/relocation-executable.test diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 02840230f5c..4f0e5b8db8f 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -607,6 +607,8 @@ private: mutable const char *dt_soname; private: + uint64_t getROffset(DataRefImpl Rel) const; + // Records for each version index the corresponding Verdef or Vernaux entry. // This is filled the first time LoadVersionMap() is called. class VersionMapEntry : public PointerIntPair { @@ -1521,45 +1523,32 @@ error_code ELFObjectFile::getRelocationSymbol(DataRefImpl Rel, template error_code ELFObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Result) const { - uint64_t offset; - const Elf_Shdr *sec = getSection(Rel.w.b); - switch (sec->sh_type) { - default : - report_fatal_error("Invalid section type in Rel!"); - case ELF::SHT_REL : { - offset = getRel(Rel)->r_offset; - break; - } - case ELF::SHT_RELA : { - offset = getRela(Rel)->r_offset; - break; - } - } - - Result = offset; + assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) && + "Only executable and shared objects files have addresses"); + Result = getROffset(Rel); return object_error::success; } template error_code ELFObjectFile::getRelocationOffset(DataRefImpl Rel, uint64_t &Result) const { - uint64_t offset; + assert(Header->e_type == ELF::ET_REL && + "Only relocatable object files have relocation offsets"); + Result = getROffset(Rel); + return object_error::success; +} + +template +uint64_t ELFObjectFile::getROffset(DataRefImpl Rel) const { const Elf_Shdr *sec = getSection(Rel.w.b); switch (sec->sh_type) { - default : - report_fatal_error("Invalid section type in Rel!"); - case ELF::SHT_REL : { - offset = getRel(Rel)->r_offset; - break; - } - case ELF::SHT_RELA : { - offset = getRela(Rel)->r_offset; - break; - } + default: + report_fatal_error("Invalid section type in Rel!"); + case ELF::SHT_REL: + return getRel(Rel)->r_offset; + case ELF::SHT_RELA: + return getRela(Rel)->r_offset; } - - Result = offset - sec->sh_addr; - return object_error::success; } template diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 2dcbdf90532..59d810763f2 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -133,7 +133,7 @@ private: int64_t Addend; R.getAdditionalInfo(Addend); uint64_t Address; - R.getAddress(Address); + R.getOffset(Address); return RelocToApply(Value + Addend - Address, 4); } @@ -151,7 +151,7 @@ private: int64_t Addend; R.getAdditionalInfo(Addend); uint64_t Address; - R.getAddress(Address); + R.getOffset(Address); return RelocToApply(Value + Addend - Address, 4); } RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 1e13731361a..e5daf55982f 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -572,7 +572,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : reloc_e = i->end_relocations(); reloc_i != reloc_e; reloc_i.increment(ec)) { uint64_t Address; - reloc_i->getAddress(Address); + reloc_i->getOffset(Address); uint64_t Type; reloc_i->getType(Type); uint64_t SymAddr = 0; diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 46acd4d5370..70fec321ba3 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -705,8 +705,7 @@ error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel, } error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { - Res = toRel(Rel)->VirtualAddress; - return object_error::success; + report_fatal_error("getRelocationAddress not implemented in COFFObjectFile"); } error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const { diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 51cd5b9a95d..14bca2bf901 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -789,21 +789,7 @@ MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { - uint64_t SectAddress; - DataRefImpl Sec; - Sec.d.a = Rel.d.b; - if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - SectAddress = Sect.Address; - } else { - macho::Section Sect = getSection(Sec); - SectAddress = Sect.Address; - } - - macho::RelocationEntry RE = getRelocation(Rel); - uint64_t RelAddr = getAnyRelocationAddress(RE); - Res = SectAddress + RelAddr; - return object_error::success; + report_fatal_error("getRelocationAddress not implemented in MachOObjectFile"); } error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, diff --git a/test/Object/Inputs/hello-world.elf-x86-64 b/test/Object/Inputs/hello-world.elf-x86-64 new file mode 100755 index 0000000000000000000000000000000000000000..16092b894721113234b4cdea9b114bf1193ce1da GIT binary patch literal 4544 zcmcInZ){Ul6u<5MPzAT5Gn8#+PtzsC*hg2#7!u@-A-s`d05?U$?7Fqvs;}+RzQLwM zXC~^)MEAkOnD~Jh6OEsUAxhMQ%^5K9OEDTT@?k-jbSMS`A^QULocqq%y60v{jHh|` z+;i^v-E;1__uTjT@?+s$ZkJ0ixy7RbrS4Kqs_a&X(L1F`x)$LPnz&EYigM7D!lTI% z^U4cK#(>g zn$5-`I6U`wL~*Z{o?|=Dpq3?p`--+G@sUKy1wYIm9ZxY-owx&Sc<(RxG&Ga4jhCXB zCq4Quo=>dTqyg%2&zSVFKRo&8LDI**@l3N;h{C2%tDvnv1?>b-p&sP{G?<$y0M&nj zGEOy@1F`W+yLJ9q-MXZY{dRRG)ing zHD3buy7jd_b$Pq)%IVfw{rs&Vz<+_Z`myg9@RtZby3GaQh@rKefXu%Hfp(oO`|}=1 z*0t%%I*ei4w;&0#W+8;NooBoloi$s?bYs=Fw1hXzwpxXD>xMpcv!vbn zvGJGuewa@`cEzm5c*54@uytdnRcI|#UDU^>UHX>ahc4^mhy0LQ!|x4`$Nau9^px

2C;+AN2$A6Bv+N&ay7|VE=ag{ zNW6~qwkQ-DuOXSouNDevRGlFIkX|XDBpFgHWsZyB|2yONyVKDw%EObyo#P7JOGp}V zvAeD95v2iMgBz44b+Z~$LczvRa7(CBX*dv%DSFhj^?}d^#NmG6o+HP1XMfs=DUE7l zBgjI{4rI-Y8SN2jA_Xs$L7}G7W?XIE(H=0P{X&h6q_QJPo0}P-4n(s9LhVltsfXj4 zY$BanB1FI<6E~s=qu!ul;@k;n&G<01eIUSCIuNdhz8Kf#~7wC+CesGnwd!?T`CC*{o1|)5&B!1vAOjVfdJa z0Iva4@m~q+1kV)Lt8i-|0g-~wv8}XixsM$0ZmeC#*Sa;37QfpRDJ?c!XRNs&Iv4}v zHMa(m5E>~ymXduAFix%)u4_Cjc=s?q@76$qdxjKT-%<&UvwrYA;oZP^uKz*0(D?r1 z`;GncIyM6qYm@O@zb6P#0pm!FXFKLQVGL`XWv=&=1W*tRg#Ivg_KP~CC*VOH<8vh% zNJ8WY&v|1196#&3z_u9A_j8^A#p}m?a^m|zhjH=!%lD&?0_F9Ci6m$IJ)kYd2kAZu zk|Fyi_`-LamlR0{zMJsfgg=Fo7ZKxFm4!~Rf4r|M34Dp2ivfdoX~m7S0F%ufw7S%2ECp$No8w zAAk*-FrL4kFOVVI<6KBi`6JL3{z~h%E zl9%vKe@^*Juq}?C-~T@6!I886bN%0e9>4E6e@?v9pHuz`uvlY^=kE*UHsk*lusA2< z8)*Fvx0$~@U~&CHc#4Vffnp`}(H4pMU(lzcCiUDLB>&F(aqeGn?iq{RgetAddress(RelocOffset); + RI->getOffset(RelocOffset); Sections[SectIdx].getAddress(SectionAddress); RelocOffset -= SectionAddress; diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 99855995651..247b90f0300 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -186,8 +186,8 @@ void llvm::DumpBytes(StringRef bytes) { bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { uint64_t a_addr, b_addr; - if (error(a.getAddress(a_addr))) return false; - if (error(b.getAddress(b_addr))) return false; + if (error(a.getOffset(a_addr))) return false; + if (error(b.getOffset(b_addr))) return false; return a_addr < b_addr; } @@ -378,7 +378,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; if (hidden) goto skip_print_rel; - if (error(rel_cur->getAddress(addr))) goto skip_print_rel; + if (error(rel_cur->getOffset(addr))) goto skip_print_rel; // Stop when rel_cur's address is past the current instruction. if (addr >= Index + Size) break; if (error(rel_cur->getTypeName(name))) goto skip_print_rel; @@ -417,7 +417,7 @@ static void PrintRelocations(const ObjectFile *o) { if (error(ri->getHidden(hidden))) continue; if (hidden) continue; if (error(ri->getTypeName(relocname))) continue; - if (error(ri->getAddress(address))) continue; + if (error(ri->getOffset(address))) continue; if (error(ri->getValueString(valuestr))) continue; outs() << address << " " << relocname << " " << valuestr << "\n"; } diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index f771cbdd52b..ea1b83f32f1 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -582,7 +582,11 @@ void ELFDumper::printRelocation(section_iterator Sec, int64_t Info; StringRef SymbolName; SymbolRef Symbol; - if (error(RelI->getOffset(Offset))) return; + if (Obj->getElfHeader()->e_type == ELF::ET_REL){ + if (error(RelI->getOffset(Offset))) return; + } else { + if (error(RelI->getAddress(Offset))) return; + } if (error(RelI->getType(RelocType))) return; if (error(RelI->getTypeName(RelocName))) return; if (error(RelI->getAdditionalInfo(Info))) return; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 7a4b4e4431c..2e95b6b5518 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -143,8 +143,8 @@ bool error(error_code EC) { bool relocAddressLess(RelocationRef a, RelocationRef b) { uint64_t a_addr, b_addr; - if (error(a.getAddress(a_addr))) return false; - if (error(b.getAddress(b_addr))) return false; + if (error(a.getOffset(a_addr))) return false; + if (error(b.getOffset(b_addr))) return false; return a_addr < b_addr; }