diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-readobj/COFFDumper.cpp')
-rw-r--r-- | contrib/llvm/tools/llvm-readobj/COFFDumper.cpp | 124 |
1 files changed, 94 insertions, 30 deletions
diff --git a/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp b/contrib/llvm/tools/llvm-readobj/COFFDumper.cpp index 156e39a..cf897d7 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" @@ -47,7 +48,6 @@ public: COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer) : ObjDumper(Writer) , Obj(Obj) { - cacheRelocations(); } void printFileHeaders() override; @@ -60,7 +60,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); @@ -71,7 +71,7 @@ private: void printBaseOfDataField(const pe32_header *Hdr); void printBaseOfDataField(const pe32plus_header *Hdr); - void printCodeViewLineTables(const SectionRef &Section); + void printCodeViewDebugInfo(const SectionRef &Section); void printCodeViewSymbolsSubsection(StringRef Subsection, const SectionRef &Section, @@ -91,6 +91,7 @@ private: typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy; const llvm::object::COFFObjectFile *Obj; + bool RelocCached = false; RelocMapTy RelocMap; StringRef CVFileIndexToStringOffsetTable; StringRef CVStringTable; @@ -118,11 +119,10 @@ std::error_code createCOFFDumper(const object::ObjectFile *Obj, // symbol used for the relocation at the offset. std::error_code COFFDumper::resolveSymbol(const coff_section *Section, uint64_t Offset, SymbolRef &Sym) { + cacheRelocations(); 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,9 +140,11 @@ 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; - return object_error::success; + Name = *NameOrErr; + return std::error_code(); } static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = { @@ -338,6 +340,10 @@ static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, } void COFFDumper::cacheRelocations() { + if (RelocCached) + return; + RelocCached = true; + for (const SectionRef &S : Obj->sections()) { const coff_section *Section = Obj->getCOFFSection(S); @@ -469,7 +475,7 @@ void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) { void COFFDumper::printBaseOfDataField(const pe32plus_header *) {} -void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { +void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) { StringRef Data; if (error(Section.getContents(Data))) return; @@ -477,7 +483,7 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { SmallVector<StringRef, 10> FunctionNames; StringMap<StringRef> FunctionLineTables; - ListScope D(W, "CodeViewLineTables"); + ListScope D(W, "CodeViewDebugInfo"); { // FIXME: Add more offset correctness checks. DataExtractor DE(Data, true, 4); @@ -503,14 +509,17 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { return; } - // Print the raw contents to simplify debugging if anything goes wrong - // afterwards. StringRef Contents = Data.substr(Offset, PayloadSize); - W.printBinaryBlock("Contents", Contents); + if (opts::CodeViewSubsectionBytes) { + // Print the raw contents to simplify debugging if anything goes wrong + // afterwards. + W.printBinaryBlock("Contents", Contents); + } switch (SubSectionType) { case COFF::DEBUG_SYMBOL_SUBSECTION: - printCodeViewSymbolsSubsection(Contents, Section, Offset); + if (opts::SectionSymbols) + printCodeViewSymbolsSubsection(Contents, Section, Offset); break; case COFF::DEBUG_LINE_TABLE_SUBSECTION: { // Holds a PC to file:line table. Some data to parse this subsection is @@ -576,7 +585,11 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { W.printString("FunctionName", Name); DataExtractor DE(FunctionLineTables[Name], true, 4); - uint32_t Offset = 8; // Skip relocations. + uint32_t Offset = 6; // Skip relocations. + uint16_t Flags = DE.getU16(&Offset); + W.printHex("Flags", Flags); + bool HasColumnInformation = + Flags & COFF::DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS; uint32_t FunctionSize = DE.getU32(&Offset); W.printHex("CodeSize", FunctionSize); while (DE.isValidOffset(Offset)) { @@ -584,9 +597,12 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { // in the line table. The filename string is accessed using double // indirection to the string table subsection using the index subsection. uint32_t OffsetInIndex = DE.getU32(&Offset), - SegmentLength = DE.getU32(&Offset), + SegmentLength = DE.getU32(&Offset), FullSegmentSize = DE.getU32(&Offset); - if (FullSegmentSize != 12 + 8 * SegmentLength) { + + if (FullSegmentSize != + 12 + 8 * SegmentLength + + (HasColumnInformation ? 4 * SegmentLength : 0)) { error(object_error::parse_failed); return; } @@ -627,6 +643,15 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { format("+0x%X", PC).snprint(Buffer, 32); W.printNumber(Buffer, LineNumber); } + if (HasColumnInformation) { + for (unsigned J = 0; J != SegmentLength && DE.isValidOffset(Offset); + ++J) { + uint16_t ColStart = DE.getU16(&Offset); + W.printNumber("ColStart", ColStart); + uint16_t ColEnd = DE.getU16(&Offset); + W.printNumber("ColEnd", ColEnd); + } + } } } } @@ -695,10 +720,20 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, InFunctionScope = false; break; } - default: + default: { + if (opts::CodeViewSubsectionBytes) { + ListScope S(W, "Record"); + W.printHex("Size", Size); + W.printHex("Type", Type); + + StringRef Contents = DE.getData().substr(Offset, Size); + W.printBinaryBlock("Contents", Contents); + } + Offset += Size; break; } + } } if (InFunctionScope) @@ -747,8 +782,8 @@ void COFFDumper::printSections() { } } - if (Name == ".debug$S" && opts::CodeViewLineTables) - printCodeViewLineTables(Sec); + if (Name == ".debug$S" && opts::CodeView) + printCodeViewDebugInfo(Sec); if (opts::SectionData && !(Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) { @@ -791,19 +826,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"); @@ -1107,6 +1141,7 @@ static StringRef getBaseRelocTypeName(uint8_t Type) { case COFF::IMAGE_REL_BASED_LOW: return "LOW"; case COFF::IMAGE_REL_BASED_HIGHLOW: return "HIGHLOW"; case COFF::IMAGE_REL_BASED_HIGHADJ: return "HIGHADJ"; + case COFF::IMAGE_REL_BASED_ARM_MOV32T: return "ARM_MOV32(T)"; case COFF::IMAGE_REL_BASED_DIR64: return "DIR64"; default: return "unknown (" + llvm::utostr(Type) + ")"; } @@ -1126,3 +1161,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)); +} |