[llvm] r351545 - [llvm-objdump] - Move getRelocationValueString and dependenices out of the llvm-objdump.cpp
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 18 03:33:27 PST 2019
Author: grimar
Date: Fri Jan 18 03:33:26 2019
New Revision: 351545
URL: http://llvm.org/viewvc/llvm-project?rev=351545&view=rev
Log:
[llvm-objdump] - Move getRelocationValueString and dependenices out of the llvm-objdump.cpp
getRelocationValueString is a dispatcher function that calls the
corresponding ELF/COFF/Wasm/MachO implementations
that currently live in the llvm-objdump.cpp file.
These implementations better be moved to ELFDump.cpp,
COFFDump.cpp and other corresponding files, to move platform specific
implementation out from the common logic.
The patch does that. Also, I had to move ToolSectionFilter helper
and SectionFilterIterator, SectionFilter to a header to make them
available across the objdump code.
Differential revision: https://reviews.llvm.org/D56842
Modified:
llvm/trunk/tools/llvm-objdump/COFFDump.cpp
llvm/trunk/tools/llvm-objdump/ELFDump.cpp
llvm/trunk/tools/llvm-objdump/MachODump.cpp
llvm/trunk/tools/llvm-objdump/WasmDump.cpp
llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
llvm/trunk/tools/llvm-objdump/llvm-objdump.h
Modified: llvm/trunk/tools/llvm-objdump/COFFDump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/COFFDump.cpp?rev=351545&r1=351544&r2=351545&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/COFFDump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/COFFDump.cpp Fri Jan 18 03:33:26 2019
@@ -469,6 +469,19 @@ static bool getPDataSection(const COFFOb
return false;
}
+std::error_code
+llvm::getCOFFRelocationValueString(const COFFObjectFile *Obj,
+ const RelocationRef &Rel,
+ SmallVectorImpl<char> &Result) {
+ symbol_iterator SymI = Rel.getSymbol();
+ Expected<StringRef> SymNameOrErr = SymI->getName();
+ if (!SymNameOrErr)
+ return errorToErrorCode(SymNameOrErr.takeError());
+ StringRef SymName = *SymNameOrErr;
+ Result.append(SymName.begin(), SymName.end());
+ return std::error_code();
+}
+
static void printWin64EHUnwindInfo(const Win64EH::UnwindInfo *UI) {
// The casts to int are required in order to output the value as number.
// Without the casts the value would be interpreted as char data (which
Modified: llvm/trunk/tools/llvm-objdump/ELFDump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/ELFDump.cpp?rev=351545&r1=351544&r2=351545&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/ELFDump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/ELFDump.cpp Fri Jan 18 03:33:26 2019
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm-objdump.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
@@ -52,6 +53,87 @@ Expected<StringRef> getDynamicStrTab(con
}
template <class ELFT>
+static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
+ const RelocationRef &RelRef,
+ SmallVectorImpl<char> &Result) {
+ typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
+ typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
+ typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
+
+ const ELFFile<ELFT> &EF = *Obj->getELFFile();
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ auto SecOrErr = EF.getSection(Rel.d.a);
+ if (!SecOrErr)
+ return errorToErrorCode(SecOrErr.takeError());
+
+ int64_t Addend = 0;
+ // If there is no Symbol associated with the relocation, we set the undef
+ // boolean value to 'true'. This will prevent us from calling functions that
+ // requires the relocation to be associated with a symbol.
+ //
+ // In SHT_REL case we would need to read the addend from section data.
+ // GNU objdump does not do that and we just follow for simplicity atm.
+ bool Undef = false;
+ if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
+ const Elf_Rela *ERela = Obj->getRela(Rel);
+ Addend = ERela->r_addend;
+ Undef = ERela->getSymbol(false) == 0;
+ } else if ((*SecOrErr)->sh_type != ELF::SHT_REL) {
+ return object_error::parse_failed;
+ }
+
+ // Default scheme is to print Target, as well as "+ <addend>" for nonzero
+ // addend. Should be acceptable for all normal purposes.
+ std::string FmtBuf;
+ raw_string_ostream Fmt(FmtBuf);
+
+ if (!Undef) {
+ symbol_iterator SI = RelRef.getSymbol();
+ const Elf_Sym *Sym = Obj->getSymbol(SI->getRawDataRefImpl());
+ if (Sym->getType() == ELF::STT_SECTION) {
+ Expected<section_iterator> SymSI = SI->getSection();
+ if (!SymSI)
+ return errorToErrorCode(SymSI.takeError());
+ const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
+ auto SecName = EF.getSectionName(SymSec);
+ if (!SecName)
+ return errorToErrorCode(SecName.takeError());
+ Fmt << *SecName;
+ } else {
+ Expected<StringRef> SymName = SI->getName();
+ if (!SymName)
+ return errorToErrorCode(SymName.takeError());
+ if (Demangle)
+ Fmt << demangle(*SymName);
+ else
+ Fmt << *SymName;
+ }
+ } else {
+ Fmt << "*ABS*";
+ }
+
+ if (Addend != 0)
+ Fmt << (Addend < 0 ? "" : "+") << Addend;
+ Fmt.flush();
+ Result.append(FmtBuf.begin(), FmtBuf.end());
+ return std::error_code();
+}
+
+std::error_code
+llvm::getELFRelocationValueString(const ELFObjectFileBase *Obj,
+ const RelocationRef &Rel,
+ SmallVectorImpl<char> &Result) {
+ if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
+ return getRelocationValueString(ELF32LE, Rel, Result);
+ if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
+ return getRelocationValueString(ELF64LE, Rel, Result);
+ if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
+ return getRelocationValueString(ELF32BE, Rel, Result);
+ auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
+ return getRelocationValueString(ELF64BE, Rel, Result);
+}
+
+template <class ELFT>
void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) {
auto ProgramHeaderOrError = Elf->program_headers();
if (!ProgramHeaderOrError)
Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=351545&r1=351544&r2=351545&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Fri Jan 18 03:33:26 2019
@@ -342,6 +342,264 @@ static void getSectionsAndSymbols(MachOO
}
}
+static void printRelocationTargetName(const MachOObjectFile *O,
+ const MachO::any_relocation_info &RE,
+ raw_string_ostream &Fmt) {
+ // Target of a scattered relocation is an address. In the interest of
+ // generating pretty output, scan through the symbol table looking for a
+ // symbol that aligns with that address. If we find one, print it.
+ // Otherwise, we just print the hex address of the target.
+ if (O->isRelocationScattered(RE)) {
+ uint32_t Val = O->getPlainRelocationSymbolNum(RE);
+
+ for (const SymbolRef &Symbol : O->symbols()) {
+ Expected<uint64_t> Addr = Symbol.getAddress();
+ if (!Addr)
+ report_error(O->getFileName(), Addr.takeError());
+ if (*Addr != Val)
+ continue;
+ Expected<StringRef> Name = Symbol.getName();
+ if (!Name)
+ report_error(O->getFileName(), Name.takeError());
+ Fmt << *Name;
+ return;
+ }
+
+ // If we couldn't find a symbol that this relocation refers to, try
+ // to find a section beginning instead.
+ for (const SectionRef &Section : ToolSectionFilter(*O)) {
+ std::error_code ec;
+
+ StringRef Name;
+ uint64_t Addr = Section.getAddress();
+ if (Addr != Val)
+ continue;
+ if ((ec = Section.getName(Name)))
+ report_error(O->getFileName(), ec);
+ Fmt << Name;
+ return;
+ }
+
+ Fmt << format("0x%x", Val);
+ return;
+ }
+
+ StringRef S;
+ bool isExtern = O->getPlainRelocationExternal(RE);
+ uint64_t Val = O->getPlainRelocationSymbolNum(RE);
+
+ if (O->getAnyRelocationType(RE) == MachO::ARM64_RELOC_ADDEND) {
+ Fmt << format("0x%0" PRIx64, Val);
+ return;
+ }
+
+ if (isExtern) {
+ symbol_iterator SI = O->symbol_begin();
+ advance(SI, Val);
+ Expected<StringRef> SOrErr = SI->getName();
+ if (!SOrErr)
+ report_error(O->getFileName(), SOrErr.takeError());
+ S = *SOrErr;
+ } else {
+ section_iterator SI = O->section_begin();
+ // Adjust for the fact that sections are 1-indexed.
+ if (Val == 0) {
+ Fmt << "0 (?,?)";
+ return;
+ }
+ uint32_t I = Val - 1;
+ while (I != 0 && SI != O->section_end()) {
+ --I;
+ advance(SI, 1);
+ }
+ if (SI == O->section_end())
+ Fmt << Val << " (?,?)";
+ else
+ SI->getName(S);
+ }
+
+ Fmt << S;
+}
+
+std::error_code
+llvm::getMachORelocationValueString(const MachOObjectFile *Obj,
+ const RelocationRef &RelRef,
+ SmallVectorImpl<char> &Result) {
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ MachO::any_relocation_info RE = Obj->getRelocation(Rel);
+
+ unsigned Arch = Obj->getArch();
+
+ std::string FmtBuf;
+ raw_string_ostream Fmt(FmtBuf);
+ unsigned Type = Obj->getAnyRelocationType(RE);
+ bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
+
+ // Determine any addends that should be displayed with the relocation.
+ // These require decoding the relocation type, which is triple-specific.
+
+ // X86_64 has entirely custom relocation types.
+ if (Arch == Triple::x86_64) {
+ switch (Type) {
+ case MachO::X86_64_RELOC_GOT_LOAD:
+ case MachO::X86_64_RELOC_GOT: {
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "@GOT";
+ if (IsPCRel)
+ Fmt << "PCREL";
+ break;
+ }
+ case MachO::X86_64_RELOC_SUBTRACTOR: {
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
+ // X86_64_RELOC_UNSIGNED.
+ // NOTE: Scattered relocations don't exist on x86_64.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+ if (RType != MachO::X86_64_RELOC_UNSIGNED)
+ report_error(Obj->getFileName(), "Expected X86_64_RELOC_UNSIGNED after "
+ "X86_64_RELOC_SUBTRACTOR.");
+
+ // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
+ // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
+ printRelocationTargetName(Obj, RENext, Fmt);
+ Fmt << "-";
+ printRelocationTargetName(Obj, RE, Fmt);
+ break;
+ }
+ case MachO::X86_64_RELOC_TLV:
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "@TLV";
+ if (IsPCRel)
+ Fmt << "P";
+ break;
+ case MachO::X86_64_RELOC_SIGNED_1:
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "-1";
+ break;
+ case MachO::X86_64_RELOC_SIGNED_2:
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "-2";
+ break;
+ case MachO::X86_64_RELOC_SIGNED_4:
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "-4";
+ break;
+ default:
+ printRelocationTargetName(Obj, RE, Fmt);
+ break;
+ }
+ // X86 and ARM share some relocation types in common.
+ } else if (Arch == Triple::x86 || Arch == Triple::arm ||
+ Arch == Triple::ppc) {
+ // Generic relocation types...
+ switch (Type) {
+ case MachO::GENERIC_RELOC_PAIR: // prints no info
+ return std::error_code();
+ case MachO::GENERIC_RELOC_SECTDIFF: {
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // X86 sect diff's must be followed by a relocation of type
+ // GENERIC_RELOC_PAIR.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+
+ if (RType != MachO::GENERIC_RELOC_PAIR)
+ report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
+ "GENERIC_RELOC_SECTDIFF.");
+
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "-";
+ printRelocationTargetName(Obj, RENext, Fmt);
+ break;
+ }
+ }
+
+ if (Arch == Triple::x86 || Arch == Triple::ppc) {
+ switch (Type) {
+ case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // X86 sect diff's must be followed by a relocation of type
+ // GENERIC_RELOC_PAIR.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+ if (RType != MachO::GENERIC_RELOC_PAIR)
+ report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
+ "GENERIC_RELOC_LOCAL_SECTDIFF.");
+
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "-";
+ printRelocationTargetName(Obj, RENext, Fmt);
+ break;
+ }
+ case MachO::GENERIC_RELOC_TLV: {
+ printRelocationTargetName(Obj, RE, Fmt);
+ Fmt << "@TLV";
+ if (IsPCRel)
+ Fmt << "P";
+ break;
+ }
+ default:
+ printRelocationTargetName(Obj, RE, Fmt);
+ }
+ } else { // ARM-specific relocations
+ switch (Type) {
+ case MachO::ARM_RELOC_HALF:
+ case MachO::ARM_RELOC_HALF_SECTDIFF: {
+ // Half relocations steal a bit from the length field to encode
+ // whether this is an upper16 or a lower16 relocation.
+ bool isUpper = (Obj->getAnyRelocationLength(RE) & 0x1) == 1;
+
+ if (isUpper)
+ Fmt << ":upper16:(";
+ else
+ Fmt << ":lower16:(";
+ printRelocationTargetName(Obj, RE, Fmt);
+
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // ARM half relocs must be followed by a relocation of type
+ // ARM_RELOC_PAIR.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+ if (RType != MachO::ARM_RELOC_PAIR)
+ report_error(Obj->getFileName(), "Expected ARM_RELOC_PAIR after "
+ "ARM_RELOC_HALF");
+
+ // NOTE: The half of the target virtual address is stashed in the
+ // address field of the secondary relocation, but we can't reverse
+ // engineer the constant offset from it without decoding the movw/movt
+ // instruction to find the other half in its immediate field.
+
+ // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
+ // symbol/section pointer of the follow-on relocation.
+ if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
+ Fmt << "-";
+ printRelocationTargetName(Obj, RENext, Fmt);
+ }
+
+ Fmt << ")";
+ break;
+ }
+ default: {
+ printRelocationTargetName(Obj, RE, Fmt);
+ }
+ }
+ }
+ } else
+ printRelocationTargetName(Obj, RE, Fmt);
+
+ Fmt.flush();
+ Result.append(FmtBuf.begin(), FmtBuf.end());
+ return std::error_code();
+}
+
static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose,
uint32_t n, uint32_t count,
uint32_t stride, uint64_t addr) {
Modified: llvm/trunk/tools/llvm-objdump/WasmDump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/WasmDump.cpp?rev=351545&r1=351544&r2=351545&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/WasmDump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/WasmDump.cpp Fri Jan 18 03:33:26 2019
@@ -26,3 +26,28 @@ void llvm::printWasmFileHeader(const obj
outs().write_hex(File->getHeader().Version);
outs() << "\n";
}
+
+std::error_code
+llvm::getWasmRelocationValueString(const WasmObjectFile *Obj,
+ const RelocationRef &RelRef,
+ SmallVectorImpl<char> &Result) {
+ const wasm::WasmRelocation &Rel = Obj->getWasmRelocation(RelRef);
+ symbol_iterator SI = RelRef.getSymbol();
+ std::string FmtBuf;
+ raw_string_ostream Fmt(FmtBuf);
+ if (SI == Obj->symbol_end()) {
+ // Not all wasm relocations have symbols associated with them.
+ // In particular R_WEBASSEMBLY_TYPE_INDEX_LEB.
+ Fmt << Rel.Index;
+ } else {
+ Expected<StringRef> SymNameOrErr = SI->getName();
+ if (!SymNameOrErr)
+ return errorToErrorCode(SymNameOrErr.takeError());
+ StringRef SymName = *SymNameOrErr;
+ Result.append(SymName.begin(), SymName.end());
+ }
+ Fmt << (Rel.Addend < 0 ? "" : "+") << Rel.Addend;
+ Fmt.flush();
+ Result.append(FmtBuf.begin(), FmtBuf.end());
+ return std::error_code();
+}
Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=351545&r1=351544&r2=351545&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Fri Jan 18 03:33:26 2019
@@ -281,56 +281,7 @@ static StringRef ToolName;
typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
-namespace {
-typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate;
-
-class SectionFilterIterator {
-public:
- SectionFilterIterator(FilterPredicate P,
- llvm::object::section_iterator const &I,
- llvm::object::section_iterator const &E)
- : Predicate(std::move(P)), Iterator(I), End(E) {
- ScanPredicate();
- }
- const llvm::object::SectionRef &operator*() const { return *Iterator; }
- SectionFilterIterator &operator++() {
- ++Iterator;
- ScanPredicate();
- return *this;
- }
- bool operator!=(SectionFilterIterator const &Other) const {
- return Iterator != Other.Iterator;
- }
-
-private:
- void ScanPredicate() {
- while (Iterator != End && !Predicate(*Iterator)) {
- ++Iterator;
- }
- }
- FilterPredicate Predicate;
- llvm::object::section_iterator Iterator;
- llvm::object::section_iterator End;
-};
-
-class SectionFilter {
-public:
- SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O)
- : Predicate(std::move(P)), Object(O) {}
- SectionFilterIterator begin() {
- return SectionFilterIterator(Predicate, Object.section_begin(),
- Object.section_end());
- }
- SectionFilterIterator end() {
- return SectionFilterIterator(Predicate, Object.section_end(),
- Object.section_end());
- }
-
-private:
- FilterPredicate Predicate;
- llvm::object::ObjectFile const &Object;
-};
-SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O) {
+SectionFilter llvm::ToolSectionFilter(llvm::object::ObjectFile const &O) {
return SectionFilter(
[](llvm::object::SectionRef const &S) {
if (FilterSections.empty())
@@ -343,7 +294,6 @@ SectionFilter ToolSectionFilter(llvm::ob
},
O);
}
-}
void llvm::error(std::error_code EC) {
if (!EC)
@@ -464,388 +414,17 @@ bool llvm::isRelocAddressLess(Relocation
return A.getOffset() < B.getOffset();
}
-template <class ELFT>
-static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
- const RelocationRef &RelRef,
- SmallVectorImpl<char> &Result) {
- typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
- typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
- typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
-
- const ELFFile<ELFT> &EF = *Obj->getELFFile();
- DataRefImpl Rel = RelRef.getRawDataRefImpl();
- auto SecOrErr = EF.getSection(Rel.d.a);
- if (!SecOrErr)
- return errorToErrorCode(SecOrErr.takeError());
-
- int64_t Addend = 0;
- // If there is no Symbol associated with the relocation, we set the undef
- // boolean value to 'true'. This will prevent us from calling functions that
- // requires the relocation to be associated with a symbol.
- //
- // In SHT_REL case we would need to read the addend from section data.
- // GNU objdump does not do that and we just follow for simplicity.
- bool Undef = false;
- if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
- const Elf_Rela *ERela = Obj->getRela(Rel);
- Addend = ERela->r_addend;
- Undef = ERela->getSymbol(false) == 0;
- } else if ((*SecOrErr)->sh_type != ELF::SHT_REL) {
- return object_error::parse_failed;
- }
-
- // Default scheme is to print Target, as well as "+ <addend>" for nonzero
- // addend. Should be acceptable for all normal purposes.
- std::string FmtBuf;
- raw_string_ostream Fmt(FmtBuf);
-
- if (!Undef) {
- symbol_iterator SI = RelRef.getSymbol();
- const Elf_Sym *Sym = Obj->getSymbol(SI->getRawDataRefImpl());
- if (Sym->getType() == ELF::STT_SECTION) {
- Expected<section_iterator> SymSI = SI->getSection();
- if (!SymSI)
- return errorToErrorCode(SymSI.takeError());
- const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
- auto SecName = EF.getSectionName(SymSec);
- if (!SecName)
- return errorToErrorCode(SecName.takeError());
- Fmt << *SecName;
- } else {
- Expected<StringRef> SymName = SI->getName();
- if (!SymName)
- return errorToErrorCode(SymName.takeError());
- if (Demangle)
- Fmt << demangle(*SymName);
- else
- Fmt << *SymName;
- }
- } else {
- Fmt << "*ABS*";
- }
-
- if (Addend != 0)
- Fmt << (Addend < 0 ? "" : "+") << Addend;
- Fmt.flush();
- Result.append(FmtBuf.begin(), FmtBuf.end());
- return std::error_code();
-}
-
-static std::error_code getRelocationValueString(const ELFObjectFileBase *Obj,
- const RelocationRef &Rel,
- SmallVectorImpl<char> &Result) {
- if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
- return getRelocationValueString(ELF32LE, Rel, Result);
- if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
- return getRelocationValueString(ELF64LE, Rel, Result);
- if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
- return getRelocationValueString(ELF32BE, Rel, Result);
- auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
- return getRelocationValueString(ELF64BE, Rel, Result);
-}
-
-static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
- const RelocationRef &Rel,
- SmallVectorImpl<char> &Result) {
- symbol_iterator SymI = Rel.getSymbol();
- Expected<StringRef> SymNameOrErr = SymI->getName();
- if (!SymNameOrErr)
- return errorToErrorCode(SymNameOrErr.takeError());
- StringRef SymName = *SymNameOrErr;
- Result.append(SymName.begin(), SymName.end());
- return std::error_code();
-}
-
-static void printRelocationTargetName(const MachOObjectFile *O,
- const MachO::any_relocation_info &RE,
- raw_string_ostream &Fmt) {
- // Target of a scattered relocation is an address. In the interest of
- // generating pretty output, scan through the symbol table looking for a
- // symbol that aligns with that address. If we find one, print it.
- // Otherwise, we just print the hex address of the target.
- if (O->isRelocationScattered(RE)) {
- uint32_t Val = O->getPlainRelocationSymbolNum(RE);
-
- for (const SymbolRef &Symbol : O->symbols()) {
- Expected<uint64_t> Addr = Symbol.getAddress();
- if (!Addr)
- report_error(O->getFileName(), Addr.takeError());
- if (*Addr != Val)
- continue;
- Expected<StringRef> Name = Symbol.getName();
- if (!Name)
- report_error(O->getFileName(), Name.takeError());
- Fmt << *Name;
- return;
- }
-
- // If we couldn't find a symbol that this relocation refers to, try
- // to find a section beginning instead.
- for (const SectionRef &Section : ToolSectionFilter(*O)) {
- std::error_code ec;
-
- StringRef Name;
- uint64_t Addr = Section.getAddress();
- if (Addr != Val)
- continue;
- if ((ec = Section.getName(Name)))
- report_error(O->getFileName(), ec);
- Fmt << Name;
- return;
- }
-
- Fmt << format("0x%x", Val);
- return;
- }
-
- StringRef S;
- bool isExtern = O->getPlainRelocationExternal(RE);
- uint64_t Val = O->getPlainRelocationSymbolNum(RE);
-
- if (O->getAnyRelocationType(RE) == MachO::ARM64_RELOC_ADDEND) {
- Fmt << format("0x%0" PRIx64, Val);
- return;
- }
-
- if (isExtern) {
- symbol_iterator SI = O->symbol_begin();
- advance(SI, Val);
- Expected<StringRef> SOrErr = SI->getName();
- if (!SOrErr)
- report_error(O->getFileName(), SOrErr.takeError());
- S = *SOrErr;
- } else {
- section_iterator SI = O->section_begin();
- // Adjust for the fact that sections are 1-indexed.
- if (Val == 0) {
- Fmt << "0 (?,?)";
- return;
- }
- uint32_t I = Val - 1;
- while (I != 0 && SI != O->section_end()) {
- --I;
- advance(SI, 1);
- }
- if (SI == O->section_end())
- Fmt << Val << " (?,?)";
- else
- SI->getName(S);
- }
-
- Fmt << S;
-}
-
-static std::error_code getRelocationValueString(const WasmObjectFile *Obj,
- const RelocationRef &RelRef,
- SmallVectorImpl<char> &Result) {
- const wasm::WasmRelocation& Rel = Obj->getWasmRelocation(RelRef);
- symbol_iterator SI = RelRef.getSymbol();
- std::string FmtBuf;
- raw_string_ostream Fmt(FmtBuf);
- if (SI == Obj->symbol_end()) {
- // Not all wasm relocations have symbols associated with them.
- // In particular R_WEBASSEMBLY_TYPE_INDEX_LEB.
- Fmt << Rel.Index;
- } else {
- Expected<StringRef> SymNameOrErr = SI->getName();
- if (!SymNameOrErr)
- return errorToErrorCode(SymNameOrErr.takeError());
- StringRef SymName = *SymNameOrErr;
- Result.append(SymName.begin(), SymName.end());
- }
- Fmt << (Rel.Addend < 0 ? "" : "+") << Rel.Addend;
- Fmt.flush();
- Result.append(FmtBuf.begin(), FmtBuf.end());
- return std::error_code();
-}
-
-static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
- const RelocationRef &RelRef,
- SmallVectorImpl<char> &Result) {
- DataRefImpl Rel = RelRef.getRawDataRefImpl();
- MachO::any_relocation_info RE = Obj->getRelocation(Rel);
-
- unsigned Arch = Obj->getArch();
-
- std::string FmtBuf;
- raw_string_ostream Fmt(FmtBuf);
- unsigned Type = Obj->getAnyRelocationType(RE);
- bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
-
- // Determine any addends that should be displayed with the relocation.
- // These require decoding the relocation type, which is triple-specific.
-
- // X86_64 has entirely custom relocation types.
- if (Arch == Triple::x86_64) {
- switch (Type) {
- case MachO::X86_64_RELOC_GOT_LOAD:
- case MachO::X86_64_RELOC_GOT: {
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "@GOT";
- if (IsPCRel)
- Fmt << "PCREL";
- break;
- }
- case MachO::X86_64_RELOC_SUBTRACTOR: {
- DataRefImpl RelNext = Rel;
- Obj->moveRelocationNext(RelNext);
- MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
-
- // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
- // X86_64_RELOC_UNSIGNED.
- // NOTE: Scattered relocations don't exist on x86_64.
- unsigned RType = Obj->getAnyRelocationType(RENext);
- if (RType != MachO::X86_64_RELOC_UNSIGNED)
- report_error(Obj->getFileName(), "Expected X86_64_RELOC_UNSIGNED after "
- "X86_64_RELOC_SUBTRACTOR.");
-
- // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
- // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
- printRelocationTargetName(Obj, RENext, Fmt);
- Fmt << "-";
- printRelocationTargetName(Obj, RE, Fmt);
- break;
- }
- case MachO::X86_64_RELOC_TLV:
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "@TLV";
- if (IsPCRel)
- Fmt << "P";
- break;
- case MachO::X86_64_RELOC_SIGNED_1:
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "-1";
- break;
- case MachO::X86_64_RELOC_SIGNED_2:
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "-2";
- break;
- case MachO::X86_64_RELOC_SIGNED_4:
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "-4";
- break;
- default:
- printRelocationTargetName(Obj, RE, Fmt);
- break;
- }
- // X86 and ARM share some relocation types in common.
- } else if (Arch == Triple::x86 || Arch == Triple::arm ||
- Arch == Triple::ppc) {
- // Generic relocation types...
- switch (Type) {
- case MachO::GENERIC_RELOC_PAIR: // prints no info
- return std::error_code();
- case MachO::GENERIC_RELOC_SECTDIFF: {
- DataRefImpl RelNext = Rel;
- Obj->moveRelocationNext(RelNext);
- MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
-
- // X86 sect diff's must be followed by a relocation of type
- // GENERIC_RELOC_PAIR.
- unsigned RType = Obj->getAnyRelocationType(RENext);
-
- if (RType != MachO::GENERIC_RELOC_PAIR)
- report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
- "GENERIC_RELOC_SECTDIFF.");
-
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "-";
- printRelocationTargetName(Obj, RENext, Fmt);
- break;
- }
- }
-
- if (Arch == Triple::x86 || Arch == Triple::ppc) {
- switch (Type) {
- case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
- DataRefImpl RelNext = Rel;
- Obj->moveRelocationNext(RelNext);
- MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
-
- // X86 sect diff's must be followed by a relocation of type
- // GENERIC_RELOC_PAIR.
- unsigned RType = Obj->getAnyRelocationType(RENext);
- if (RType != MachO::GENERIC_RELOC_PAIR)
- report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
- "GENERIC_RELOC_LOCAL_SECTDIFF.");
-
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "-";
- printRelocationTargetName(Obj, RENext, Fmt);
- break;
- }
- case MachO::GENERIC_RELOC_TLV: {
- printRelocationTargetName(Obj, RE, Fmt);
- Fmt << "@TLV";
- if (IsPCRel)
- Fmt << "P";
- break;
- }
- default:
- printRelocationTargetName(Obj, RE, Fmt);
- }
- } else { // ARM-specific relocations
- switch (Type) {
- case MachO::ARM_RELOC_HALF:
- case MachO::ARM_RELOC_HALF_SECTDIFF: {
- // Half relocations steal a bit from the length field to encode
- // whether this is an upper16 or a lower16 relocation.
- bool isUpper = (Obj->getAnyRelocationLength(RE) & 0x1) == 1;
-
- if (isUpper)
- Fmt << ":upper16:(";
- else
- Fmt << ":lower16:(";
- printRelocationTargetName(Obj, RE, Fmt);
-
- DataRefImpl RelNext = Rel;
- Obj->moveRelocationNext(RelNext);
- MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
-
- // ARM half relocs must be followed by a relocation of type
- // ARM_RELOC_PAIR.
- unsigned RType = Obj->getAnyRelocationType(RENext);
- if (RType != MachO::ARM_RELOC_PAIR)
- report_error(Obj->getFileName(), "Expected ARM_RELOC_PAIR after "
- "ARM_RELOC_HALF");
-
- // NOTE: The half of the target virtual address is stashed in the
- // address field of the secondary relocation, but we can't reverse
- // engineer the constant offset from it without decoding the movw/movt
- // instruction to find the other half in its immediate field.
-
- // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
- // symbol/section pointer of the follow-on relocation.
- if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
- Fmt << "-";
- printRelocationTargetName(Obj, RENext, Fmt);
- }
-
- Fmt << ")";
- break;
- }
- default: { printRelocationTargetName(Obj, RE, Fmt); }
- }
- }
- } else
- printRelocationTargetName(Obj, RE, Fmt);
-
- Fmt.flush();
- Result.append(FmtBuf.begin(), FmtBuf.end());
- return std::error_code();
-}
-
static std::error_code getRelocationValueString(const RelocationRef &Rel,
SmallVectorImpl<char> &Result) {
const ObjectFile *Obj = Rel.getObject();
if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
- return getRelocationValueString(ELF, Rel, Result);
+ return getELFRelocationValueString(ELF, Rel, Result);
if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
- return getRelocationValueString(COFF, Rel, Result);
+ return getCOFFRelocationValueString(COFF, Rel, Result);
if (auto *Wasm = dyn_cast<WasmObjectFile>(Obj))
- return getRelocationValueString(Wasm, Rel, Result);
+ return getWasmRelocationValueString(Wasm, Rel, Result);
if (auto *MachO = dyn_cast<MachOObjectFile>(Obj))
- return getRelocationValueString(MachO, Rel, Result);
+ return getMachORelocationValueString(MachO, Rel, Result);
llvm_unreachable("unknown object file format");
}
Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=351545&r1=351544&r2=351545&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Fri Jan 18 03:33:26 2019
@@ -19,13 +19,14 @@ namespace llvm {
class StringRef;
namespace object {
- class COFFObjectFile;
- class COFFImportFile;
- class MachOObjectFile;
- class MachOUniversalBinary;
- class ObjectFile;
- class Archive;
- class RelocationRef;
+class COFFObjectFile;
+class COFFImportFile;
+class ELFObjectFileBase;
+class MachOObjectFile;
+class MachOUniversalBinary;
+class ObjectFile;
+class Archive;
+class RelocationRef;
}
extern cl::opt<std::string> TripleName;
@@ -68,7 +69,75 @@ extern cl::opt<bool> UnwindInfo;
extern cl::opt<bool> PrintImmHex;
extern cl::opt<DIDumpType> DwarfDumpType;
+typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate;
+
+class SectionFilterIterator {
+public:
+ SectionFilterIterator(FilterPredicate P,
+ llvm::object::section_iterator const &I,
+ llvm::object::section_iterator const &E)
+ : Predicate(std::move(P)), Iterator(I), End(E) {
+ ScanPredicate();
+ }
+ const llvm::object::SectionRef &operator*() const { return *Iterator; }
+ SectionFilterIterator &operator++() {
+ ++Iterator;
+ ScanPredicate();
+ return *this;
+ }
+ bool operator!=(SectionFilterIterator const &Other) const {
+ return Iterator != Other.Iterator;
+ }
+
+private:
+ void ScanPredicate() {
+ while (Iterator != End && !Predicate(*Iterator)) {
+ ++Iterator;
+ }
+ }
+ FilterPredicate Predicate;
+ llvm::object::section_iterator Iterator;
+ llvm::object::section_iterator End;
+};
+
+class SectionFilter {
+public:
+ SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O)
+ : Predicate(std::move(P)), Object(O) {}
+ SectionFilterIterator begin() {
+ return SectionFilterIterator(Predicate, Object.section_begin(),
+ Object.section_end());
+ }
+ SectionFilterIterator end() {
+ return SectionFilterIterator(Predicate, Object.section_end(),
+ Object.section_end());
+ }
+
+private:
+ FilterPredicate Predicate;
+ llvm::object::ObjectFile const &Object;
+};
+
// Various helper functions.
+SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O);
+
+std::error_code
+getELFRelocationValueString(const object::ELFObjectFileBase *Obj,
+ const object::RelocationRef &Rel,
+ llvm::SmallVectorImpl<char> &Result);
+std::error_code
+getCOFFRelocationValueString(const object::COFFObjectFile *Obj,
+ const object::RelocationRef &Rel,
+ llvm::SmallVectorImpl<char> &Result);
+std::error_code
+getWasmRelocationValueString(const object::WasmObjectFile *Obj,
+ const object::RelocationRef &RelRef,
+ llvm::SmallVectorImpl<char> &Result);
+std::error_code
+getMachORelocationValueString(const object::MachOObjectFile *Obj,
+ const object::RelocationRef &RelRef,
+ llvm::SmallVectorImpl<char> &Result);
+
void error(std::error_code ec);
bool isRelocAddressLess(object::RelocationRef A, object::RelocationRef B);
void parseInputMachO(StringRef Filename);
More information about the llvm-commits
mailing list