diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-07-05 14:21:36 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-07-05 14:21:36 +0000 |
commit | 1a82d4c088707c791c792f6822f611b47a12bdfe (patch) | |
tree | 7c411f9b5d807f7f204fdd16965d8925a82b6d18 /tools/llvm-objdump | |
parent | 3a0822f094b578157263e04114075ad7df81db41 (diff) |
Notes
Diffstat (limited to 'tools/llvm-objdump')
-rw-r--r-- | tools/llvm-objdump/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tools/llvm-objdump/COFFDump.cpp | 8 | ||||
-rw-r--r-- | tools/llvm-objdump/ELFDump.cpp | 6 | ||||
-rw-r--r-- | tools/llvm-objdump/MachODump.cpp | 169 | ||||
-rw-r--r-- | tools/llvm-objdump/llvm-objdump.cpp | 231 |
5 files changed, 257 insertions, 158 deletions
diff --git a/tools/llvm-objdump/CMakeLists.txt b/tools/llvm-objdump/CMakeLists.txt index d717653685c8..1f2721ab5452 100644 --- a/tools/llvm-objdump/CMakeLists.txt +++ b/tools/llvm-objdump/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} + CodeGen DebugInfoDWARF MC MCDisassembler diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index 976a92154bda..58bdddfa9918 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -177,9 +177,7 @@ static std::error_code resolveSymbol(const std::vector<RelocationRef> &Rels, for (std::vector<RelocationRef>::const_iterator I = Rels.begin(), E = Rels.end(); I != E; ++I) { - uint64_t Ofs; - if (std::error_code EC = I->getOffset(Ofs)) - return EC; + uint64_t Ofs = I->getOffset(); if (Ofs == Offset) { Sym = *I->getSymbol(); return std::error_code(); @@ -215,8 +213,10 @@ static std::error_code resolveSymbolName(const std::vector<RelocationRef> &Rels, SymbolRef Sym; if (std::error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC; - if (std::error_code EC = Sym.getName(Name)) + ErrorOr<StringRef> NameOrErr = Sym.getName(); + if (std::error_code EC = NameOrErr.getError()) return EC; + Name = *NameOrErr; return std::error_code(); } diff --git a/tools/llvm-objdump/ELFDump.cpp b/tools/llvm-objdump/ELFDump.cpp index 9c091a410d8f..2d0d7d7db0f3 100644 --- a/tools/llvm-objdump/ELFDump.cpp +++ b/tools/llvm-objdump/ELFDump.cpp @@ -24,9 +24,9 @@ using namespace llvm::object; template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) { typedef ELFFile<ELFT> ELFO; outs() << "Program Header:\n"; - for (typename ELFO::Elf_Phdr_Iter pi = o->begin_program_headers(), - pe = o->end_program_headers(); - pi != pe; ++pi) { + for (typename ELFO::Elf_Phdr_Iter pi = o->program_header_begin(), + pe = o->program_header_end(); + pi != pe; ++pi) { switch (pi->p_type) { case ELF::PT_LOAD: outs() << " LOAD "; diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 1730bf3859f0..5263c33bf2dc 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -178,9 +178,8 @@ static const Target *GetTarget(const MachOObjectFile *MachOObj, struct SymbolSorter { bool operator()(const SymbolRef &A, const SymbolRef &B) { - SymbolRef::Type AType, BType; - A.getType(AType); - B.getType(BType); + SymbolRef::Type AType = A.getType(); + SymbolRef::Type BType = B.getType(); uint64_t AAddr, BAddr; if (AType != SymbolRef::ST_Function) @@ -283,9 +282,10 @@ static void getSectionsAndSymbols(MachOObjectFile *MachOObj, SmallVectorImpl<uint64_t> &FoundFns, uint64_t &BaseSegmentAddress) { for (const SymbolRef &Symbol : MachOObj->symbols()) { - StringRef SymName; - Symbol.getName(SymName); - if (!SymName.startswith("ltmp")) + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + if (!SymName->startswith("ltmp")) Symbols.push_back(Symbol); } @@ -362,9 +362,10 @@ static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose, if (indirect_symbol < Symtab.nsyms) { symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; - StringRef SymName; - Symbol.getName(SymName); - outs() << SymName; + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + outs() << *SymName; } else { outs() << "?"; } @@ -588,14 +589,15 @@ static void CreateSymbolAddressMap(MachOObjectFile *O, SymbolAddressMap *AddrMap) { // Create a map of symbol addresses to symbol names. for (const SymbolRef &Symbol : O->symbols()) { - SymbolRef::Type ST; - Symbol.getType(ST); + SymbolRef::Type ST = Symbol.getType(); if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { uint64_t Address; Symbol.getAddress(Address); - StringRef SymName; - Symbol.getName(SymName); + ErrorOr<StringRef> SymNameOrErr = Symbol.getName(); + if (std::error_code EC = SymNameOrErr.getError()) + report_fatal_error(EC.message()); + StringRef SymName = *SymNameOrErr; if (!SymName.startswith(".objc")) (*AddrMap)[Address] = SymName; } @@ -798,8 +800,7 @@ static void DumpLiteralPointerSection(MachOObjectFile *O, RE = O->getRelocation(Rel); isExtern = O->getPlainRelocationExternal(RE); if (isExtern) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); symbol_iterator RelocSym = Reloc.getSymbol(); Relocs.push_back(std::make_pair(RelocOffset, *RelocSym)); } @@ -833,9 +834,10 @@ static void DumpLiteralPointerSection(MachOObjectFile *O, [&](const std::pair<uint64_t, SymbolRef> &P) { return P.first == i; }); if (Reloc != Relocs.end()) { symbol_iterator RelocSym = Reloc->second; - StringRef SymName; - RelocSym->getName(SymName); - outs() << "external relocation entry for symbol:" << SymName << "\n"; + ErrorOr<StringRef> SymName = RelocSym->getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + outs() << "external relocation entry for symbol:" << *SymName << "\n"; continue; } @@ -1765,8 +1767,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, bool r_scattered = false; uint32_t r_value, pair_r_value, r_type; for (const RelocationRef &Reloc : info->S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -1797,9 +1798,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, } } if (reloc_found && isExtern) { - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; // For i386 extern relocation entries the value in the instruction is @@ -1843,8 +1845,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, bool isExtern = false; SymbolRef Symbol; for (const RelocationRef &Reloc : info->S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -1864,9 +1865,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, // is the offset from the external symbol. if (info->O->getAnyRelocationPCRel(RE)) op_info->Value -= Pc + Offset + Size; - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); unsigned Type = info->O->getAnyRelocationType(RE); if (Type == MachO::X86_64_RELOC_SUBTRACTOR) { DataRefImpl RelNext = Rel; @@ -1880,9 +1882,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, op_info->SubtractSymbol.Name = name; symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum); Symbol = *RelocSymNext; - StringRef SymNameNext; - Symbol.getName(SymNameNext); - name = SymNameNext.data(); + ErrorOr<StringRef> SymNameNext = Symbol.getName(); + if (std::error_code EC = SymNameNext.getError()) + report_fatal_error(EC.message()); + name = SymNameNext->data(); } } // TODO: add the VariantKinds to op_info->VariantKind for relocation types @@ -1913,8 +1916,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, auto Reloc = std::find_if(info->S.relocations().begin(), info->S.relocations().end(), [&](const RelocationRef &Reloc) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); return RelocOffset == sect_offset; }); @@ -1950,9 +1952,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, } if (isExtern) { - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; switch (r_type) { @@ -2040,8 +2043,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, auto Reloc = std::find_if(info->S.relocations().begin(), info->S.relocations().end(), [&](const RelocationRef &Reloc) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); return RelocOffset == sect_offset; }); @@ -2063,9 +2065,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, // NOTE: Scattered relocations don't exist on arm64. if (!info->O->getPlainRelocationExternal(RE)) return 0; - StringRef SymName; - Reloc->getSymbol()->getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Reloc->getSymbol()->getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; @@ -2192,9 +2195,10 @@ static const char *GuessIndirectSymbol(uint64_t ReferenceValue, if (indirect_symbol < Symtab.nsyms) { symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); return name; } } @@ -2226,9 +2230,10 @@ static const char *GuessIndirectSymbol(uint64_t ReferenceValue, if (indirect_symbol < Symtab.nsyms) { symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); return name; } } @@ -2417,10 +2422,9 @@ static const char *get_pointer_32(uint32_t Address, uint32_t &offset, // for the specified section offset in the specified section reference. // If no relocation information is found and a non-zero ReferenceValue for the // symbol is passed, look up that address in the info's AddrMap. -static const char * -get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, - uint64_t &n_value, - uint64_t ReferenceValue = UnknownAddressOrSize) { +static const char *get_symbol_64(uint32_t sect_offset, SectionRef S, + DisassembleInfo *info, uint64_t &n_value, + uint64_t ReferenceValue = UnknownAddress) { n_value = 0; if (!info->verbose) return nullptr; @@ -2432,8 +2436,7 @@ get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, bool isExtern = false; SymbolRef Symbol; for (const RelocationRef &Reloc : S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -2454,12 +2457,14 @@ get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, const char *SymbolName = nullptr; if (reloc_found && isExtern) { Symbol.getAddress(n_value); - if (n_value == UnknownAddressOrSize) + if (n_value == UnknownAddress) n_value = 0; - StringRef name; - Symbol.getName(name); - if (!name.empty()) { - SymbolName = name.data(); + ErrorOr<StringRef> NameOrError = Symbol.getName(); + if (std::error_code EC = NameOrError.getError()) + report_fatal_error(EC.message()); + StringRef Name = *NameOrError; + if (!Name.empty()) { + SymbolName = Name.data(); return SymbolName; } } @@ -2475,7 +2480,7 @@ get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, // We did not find an external relocation entry so look up the ReferenceValue // as an address of a symbol and if found return that symbol's name. - if (ReferenceValue != UnknownAddressOrSize) + if (ReferenceValue != UnknownAddress) SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap); return SymbolName; @@ -5614,8 +5619,7 @@ static const char *GuessLiteralPointer(uint64_t ReferenceValue, bool isExtern = false; SymbolRef Symbol; for (const RelocationRef &Reloc : info->S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -6109,8 +6113,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, // Parse relocations. std::vector<std::pair<uint64_t, SymbolRef>> Relocs; for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); uint64_t SectionAddress = Sections[SectIdx].getAddress(); RelocOffset -= SectionAddress; @@ -6125,14 +6128,15 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, SymbolAddressMap AddrMap; bool DisSymNameFound = false; for (const SymbolRef &Symbol : MachOOF->symbols()) { - SymbolRef::Type ST; - Symbol.getType(ST); + SymbolRef::Type ST = Symbol.getType(); if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { uint64_t Address; Symbol.getAddress(Address); - StringRef SymName; - Symbol.getName(SymName); + ErrorOr<StringRef> SymNameOrErr = Symbol.getName(); + if (std::error_code EC = SymNameOrErr.getError()) + report_fatal_error(EC.message()); + StringRef SymName = *SymNameOrErr; AddrMap[Address] = SymName; if (!DisSymName.empty() && DisSymName == SymName) DisSymNameFound = true; @@ -6171,11 +6175,12 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, // Disassemble symbol by symbol. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { - StringRef SymName; - Symbols[SymIdx].getName(SymName); + ErrorOr<StringRef> SymNameOrErr = Symbols[SymIdx].getName(); + if (std::error_code EC = SymNameOrErr.getError()) + report_fatal_error(EC.message()); + StringRef SymName = *SymNameOrErr; - SymbolRef::Type ST; - Symbols[SymIdx].getType(ST); + SymbolRef::Type ST = Symbols[SymIdx].getType(); if (ST != SymbolRef::ST_Function) continue; @@ -6200,8 +6205,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, uint64_t NextSym = 0; uint64_t NextSymIdx = SymIdx + 1; while (Symbols.size() > NextSymIdx) { - SymbolRef::Type NextSymType; - Symbols[NextSymIdx].getType(NextSymType); + SymbolRef::Type NextSymType = Symbols[NextSymIdx].getType(); if (NextSymType == SymbolRef::ST_Function) { containsNextSym = Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]); @@ -6437,7 +6441,10 @@ static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, const RelocationRef &Reloc, uint64_t Addr, StringRef &Name, uint64_t &Addend) { if (Reloc.getSymbol() != Obj->symbol_end()) { - Reloc.getSymbol()->getName(Name); + ErrorOr<StringRef> NameOrErr = Reloc.getSymbol()->getName(); + if (std::error_code EC = NameOrErr.getError()) + report_fatal_error(EC.message()); + Name = *NameOrErr; Addend = Addr; return; } @@ -6463,7 +6470,10 @@ static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, Sym->second.getSection(SymSection); if (RelocSection == *SymSection) { // There's a valid symbol in the same section before this reference. - Sym->second.getName(Name); + ErrorOr<StringRef> NameOrErr = Sym->second.getName(); + if (std::error_code EC = NameOrErr.getError()) + report_fatal_error(EC.message()); + Name = *NameOrErr; Addend = Addr - Sym->first; return; } @@ -6480,7 +6490,7 @@ static void printUnwindRelocDest(const MachOObjectFile *Obj, StringRef Name; uint64_t Addend; - if (!Reloc.getObjectFile()) + if (!Reloc.getObject()) return; findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend); @@ -6516,8 +6526,7 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, // Next we need to look at the relocations to find out what objects are // actually being referred to. for (const RelocationRef &Reloc : CompactUnwind.relocations()) { - uint64_t RelocAddress; - Reloc.getOffset(RelocAddress); + uint64_t RelocAddress = Reloc.getOffset(); uint32_t EntryIdx = RelocAddress / EntrySize; uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize; @@ -6553,7 +6562,7 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n'; // 4. The personality function, if present. - if (Entry.PersonalityReloc.getObjectFile()) { + if (Entry.PersonalityReloc.getObject()) { outs() << " personality function: " << format("0x%" PRIx64, Entry.PersonalityAddr) << ' '; printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc, @@ -6562,7 +6571,7 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, } // 5. This entry's language-specific data area. - if (Entry.LSDAReloc.getObjectFile()) { + if (Entry.LSDAReloc.getObject()) { outs() << " LSDA: " << format("0x%" PRIx64, Entry.LSDAAddr) << ' '; printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr); diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 1152a154b4db..786981854609 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -17,9 +17,11 @@ //===----------------------------------------------------------------------===// #include "llvm-objdump.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/FaultMaps.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" @@ -153,6 +155,9 @@ cl::opt<bool> llvm::PrintImmHex("print-imm-hex", cl::desc("Use hex format for immediate values")); +cl::opt<bool> PrintFaultMaps("fault-map-section", + cl::desc("Display contents of faultmap section")); + static StringRef ToolName; static int ReturnValue = EXIT_SUCCESS; @@ -207,9 +212,8 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) { } bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) return false; - if (error(b.getOffset(b_addr))) return false; + uint64_t a_addr = a.getOffset(); + uint64_t b_addr = b.getOffset(); return a_addr < b_addr; } @@ -294,60 +298,68 @@ PrettyPrinter &selectPrettyPrinter(Triple const &Triple) { } template <class ELFT> -static const typename ELFObjectFile<ELFT>::Elf_Rel * -getRel(const ELFFile<ELFT> &EF, DataRefImpl Rel) { - typedef typename ELFObjectFile<ELFT>::Elf_Rel Elf_Rel; - return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); -} - -template <class ELFT> -static const typename ELFObjectFile<ELFT>::Elf_Rela * -getRela(const ELFFile<ELFT> &EF, DataRefImpl Rela) { - typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela; - return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); -} - -template <class ELFT> static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj, DataRefImpl Rel, SmallVectorImpl<char> &Result) { typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; + typedef typename ELFObjectFile<ELFT>::Elf_Rel Elf_Rel; + typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela; + const ELFFile<ELFT> &EF = *Obj->getELFFile(); - const Elf_Shdr *sec = EF.getSection(Rel.d.a); + ErrorOr<const Elf_Shdr *> SecOrErr = EF.getSection(Rel.d.a); + if (std::error_code EC = SecOrErr.getError()) + return EC; + const Elf_Shdr *Sec = *SecOrErr; + ErrorOr<const Elf_Shdr *> SymTabOrErr = EF.getSection(Sec->sh_link); + if (std::error_code EC = SymTabOrErr.getError()) + return EC; + const Elf_Shdr *SymTab = *SymTabOrErr; + assert(SymTab->sh_type == ELF::SHT_SYMTAB || + SymTab->sh_type == ELF::SHT_DYNSYM); + ErrorOr<const Elf_Shdr *> StrTabSec = EF.getSection(SymTab->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(*StrTabSec); + if (std::error_code EC = StrTabOrErr.getError()) + return EC; + StringRef StrTab = *StrTabOrErr; uint8_t type; StringRef res; int64_t addend = 0; uint16_t symbol_index = 0; - switch (sec->sh_type) { + switch (Sec->sh_type) { default: return object_error::parse_failed; case ELF::SHT_REL: { - type = getRel(EF, Rel)->getType(EF.isMips64EL()); - symbol_index = getRel(EF, Rel)->getSymbol(EF.isMips64EL()); + const Elf_Rel *ERel = Obj->getRel(Rel); + type = ERel->getType(EF.isMips64EL()); + symbol_index = ERel->getSymbol(EF.isMips64EL()); // TODO: Read implicit addend from section data. break; } case ELF::SHT_RELA: { - type = getRela(EF, Rel)->getType(EF.isMips64EL()); - symbol_index = getRela(EF, Rel)->getSymbol(EF.isMips64EL()); - addend = getRela(EF, Rel)->r_addend; + const Elf_Rela *ERela = Obj->getRela(Rel); + type = ERela->getType(EF.isMips64EL()); + symbol_index = ERela->getSymbol(EF.isMips64EL()); + addend = ERela->r_addend; break; } } const Elf_Sym *symb = - EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index); + EF.template getEntry<Elf_Sym>(Sec->sh_link, symbol_index); StringRef Target; - const Elf_Shdr *SymSec = EF.getSection(symb); + ErrorOr<const Elf_Shdr *> SymSec = EF.getSection(symb); + if (std::error_code EC = SymSec.getError()) + return EC; if (symb->getType() == ELF::STT_SECTION) { - ErrorOr<StringRef> SecName = EF.getSectionName(SymSec); + ErrorOr<StringRef> SecName = EF.getSectionName(*SymSec); if (std::error_code EC = SecName.getError()) return EC; Target = *SecName; } else { - ErrorOr<StringRef> SymName = - EF.getSymbolName(EF.getSection(sec->sh_link), symb); + ErrorOr<StringRef> SymName = symb->getName(StrTab); if (!SymName) return SymName.getError(); Target = *SymName; @@ -421,9 +433,10 @@ static std::error_code getRelocationValueString(const COFFObjectFile *Obj, const RelocationRef &Rel, SmallVectorImpl<char> &Result) { symbol_iterator SymI = Rel.getSymbol(); - StringRef SymName; - if (std::error_code EC = SymI->getName(SymName)) + ErrorOr<StringRef> SymNameOrErr = SymI->getName(); + if (std::error_code EC = SymNameOrErr.getError()) return EC; + StringRef SymName = *SymNameOrErr; Result.append(SymName.begin(), SymName.end()); return std::error_code(); } @@ -443,15 +456,15 @@ static void printRelocationTargetName(const MachOObjectFile *O, for (const SymbolRef &Symbol : O->symbols()) { std::error_code ec; uint64_t Addr; - StringRef Name; + ErrorOr<StringRef> Name = Symbol.getName(); if ((ec = Symbol.getAddress(Addr))) report_fatal_error(ec.message()); if (Addr != Val) continue; - if ((ec = Symbol.getName(Name))) - report_fatal_error(ec.message()); - fmt << Name; + if (std::error_code EC = Name.getError()) + report_fatal_error(EC.message()); + fmt << *Name; return; } @@ -481,7 +494,9 @@ static void printRelocationTargetName(const MachOObjectFile *O, if (isExtern) { symbol_iterator SI = O->symbol_begin(); advance(SI, Val); - SI->getName(S); + ErrorOr<StringRef> SOrErr = SI->getName(); + if (!error(SOrErr.getError())) + S = *SOrErr; } else { section_iterator SI = O->section_begin(); // Adjust for the fact that sections are 1-indexed. @@ -672,7 +687,7 @@ static std::error_code getRelocationValueString(const MachOObjectFile *Obj, static std::error_code getRelocationValueString(const RelocationRef &Rel, SmallVectorImpl<char> &Result) { - const ObjectFile *Obj = Rel.getObjectFile(); + const ObjectFile *Obj = Rel.getObject(); if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj)) return getRelocationValueString(ELF, Rel, Result); if (auto *COFF = dyn_cast<COFFObjectFile>(Obj)) @@ -681,6 +696,39 @@ static std::error_code getRelocationValueString(const RelocationRef &Rel, return getRelocationValueString(MachO, Rel, Result); } +/// @brief Indicates whether this relocation should hidden when listing +/// relocations, usually because it is the trailing part of a multipart +/// relocation that will be printed as part of the leading relocation. +static bool getHidden(RelocationRef RelRef) { + const ObjectFile *Obj = RelRef.getObject(); + auto *MachO = dyn_cast<MachOObjectFile>(Obj); + if (!MachO) + return false; + + unsigned Arch = MachO->getArch(); + DataRefImpl Rel = RelRef.getRawDataRefImpl(); + uint64_t Type = MachO->getRelocationType(Rel); + + // On arches that use the generic relocations, GENERIC_RELOC_PAIR + // is always hidden. + if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) { + if (Type == MachO::GENERIC_RELOC_PAIR) + return true; + } else if (Arch == Triple::x86_64) { + // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows + // an X86_64_RELOC_SUBTRACTOR. + if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) { + DataRefImpl RelPrev = Rel; + RelPrev.d.a--; + uint64_t PrevType = MachO->getRelocationType(RelPrev); + if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR) + return true; + } + } + + return false; +} + static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { const Target *TheTarget = getTarget(Obj); // getTarget() will have already issued a diagnostic if necessary, so @@ -779,16 +827,16 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { uint64_t Address; if (error(Symbol.getAddress(Address))) break; - if (Address == UnknownAddressOrSize) + if (Address == UnknownAddress) continue; Address -= SectionAddr; if (Address >= SectSize) continue; - StringRef Name; - if (error(Symbol.getName(Name))) + ErrorOr<StringRef> Name = Symbol.getName(); + if (error(Name.getError())) break; - Symbols.push_back(std::make_pair(Address, Name)); + Symbols.push_back(std::make_pair(Address, *Name)); } } @@ -877,19 +925,17 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // Print relocation for instruction. while (rel_cur != rel_end) { - bool hidden = false; - uint64_t addr; + bool hidden = getHidden(*rel_cur); + uint64_t addr = rel_cur->getOffset(); SmallString<16> name; SmallString<32> val; // If this relocation is hidden, skip it. - if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; if (hidden) 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; + rel_cur->getTypeName(name); if (error(getRelocationValueString(*rel_cur, val))) goto skip_print_rel; outs() << format(Fmt.data(), SectionAddr + addr) << name @@ -919,18 +965,13 @@ void llvm::PrintRelocations(const ObjectFile *Obj) { continue; outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n"; for (const RelocationRef &Reloc : Section.relocations()) { - bool hidden; - uint64_t address; + bool hidden = getHidden(Reloc); + uint64_t address = Reloc.getOffset(); SmallString<32> relocname; SmallString<32> valuestr; - if (error(Reloc.getHidden(hidden))) - continue; if (hidden) continue; - if (error(Reloc.getTypeName(relocname))) - continue; - if (error(Reloc.getOffset(address))) - continue; + Reloc.getTypeName(relocname); if (error(getRelocationValueString(Reloc, valuestr))) continue; outs() << format(Fmt.data(), address) << " " << relocname << " " @@ -1073,21 +1114,21 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { } for (const SymbolRef &Symbol : o->symbols()) { uint64_t Address; - SymbolRef::Type Type; + SymbolRef::Type Type = Symbol.getType(); uint32_t Flags = Symbol.getFlags(); section_iterator Section = o->section_end(); if (error(Symbol.getAddress(Address))) continue; - if (error(Symbol.getType(Type))) - continue; - uint64_t Size = Symbol.getSize(); if (error(Symbol.getSection(Section))) continue; StringRef Name; if (Type == SymbolRef::ST_Debug && Section != o->section_end()) { Section->getName(Name); - } else if (error(Symbol.getName(Name))) { - continue; + } else { + ErrorOr<StringRef> NameOrErr = Symbol.getName(); + if (error(NameOrErr.getError())) + continue; + Name = *NameOrErr; } bool Global = Flags & SymbolRef::SF_Global; @@ -1096,15 +1137,11 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { bool Common = Flags & SymbolRef::SF_Common; bool Hidden = Flags & SymbolRef::SF_Hidden; - if (Common) { - uint32_t Alignment = Symbol.getAlignment(); - Address = Size; - Size = Alignment; - } - if (Address == UnknownAddressOrSize) + if (Common) + Address = Symbol.getCommonSize(); + + if (Address == UnknownAddress) Address = 0; - if (Size == UnknownAddressOrSize) - Size = 0; char GlobLoc = ' '; if (Type != SymbolRef::ST_Unknown) GlobLoc = Global ? 'g' : 'l'; @@ -1146,8 +1183,14 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { SectionName = ""; outs() << SectionName; } - outs() << '\t' - << format("%08" PRIx64 " ", Size); + + outs() << '\t'; + if (Common || isa<ELFObjectFileBase>(o)) { + uint64_t Val = + Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize(); + outs() << format("\t %08" PRIx64 " ", Val); + } + if (Hidden) { outs() << ".hidden "; } @@ -1226,6 +1269,49 @@ void llvm::printWeakBindTable(const ObjectFile *o) { } } +static void printFaultMaps(const ObjectFile *Obj) { + const char *FaultMapSectionName = nullptr; + + if (isa<ELFObjectFileBase>(Obj)) { + FaultMapSectionName = ".llvm_faultmaps"; + } else if (isa<MachOObjectFile>(Obj)) { + FaultMapSectionName = "__llvm_faultmaps"; + } else { + errs() << "This operation is only currently supported " + "for ELF and Mach-O executable files.\n"; + return; + } + + Optional<object::SectionRef> FaultMapSection; + + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == FaultMapSectionName) { + FaultMapSection = Sec; + break; + } + } + + outs() << "FaultMap table:\n"; + + if (!FaultMapSection.hasValue()) { + outs() << "<not found>\n"; + return; + } + + StringRef FaultMapContents; + if (error(FaultMapSection.getValue().getContents(FaultMapContents))) { + errs() << "Could not read the " << FaultMapContents << " section!\n"; + return; + } + + FaultMapParser FMP(FaultMapContents.bytes_begin(), + FaultMapContents.bytes_end()); + + outs() << FMP; +} + static void printPrivateFileHeader(const ObjectFile *o) { if (o->isELF()) { printELFFileHeader(o); @@ -1265,6 +1351,8 @@ static void DumpObject(const ObjectFile *o) { printLazyBindTable(o); if (WeakBind) printWeakBindTable(o); + if (PrintFaultMaps) + printFaultMaps(o); } /// @brief Dump each object file in \a a; @@ -1362,7 +1450,8 @@ int main(int argc, char **argv) { && !(DylibsUsed && MachOOpt) && !(DylibId && MachOOpt) && !(ObjcMetaData && MachOOpt) - && !(DumpSections.size() != 0 && MachOOpt)) { + && !(DumpSections.size() != 0 && MachOOpt) + && !PrintFaultMaps) { cl::PrintHelpMessage(); return 2; } |