diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-readobj')
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/ARMEHABIPrinter.h | 44 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp | 40 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/COFFDumper.cpp | 59 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/ELFDumper.cpp | 224 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/MachODumper.cpp | 46 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/ObjDumper.h | 3 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/StackMapPrinter.h | 80 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/Win64EHDumper.cpp | 20 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp | 26 |
9 files changed, 379 insertions, 163 deletions
diff --git a/contrib/llvm/tools/llvm-readobj/ARMEHABIPrinter.h b/contrib/llvm/tools/llvm-readobj/ARMEHABIPrinter.h index b15421d..dd2490d 100644 --- a/contrib/llvm/tools/llvm-readobj/ARMEHABIPrinter.h +++ b/contrib/llvm/tools/llvm-readobj/ARMEHABIPrinter.h @@ -312,8 +312,6 @@ class PrinterContext { typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr; typedef typename object::ELFFile<ET>::Elf_Rel_Iter Elf_Rel_iterator; - typedef typename object::ELFFile<ET>::Elf_Sym_Iter Elf_Sym_iterator; - typedef typename object::ELFFile<ET>::Elf_Shdr_Iter Elf_Shdr_iterator; static const size_t IndexTableEntrySize; @@ -344,13 +342,13 @@ template <typename ET> const size_t PrinterContext<ET>::IndexTableEntrySize = 8; template <typename ET> -ErrorOr<StringRef> PrinterContext<ET>::FunctionAtAddress(unsigned Section, - uint64_t Address) const { - for (Elf_Sym_iterator SI = ELF->begin_symbols(), SE = ELF->end_symbols(); - SI != SE; ++SI) - if (SI->st_shndx == Section && SI->st_value == Address && - SI->getType() == ELF::STT_FUNC) - return ELF->getSymbolName(SI); +ErrorOr<StringRef> +PrinterContext<ET>::FunctionAtAddress(unsigned Section, + uint64_t Address) const { + for (const Elf_Sym &Sym : ELF->symbols()) + if (Sym.st_shndx == Section && Sym.st_value == Address && + Sym.getType() == ELF::STT_FUNC) + return ELF->getSymbolName(&Sym, false); return readobj_error::unknown_symbol; } @@ -366,10 +364,9 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex, /// handling table. Use this symbol to recover the actual exception handling /// table. - for (Elf_Shdr_iterator SI = ELF->begin_sections(), SE = ELF->end_sections(); - SI != SE; ++SI) { - if (SI->sh_type == ELF::SHT_REL && SI->sh_info == IndexSectionIndex) { - for (Elf_Rel_iterator RI = ELF->begin_rel(&*SI), RE = ELF->end_rel(&*SI); + for (const Elf_Shdr &Sec : ELF->sections()) { + if (Sec.sh_type == ELF::SHT_REL && Sec.sh_info == IndexSectionIndex) { + for (Elf_Rel_iterator RI = ELF->rel_begin(&Sec), RE = ELF->rel_end(&Sec); RI != RE; ++RI) { if (RI->r_offset == static_cast<unsigned>(IndexTableOffset)) { typename object::ELFFile<ET>::Elf_Rela RelA; @@ -378,9 +375,12 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex, RelA.r_addend = 0; std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol = - ELF->getRelocationSymbol(&(*SI), &RelA); + ELF->getRelocationSymbol(&Sec, &RelA); - return ELF->getSection(Symbol.second); + ErrorOr<const Elf_Shdr *> Ret = ELF->getSection(Symbol.second); + if (std::error_code EC = Ret.getError()) + report_fatal_error(EC.message()); + return *Ret; } } } @@ -528,20 +528,18 @@ void PrinterContext<ET>::PrintUnwindInformation() const { DictScope UI(SW, "UnwindInformation"); int SectionIndex = 0; - for (Elf_Shdr_iterator SI = ELF->begin_sections(), SE = ELF->end_sections(); - SI != SE; ++SI, ++SectionIndex) { - if (SI->sh_type == ELF::SHT_ARM_EXIDX) { - const Elf_Shdr *IT = &(*SI); - + for (const Elf_Shdr &Sec : ELF->sections()) { + if (Sec.sh_type == ELF::SHT_ARM_EXIDX) { DictScope UIT(SW, "UnwindIndexTable"); SW.printNumber("SectionIndex", SectionIndex); - if (ErrorOr<StringRef> SectionName = ELF->getSectionName(IT)) + if (ErrorOr<StringRef> SectionName = ELF->getSectionName(&Sec)) SW.printString("SectionName", *SectionName); - SW.printHex("SectionOffset", IT->sh_offset); + SW.printHex("SectionOffset", Sec.sh_offset); - PrintIndexTable(SectionIndex, IT); + PrintIndexTable(SectionIndex, &Sec); } + ++SectionIndex; } } } diff --git a/contrib/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp b/contrib/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp index 62252fc..a1ea79f 100644 --- a/contrib/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp +++ b/contrib/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp @@ -198,13 +198,8 @@ Decoder::getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) { ErrorOr<object::SymbolRef> Decoder::getSymbol(const COFFObjectFile &COFF, uint64_t VA, bool FunctionOnly) { for (const auto &Symbol : COFF.symbols()) { - if (FunctionOnly) { - SymbolRef::Type Type; - if (std::error_code EC = Symbol.getType(Type)) - return EC; - if (Type != SymbolRef::ST_Function) - continue; - } + if (FunctionOnly && Symbol.getType() != SymbolRef::ST_Function) + continue; uint64_t Address; if (std::error_code EC = Symbol.getAddress(Address)) @@ -219,9 +214,7 @@ ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &, const SectionRef &Section, uint64_t Offset) { for (const auto &Relocation : Section.relocations()) { - uint64_t RelocationOffset; - if (auto Error = Relocation.getOffset(RelocationOffset)) - return Error; + uint64_t RelocationOffset = Relocation.getOffset(); if (RelocationOffset == Offset) return *Relocation.getSymbol(); } @@ -574,12 +567,12 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF, if (!Symbol) Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true); - StringRef Name; - if (Symbol) - Symbol->getName(Name); + ErrorOr<StringRef> Name = Symbol->getName(); + if (std::error_code EC = Name.getError()) + report_fatal_error(EC.message()); ListScope EHS(SW, "ExceptionHandler"); - SW.printString("Routine", formatSymbol(Name, Address)); + SW.printString("Routine", formatSymbol(*Name, Address)); SW.printHex("Parameter", Parameter); } @@ -608,7 +601,10 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF, StringRef FunctionName; uint64_t FunctionAddress; if (Function) { - Function->getName(FunctionName); + ErrorOr<StringRef> FunctionNameOrErr = Function->getName(); + if (std::error_code EC = FunctionNameOrErr.getError()) + report_fatal_error(EC.message()); + FunctionName = *FunctionNameOrErr; Function->getAddress(FunctionAddress); } else { const pe32_header *PEHeader; @@ -620,13 +616,14 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF, SW.printString("Function", formatSymbol(FunctionName, FunctionAddress)); if (XDataRecord) { - StringRef Name; - uint64_t Address; + ErrorOr<StringRef> Name = XDataRecord->getName(); + if (std::error_code EC = Name.getError()) + report_fatal_error(EC.message()); - XDataRecord->getName(Name); + uint64_t Address; XDataRecord->getAddress(Address); - SW.printString("ExceptionRecord", formatSymbol(Name, Address)); + SW.printString("ExceptionRecord", formatSymbol(*Name, Address)); section_iterator SI = COFF.section_end(); if (XDataRecord->getSection(SI)) @@ -665,7 +662,10 @@ bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF, StringRef FunctionName; uint64_t FunctionAddress; if (Function) { - Function->getName(FunctionName); + ErrorOr<StringRef> FunctionNameOrErr = Function->getName(); + if (std::error_code EC = FunctionNameOrErr.getError()) + report_fatal_error(EC.message()); + FunctionName = *FunctionNameOrErr; Function->getAddress(FunctionAddress); } else { const pe32_header *PEHeader; diff --git a/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp b/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp index 4a1d5da..f5effe2 100644 --- a/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -16,6 +16,7 @@ #include "ARMWinEHPrinter.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "Win64EHDumper.h" #include "llvm/ADT/DenseMap.h" @@ -60,7 +61,7 @@ public: void printCOFFExports() override; void printCOFFDirectives() override; void printCOFFBaseReloc() override; - + void printStackMap() const override; private: void printSymbol(const SymbolRef &Sym); void printRelocation(const SectionRef &Section, const RelocationRef &Reloc); @@ -120,9 +121,7 @@ std::error_code COFFDumper::resolveSymbol(const coff_section *Section, uint64_t Offset, SymbolRef &Sym) { const auto &Relocations = RelocMap[Section]; for (const auto &Relocation : Relocations) { - uint64_t RelocationOffset; - if (std::error_code EC = Relocation.getOffset(RelocationOffset)) - return EC; + uint64_t RelocationOffset = Relocation.getOffset(); if (RelocationOffset == Offset) { Sym = *Relocation.getSymbol(); @@ -140,8 +139,10 @@ std::error_code COFFDumper::resolveSymbolName(const coff_section *Section, SymbolRef Symbol; if (std::error_code EC = resolveSymbol(Section, Offset, Symbol)) return EC; - if (std::error_code EC = Symbol.getName(Name)) + ErrorOr<StringRef> NameOrErr = Symbol.getName(); + if (std::error_code EC = NameOrErr.getError()) return EC; + Name = *NameOrErr; return std::error_code(); } @@ -804,19 +805,18 @@ void COFFDumper::printRelocations() { void COFFDumper::printRelocation(const SectionRef &Section, const RelocationRef &Reloc) { - uint64_t Offset; - uint64_t RelocType; + uint64_t Offset = Reloc.getOffset(); + uint64_t RelocType = Reloc.getType(); SmallString<32> RelocName; StringRef SymbolName; - if (error(Reloc.getOffset(Offset))) - return; - if (error(Reloc.getType(RelocType))) - return; - if (error(Reloc.getTypeName(RelocName))) - return; + Reloc.getTypeName(RelocName); symbol_iterator Symbol = Reloc.getSymbol(); - if (Symbol != Obj->symbol_end() && error(Symbol->getName(SymbolName))) - return; + if (Symbol != Obj->symbol_end()) { + ErrorOr<StringRef> SymbolNameOrErr = Symbol->getName(); + if (error(SymbolNameOrErr.getError())) + return; + SymbolName = *SymbolNameOrErr; + } if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); @@ -1140,3 +1140,32 @@ void COFFDumper::printCOFFBaseReloc() { W.printHex("Address", RVA); } } + +void COFFDumper::printStackMap() const { + object::SectionRef StackMapSection; + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == ".llvm_stackmaps") { + StackMapSection = Sec; + break; + } + } + + if (StackMapSection == object::SectionRef()) + return; + + StringRef StackMapContents; + StackMapSection.getContents(StackMapContents); + ArrayRef<uint8_t> StackMapContentsArray( + reinterpret_cast<const uint8_t*>(StackMapContents.data()), + StackMapContents.size()); + + if (Obj->isLittleEndian()) + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<support::little>(StackMapContentsArray)); + else + prettyPrintStackMap(llvm::outs(), + StackMapV1Parser<support::big>(StackMapContentsArray)); +} diff --git a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp index 99969fd..a4b25ef 100644 --- a/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/contrib/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -17,6 +17,7 @@ #include "ARMEHABIPrinter.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" @@ -47,6 +48,7 @@ public: void printFileHeaders() override; void printSections() override; void printRelocations() override; + void printDynamicRelocations() override; void printSymbols() override; void printDynamicSymbols() override; void printUnwindInfo() override; @@ -60,12 +62,14 @@ public: void printMipsABIFlags() override; void printMipsReginfo() override; + void printStackMap() const override; + private: typedef ELFFile<ELFT> ELFO; typedef typename ELFO::Elf_Shdr Elf_Shdr; typedef typename ELFO::Elf_Sym Elf_Sym; - void printSymbol(typename ELFO::Elf_Sym_Iter Symbol); + void printSymbol(const Elf_Sym *Symbol, bool IsDynamic); void printRelocations(const Elf_Shdr *Sec); void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel); @@ -119,9 +123,10 @@ std::error_code createELFDumper(const object::ObjectFile *Obj, template <typename ELFO> static std::string getFullSymbolName(const ELFO &Obj, - typename ELFO::Elf_Sym_Iter Symbol) { - StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol)); - if (!Symbol.isDynamic()) + const typename ELFO::Elf_Sym *Symbol, + bool IsDynamic) { + StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol, IsDynamic)); + if (!IsDynamic) return SymbolName; std::string FullSymbolName(SymbolName); @@ -139,7 +144,7 @@ static std::string getFullSymbolName(const ELFO &Obj, template <typename ELFO> static void -getSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol, +getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, StringRef &SectionName, unsigned &SectionIndex) { SectionIndex = Symbol->st_shndx; if (Symbol->isUndefined()) @@ -156,11 +161,10 @@ getSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol, SectionName = "Reserved"; else { if (SectionIndex == SHN_XINDEX) - SectionIndex = Obj.getSymbolTableIndex(&*Symbol); - assert(SectionIndex != SHN_XINDEX && - "getSymbolTableIndex should handle this"); - const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex); - SectionName = errorOrDefault(Obj.getSectionName(Sec)); + SectionIndex = Obj.getExtendedSymbolTableIndex(&*Symbol); + ErrorOr<const typename ELFO::Elf_Shdr *> Sec = Obj.getSection(SectionIndex); + if (!error(Sec.getError())) + SectionName = errorOrDefault(Obj.getSectionName(*Sec)); } } @@ -382,7 +386,8 @@ static const EnumEntry<unsigned> ElfMachineType[] = { LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ), - LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ) + LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_AMDGPU ) }; static const EnumEntry<unsigned> ElfSymbolBindings[] = { @@ -574,7 +579,13 @@ void ELFDumper<ELFT>::printFileHeaders() { W.printEnum ("DataEncoding", Header->e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding)); W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]); - W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI], + + // Handle architecture specific OS/ABI values. + if (Header->e_machine == ELF::EM_AMDGPU && + Header->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA) + W.printHex("OS/ABI", "AMDGPU_HSA", ELF::ELFOSABI_AMDGPU_HSA); + else + W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI)); W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]); W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD)); @@ -606,46 +617,44 @@ void ELFDumper<ELFT>::printSections() { ListScope SectionsD(W, "Sections"); int SectionIndex = -1; - for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; ++SecI) { + for (const typename ELFO::Elf_Shdr &Sec : Obj->sections()) { ++SectionIndex; - const Elf_Shdr *Section = &*SecI; - StringRef Name = errorOrDefault(Obj->getSectionName(Section)); + StringRef Name = errorOrDefault(Obj->getSectionName(&Sec)); DictScope SectionD(W, "Section"); W.printNumber("Index", SectionIndex); - W.printNumber("Name", Name, Section->sh_name); + W.printNumber("Name", Name, Sec.sh_name); W.printHex("Type", - getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type), - Section->sh_type); - W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags)); - W.printHex ("Address", Section->sh_addr); - W.printHex ("Offset", Section->sh_offset); - W.printNumber("Size", Section->sh_size); - W.printNumber("Link", Section->sh_link); - W.printNumber("Info", Section->sh_info); - W.printNumber("AddressAlignment", Section->sh_addralign); - W.printNumber("EntrySize", Section->sh_entsize); + getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type), + Sec.sh_type); + W.printFlags("Flags", Sec.sh_flags, makeArrayRef(ElfSectionFlags)); + W.printHex("Address", Sec.sh_addr); + W.printHex("Offset", Sec.sh_offset); + W.printNumber("Size", Sec.sh_size); + W.printNumber("Link", Sec.sh_link); + W.printNumber("Info", Sec.sh_info); + W.printNumber("AddressAlignment", Sec.sh_addralign); + W.printNumber("EntrySize", Sec.sh_entsize); if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - printRelocations(Section); + printRelocations(&Sec); } if (opts::SectionSymbols) { ListScope D(W, "Symbols"); - for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), - SymE = Obj->end_symbols(); - SymI != SymE; ++SymI) { - if (Obj->getSection(&*SymI) == Section) - printSymbol(SymI); + for (const typename ELFO::Elf_Sym &Sym : Obj->symbols()) { + ErrorOr<const Elf_Shdr *> SymSec = Obj->getSection(&Sym); + if (!SymSec) + continue; + if (*SymSec == &Sec) + printSymbol(&Sym, false); } } - if (opts::SectionData && Section->sh_type != ELF::SHT_NOBITS) { - ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section)); + if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) { + ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(&Sec)); W.printBinaryBlock("SectionData", StringRef((const char *)Data.data(), Data.size())); } @@ -657,32 +666,63 @@ void ELFDumper<ELFT>::printRelocations() { ListScope D(W, "Relocations"); int SectionNumber = -1; - for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; ++SecI) { + for (const typename ELFO::Elf_Shdr &Sec : Obj->sections()) { ++SectionNumber; - if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA) + if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA) continue; - StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI)); + StringRef Name = errorOrDefault(Obj->getSectionName(&Sec)); W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; W.indent(); - printRelocations(&*SecI); + printRelocations(&Sec); W.unindent(); W.startLine() << "}\n"; } } +template<class ELFT> +void ELFDumper<ELFT>::printDynamicRelocations() { + W.startLine() << "Dynamic Relocations {\n"; + W.indent(); + for (typename ELFO::Elf_Rela_Iter RelI = Obj->dyn_rela_begin(), + RelE = Obj->dyn_rela_end(); + RelI != RelE; ++RelI) { + SmallString<32> RelocName; + Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName); + StringRef SymbolName; + uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL()); + const typename ELFO::Elf_Sym *Sym = Obj->dynamic_symbol_begin() + SymIndex; + SymbolName = errorOrDefault(Obj->getSymbolName(Sym, true)); + if (opts::ExpandRelocs) { + DictScope Group(W, "Relocation"); + W.printHex("Offset", RelI->r_offset); + W.printNumber("Type", RelocName, (int)RelI->getType(Obj->isMips64EL())); + W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); + W.printHex("Addend", RelI->r_addend); + } + else { + raw_ostream& OS = W.startLine(); + OS << W.hex(RelI->r_offset) + << " " << RelocName + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << " " << W.hex(RelI->r_addend) + << "\n"; + } + } + W.unindent(); + W.startLine() << "}\n"; +} + template <class ELFT> void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) { switch (Sec->sh_type) { case ELF::SHT_REL: - for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec), - RE = Obj->end_rel(Sec); + for (typename ELFO::Elf_Rel_Iter RI = Obj->rel_begin(Sec), + RE = Obj->rel_end(Sec); RI != RE; ++RI) { typename ELFO::Elf_Rela Rela; Rela.r_offset = RI->r_offset; @@ -692,8 +732,8 @@ void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) { } break; case ELF::SHT_RELA: - for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec), - RE = Obj->end_rela(Sec); + for (typename ELFO::Elf_Rela_Iter RI = Obj->rela_begin(Sec), + RE = Obj->rela_end(Sec); RI != RE; ++RI) { printRelocation(Sec, *RI); } @@ -710,12 +750,20 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec, std::pair<const Elf_Shdr *, const Elf_Sym *> Sym = Obj->getRelocationSymbol(Sec, &Rel); if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) { - const Elf_Shdr *Sec = Obj->getSection(Sym.second); - ErrorOr<StringRef> SecName = Obj->getSectionName(Sec); - if (SecName) - TargetName = SecName.get(); + ErrorOr<const Elf_Shdr *> Sec = Obj->getSection(Sym.second); + if (!error(Sec.getError())) { + ErrorOr<StringRef> SecName = Obj->getSectionName(*Sec); + if (SecName) + TargetName = SecName.get(); + } } else if (Sym.first) { - TargetName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second)); + const Elf_Shdr *SymTable = Sym.first; + ErrorOr<const Elf_Shdr *> StrTableSec = Obj->getSection(SymTable->sh_link); + if (!error(StrTableSec.getError())) { + ErrorOr<StringRef> StrTableOrErr = Obj->getStringTable(*StrTableSec); + if (!error(StrTableOrErr.getError())) + TargetName = errorOrDefault(Sym.second->getName(*StrTableOrErr)); + } } if (opts::ExpandRelocs) { @@ -736,30 +784,25 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec, template<class ELFT> void ELFDumper<ELFT>::printSymbols() { ListScope Group(W, "Symbols"); - for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), - SymE = Obj->end_symbols(); - SymI != SymE; ++SymI) { - printSymbol(SymI); - } + for (const typename ELFO::Elf_Sym &Sym : Obj->symbols()) + printSymbol(&Sym, false); } template<class ELFT> void ELFDumper<ELFT>::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); - for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(), - SymE = Obj->end_dynamic_symbols(); - SymI != SymE; ++SymI) { - printSymbol(SymI); - } + for (const typename ELFO::Elf_Sym &Sym : Obj->dynamic_symbols()) + printSymbol(&Sym, true); } template <class ELFT> -void ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) { +void ELFDumper<ELFT>::printSymbol(const typename ELFO::Elf_Sym *Symbol, + bool IsDynamic) { unsigned SectionIndex = 0; StringRef SectionName; getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex); - std::string FullSymbolName = getFullSymbolName(*Obj, Symbol); + std::string FullSymbolName = getFullSymbolName(*Obj, Symbol, IsDynamic); DictScope D(W, "Symbol"); W.printNumber("Name", FullSymbolName, Symbol->st_name); @@ -987,6 +1030,9 @@ static void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value, case DT_FLAGS_1: printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS); break; + default: + OS << format("0x%" PRIX64, Value); + break; } } @@ -1056,9 +1102,9 @@ template<class ELFT> void ELFDumper<ELFT>::printProgramHeaders() { ListScope L(W, "ProgramHeaders"); - for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(), - PE = Obj->end_program_headers(); - PI != PE; ++PI) { + for (typename ELFO::Elf_Phdr_Iter PI = Obj->program_header_begin(), + PE = Obj->program_header_end(); + PI != PE; ++PI) { DictScope P(W, "ProgramHeader"); W.printHex ("Type", getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type), @@ -1086,12 +1132,11 @@ template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() { } DictScope BA(W, "BuildAttributes"); - for (ELFO::Elf_Shdr_Iter SI = Obj->begin_sections(), SE = Obj->end_sections(); - SI != SE; ++SI) { - if (SI->sh_type != ELF::SHT_ARM_ATTRIBUTES) + for (const ELFO::Elf_Shdr &Sec : Obj->sections()) { + if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES) continue; - ErrorOr<ArrayRef<uint8_t> > Contents = Obj->getSectionContents(&(*SI)); + ErrorOr<ArrayRef<uint8_t>> Contents = Obj->getSectionContents(&Sec); if (!Contents) continue; @@ -1115,13 +1160,13 @@ template <class ELFT> class MipsGOTParser { public: typedef object::ELFFile<ELFT> ObjectFile; typedef typename ObjectFile::Elf_Shdr Elf_Shdr; + typedef typename ObjectFile::Elf_Sym Elf_Sym; MipsGOTParser(const ObjectFile *Obj, StreamWriter &W) : Obj(Obj), W(W) {} void parseGOT(const Elf_Shdr &GOTShdr); private: - typedef typename ObjectFile::Elf_Sym_Iter Elf_Sym_Iter; typedef typename ObjectFile::Elf_Addr GOTEntry; typedef typename ObjectFile::template ELFEntityIterator<const GOTEntry> GOTIter; @@ -1135,7 +1180,7 @@ private: bool getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym); void printGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It); void printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It, - Elf_Sym_Iter Sym); + const Elf_Sym *Sym, bool IsDynamic); }; } @@ -1161,8 +1206,8 @@ void MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) { return; } - Elf_Sym_Iter DynSymBegin = Obj->begin_dynamic_symbols(); - Elf_Sym_Iter DynSymEnd = Obj->end_dynamic_symbols(); + const Elf_Sym *DynSymBegin = Obj->dynamic_symbol_begin(); + const Elf_Sym *DynSymEnd = Obj->dynamic_symbol_end(); std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd)); if (DtGotSym > DynSymTotal) { @@ -1210,10 +1255,10 @@ void MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) { ListScope GS(W, "Global entries"); GOTIter GotGlobalEnd = makeGOTIter(*GOT, DtLocalGotNum + GlobalGotNum); - Elf_Sym_Iter GotDynSym = DynSymBegin + DtGotSym; + const Elf_Sym *GotDynSym = DynSymBegin + DtGotSym; for (; It != GotGlobalEnd; ++It) { DictScope D(W, "Entry"); - printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++); + printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++, true); } } @@ -1274,7 +1319,8 @@ void MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr, GOTIter BeginIt, template <class ELFT> void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, - GOTIter It, Elf_Sym_Iter Sym) { + GOTIter It, const Elf_Sym *Sym, + bool IsDynamic) { printGotEntry(GotAddr, BeginIt, It); W.printHex("Value", Sym->st_value); @@ -1285,7 +1331,7 @@ void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex); W.printHex("Section", SectionName, SectionIndex); - std::string FullSymbolName = getFullSymbolName(*Obj, Sym); + std::string FullSymbolName = getFullSymbolName(*Obj, Sym, IsDynamic); W.printNumber("Name", FullSymbolName, Sym->st_name); } @@ -1452,3 +1498,25 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() { W.printHex("Co-Proc Mask2", Reginfo->ri_cprmask[2]); W.printHex("Co-Proc Mask3", Reginfo->ri_cprmask[3]); } + +template <class ELFT> void ELFDumper<ELFT>::printStackMap() const { + const typename ELFFile<ELFT>::Elf_Shdr *StackMapSection = nullptr; + for (const auto &Sec : Obj->sections()) { + ErrorOr<StringRef> Name = Obj->getSectionName(&Sec); + if (*Name == ".llvm_stackmaps") { + StackMapSection = &Sec; + break; + } + } + + if (!StackMapSection) + return; + + StringRef StackMapContents; + ErrorOr<ArrayRef<uint8_t>> StackMapContentsArray = + Obj->getSectionContents(StackMapSection); + + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<ELFT::TargetEndianness>(*StackMapContentsArray)); +} diff --git a/contrib/llvm/tools/llvm-readobj/MachODumper.cpp b/contrib/llvm/tools/llvm-readobj/MachODumper.cpp index aeb563a..adb99b0 100644 --- a/contrib/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/contrib/llvm/tools/llvm-readobj/MachODumper.cpp @@ -14,6 +14,7 @@ #include "llvm-readobj.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -37,6 +38,7 @@ public: void printSymbols() override; void printDynamicSymbols() override; void printUnwindInfo() override; + void printStackMap() const override; private: template<class MachHeader> @@ -459,12 +461,9 @@ void MachODumper::printRelocation(const RelocationRef &Reloc) { void MachODumper::printRelocation(const MachOObjectFile *Obj, const RelocationRef &Reloc) { - uint64_t Offset; + uint64_t Offset = Reloc.getOffset(); SmallString<32> RelocName; - if (error(Reloc.getOffset(Offset))) - return; - if (error(Reloc.getTypeName(RelocName))) - return; + Reloc.getTypeName(RelocName); DataRefImpl DR = Reloc.getRawDataRefImpl(); MachO::any_relocation_info RE = Obj->getRelocation(DR); @@ -475,8 +474,10 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj, if (IsExtern) { symbol_iterator Symbol = Reloc.getSymbol(); if (Symbol != Obj->symbol_end()) { - if (error(Symbol->getName(TargetName))) + ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); + if (error(TargetNameOrErr.getError())) return; + TargetName = *TargetNameOrErr; } } else if (!IsScattered) { section_iterator SecI = Obj->getRelocationSection(DR); @@ -539,8 +540,8 @@ void MachODumper::printDynamicSymbols() { void MachODumper::printSymbol(const SymbolRef &Symbol) { StringRef SymbolName; - if (Symbol.getName(SymbolName)) - SymbolName = ""; + if (ErrorOr<StringRef> SymbolNameOrErr = Symbol.getName()) + SymbolName = *SymbolNameOrErr; MachOSymbol MOSymbol; getSymbol(Obj, Symbol.getRawDataRefImpl(), MOSymbol); @@ -573,3 +574,32 @@ void MachODumper::printSymbol(const SymbolRef &Symbol) { void MachODumper::printUnwindInfo() { W.startLine() << "UnwindInfo not implemented.\n"; } + +void MachODumper::printStackMap() const { + object::SectionRef StackMapSection; + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == "__llvm_stackmaps") { + StackMapSection = Sec; + break; + } + } + + if (StackMapSection == object::SectionRef()) + return; + + StringRef StackMapContents; + StackMapSection.getContents(StackMapContents); + ArrayRef<uint8_t> StackMapContentsArray( + reinterpret_cast<const uint8_t*>(StackMapContents.data()), + StackMapContents.size()); + + if (Obj->isLittleEndian()) + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<support::little>(StackMapContentsArray)); + else + prettyPrintStackMap(llvm::outs(), + StackMapV1Parser<support::big>(StackMapContentsArray)); +} diff --git a/contrib/llvm/tools/llvm-readobj/ObjDumper.h b/contrib/llvm/tools/llvm-readobj/ObjDumper.h index 323f5e3..27e15b2 100644 --- a/contrib/llvm/tools/llvm-readobj/ObjDumper.h +++ b/contrib/llvm/tools/llvm-readobj/ObjDumper.h @@ -33,6 +33,7 @@ public: virtual void printUnwindInfo() = 0; // Only implemented for ELF at this time. + virtual void printDynamicRelocations() { } virtual void printDynamicTable() { } virtual void printNeededLibraries() { } virtual void printProgramHeaders() { } @@ -51,6 +52,8 @@ public: virtual void printCOFFDirectives() { } virtual void printCOFFBaseReloc() { } + virtual void printStackMap() const = 0; + protected: StreamWriter& W; }; diff --git a/contrib/llvm/tools/llvm-readobj/StackMapPrinter.h b/contrib/llvm/tools/llvm-readobj/StackMapPrinter.h new file mode 100644 index 0000000..92645bc --- /dev/null +++ b/contrib/llvm/tools/llvm-readobj/StackMapPrinter.h @@ -0,0 +1,80 @@ +//===-------- StackMapPrinter.h - Pretty-print stackmaps --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H +#define LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H + +#include "llvm/Object/StackMapParser.h" + +namespace llvm { + +// Pretty print a stackmap to the given ostream. +template <typename OStreamT, typename StackMapParserT> +void prettyPrintStackMap(OStreamT &OS, const StackMapParserT &SMP) { + + OS << "LLVM StackMap Version: " << SMP.getVersion() + << "\nNum Functions: " << SMP.getNumFunctions(); + + // Functions: + for (const auto &F : SMP.functions()) + OS << "\n Function address: " << F.getFunctionAddress() + << ", stack size: " << F.getStackSize(); + + // Constants: + OS << "\nNum Constants: " << SMP.getNumConstants(); + unsigned ConstantIndex = 0; + for (const auto &C : SMP.constants()) + OS << "\n #" << ++ConstantIndex << ": " << C.getValue(); + + // Records: + OS << "\nNum Records: " << SMP.getNumRecords(); + for (const auto &R : SMP.records()) { + OS << "\n Record ID: " << R.getID() + << ", instruction offset: " << R.getInstructionOffset() + << "\n " << R.getNumLocations() << " locations:"; + + unsigned LocationIndex = 0; + for (const auto &Loc : R.locations()) { + OS << "\n #" << ++LocationIndex << ": "; + switch (Loc.getKind()) { + case StackMapParserT::LocationKind::Register: + OS << "Register R#" << Loc.getDwarfRegNum(); + break; + case StackMapParserT::LocationKind::Direct: + OS << "Direct R#" << Loc.getDwarfRegNum() << " + " + << Loc.getOffset(); + break; + case StackMapParserT::LocationKind::Indirect: + OS << "Indirect [R#" << Loc.getDwarfRegNum() << " + " + << Loc.getOffset() << "]"; + break; + case StackMapParserT::LocationKind::Constant: + OS << "Constant " << Loc.getSmallConstant(); + break; + case StackMapParserT::LocationKind::ConstantIndex: + OS << "ConstantIndex #" << Loc.getConstantIndex() << " (" + << SMP.getConstant(Loc.getConstantIndex()).getValue() << ")"; + break; + } + } + + OS << "\n " << R.getNumLiveOuts() << " live-outs: [ "; + for (const auto &LO : R.liveouts()) + OS << "R#" << LO.getDwarfRegNum() << " (" + << LO.getSizeInBytes() << "-bytes) "; + OS << "]\n"; + } + + OS << "\n"; + +} + +} + +#endif diff --git a/contrib/llvm/tools/llvm-readobj/Win64EHDumper.cpp b/contrib/llvm/tools/llvm-readobj/Win64EHDumper.cpp index b148c5d..5a8af41 100644 --- a/contrib/llvm/tools/llvm-readobj/Win64EHDumper.cpp +++ b/contrib/llvm/tools/llvm-readobj/Win64EHDumper.cpp @@ -118,19 +118,19 @@ static std::string formatSymbol(const Dumper::Context &Ctx, std::string Buffer; raw_string_ostream OS(Buffer); - StringRef Name; SymbolRef Symbol; - if (Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData) || - Symbol.getName(Name)) { - OS << format(" (0x%" PRIX64 ")", Offset); - return OS.str(); + if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) { + if (ErrorOr<StringRef> Name = Symbol.getName()) { + OS << *Name; + if (Displacement > 0) + OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset); + else + OS << format(" (0x%" PRIX64 ")", Offset); + return OS.str(); + } } - OS << Name; - if (Displacement > 0) - OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset); - else - OS << format(" (0x%" PRIX64 ")", Offset); + OS << format(" (0x%" PRIX64 ")", Offset); return OS.str(); } diff --git a/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp b/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp index f960796..c5bccf9 100644 --- a/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/contrib/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -40,7 +40,6 @@ #include <string> #include <system_error> - using namespace llvm; using namespace llvm::object; @@ -91,6 +90,10 @@ namespace opts { cl::desc("Alias for --relocations"), cl::aliasopt(Relocations)); + // -dyn-relocations + cl::opt<bool> DynRelocs("dyn-relocations", + cl::desc("Display the dynamic relocation entries in the file")); + // -symbols, -t cl::opt<bool> Symbols("symbols", cl::desc("Display the symbol table")); @@ -173,6 +176,12 @@ namespace opts { cl::opt<bool> COFFBaseRelocs("coff-basereloc", cl::desc("Display the PE/COFF .reloc section")); + + // -stackmap + cl::opt<bool> + PrintStackMap("stackmap", + cl::desc("Display contents of stackmap section")); + } // namespace opts static int ReturnValue = EXIT_SUCCESS; @@ -190,9 +199,8 @@ bool error(std::error_code EC) { } bool relocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) exit(ReturnValue); - if (error(b.getOffset(b_addr))) exit(ReturnValue); + uint64_t a_addr = a.getOffset(); + uint64_t b_addr = b.getOffset(); return a_addr < b_addr; } @@ -280,6 +288,8 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printSections(); if (opts::Relocations) Dumper->printRelocations(); + if (opts::DynRelocs) + Dumper->printDynamicRelocations(); if (opts::Symbols) Dumper->printSymbols(); if (opts::DynamicSymbols) @@ -311,8 +321,10 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printCOFFDirectives(); if (opts::COFFBaseRelocs) Dumper->printCOFFBaseReloc(); -} + if (opts::PrintStackMap) + Dumper->printStackMap(); +} /// @brief Dumps each object file in \a Arc; static void dumpArchive(const Archive *Arc) { @@ -374,15 +386,11 @@ static void dumpInput(StringRef File) { reportError(File, readobj_error::unrecognized_file_format); } - int main(int argc, const char *argv[]) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; - // Initialize targets. - llvm::InitializeAllTargetInfos(); - // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); |