diff options
Diffstat (limited to 'tools/llvm-readobj/COFFDumper.cpp')
-rw-r--r-- | tools/llvm-readobj/COFFDumper.cpp | 187 |
1 files changed, 80 insertions, 107 deletions
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 3e2626dad118..4c2e39dfa3cc 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -1,9 +1,8 @@ //===-- COFFDumper.cpp - COFF-specific dumper -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -44,13 +43,14 @@ #include "llvm/DebugInfo/CodeView/TypeTableCollection.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/WindowsResource.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/Win64EH.h" #include "llvm/Support/raw_ostream.h" @@ -81,8 +81,6 @@ public: void printFileHeaders() override; void printSectionHeaders() override; void printRelocations() override; - void printSymbols() override; - void printDynamicSymbols() override; void printUnwindInfo() override; void printNeededLibraries() override; @@ -95,12 +93,16 @@ public: void printCOFFResources() override; void printCOFFLoadConfig() override; void printCodeViewDebugInfo() override; - void - mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs, - llvm::codeview::MergingTypeTableBuilder &CVTypes) override; + void mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs, + llvm::codeview::MergingTypeTableBuilder &CVTypes, + llvm::codeview::GlobalTypeTableBuilder &GlobalCVIDs, + llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes, + bool GHash) override; void printStackMap() const override; void printAddrsig() override; private: + void printSymbols() override; + void printDynamicSymbols() override; void printSymbol(const SymbolRef &Sym); void printRelocation(const SectionRef &Section, const RelocationRef &Reloc, uint64_t Bias = 0); @@ -568,29 +570,6 @@ static const EnumEntry<uint8_t> FileChecksumKindNames[] = { LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256), }; -static const EnumEntry<COFF::ResourceTypeID> ResourceTypeNames[]{ - {"kRT_CURSOR (ID 1)", COFF::RID_Cursor}, - {"kRT_BITMAP (ID 2)", COFF::RID_Bitmap}, - {"kRT_ICON (ID 3)", COFF::RID_Icon}, - {"kRT_MENU (ID 4)", COFF::RID_Menu}, - {"kRT_DIALOG (ID 5)", COFF::RID_Dialog}, - {"kRT_STRING (ID 6)", COFF::RID_String}, - {"kRT_FONTDIR (ID 7)", COFF::RID_FontDir}, - {"kRT_FONT (ID 8)", COFF::RID_Font}, - {"kRT_ACCELERATOR (ID 9)", COFF::RID_Accelerator}, - {"kRT_RCDATA (ID 10)", COFF::RID_RCData}, - {"kRT_MESSAGETABLE (ID 11)", COFF::RID_MessageTable}, - {"kRT_GROUP_CURSOR (ID 12)", COFF::RID_Group_Cursor}, - {"kRT_GROUP_ICON (ID 14)", COFF::RID_Group_Icon}, - {"kRT_VERSION (ID 16)", COFF::RID_Version}, - {"kRT_DLGINCLUDE (ID 17)", COFF::RID_DLGInclude}, - {"kRT_PLUGPLAY (ID 19)", COFF::RID_PlugPlay}, - {"kRT_VXD (ID 20)", COFF::RID_VXD}, - {"kRT_ANICURSOR (ID 21)", COFF::RID_AniCursor}, - {"kRT_ANIICON (ID 22)", COFF::RID_AniIcon}, - {"kRT_HTML (ID 23)", COFF::RID_HTML}, - {"kRT_MANIFEST (ID 24)", COFF::RID_Manifest}}; - template <typename T> static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, COFFSymbolRef Symbol, @@ -613,11 +592,14 @@ void COFFDumper::cacheRelocations() { RelocMap[Section].push_back(Reloc); // Sort relocations by address. - llvm::sort(RelocMap[Section], relocAddressLess); + llvm::sort(RelocMap[Section], [](RelocationRef L, RelocationRef R) { + return L.getOffset() < R.getOffset(); + }); } } -void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName) { +void COFFDumper::printDataDirectory(uint32_t Index, + const std::string &FieldName) { const data_directory *Data; if (Obj->getDataDirectory(Index, Data)) return; @@ -951,8 +933,7 @@ void COFFDumper::initializeFileAndStringTables(BinaryStreamReader &Reader) { void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, const SectionRef &Section) { - StringRef SectionContents; - error(Section.getContents(SectionContents)); + StringRef SectionContents = unwrapOrError(Section.getContents()); StringRef Data = SectionContents; SmallVector<StringRef, 10> FunctionNames; @@ -980,6 +961,11 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, error(consume(Data, SubSectionSize)); ListScope S(W, "Subsection"); + // Dump the subsection as normal even if the ignore bit is set. + if (SubType & SubsectionIgnoreFlag) { + W.printHex("IgnoredSubsectionKind", SubType); + SubType &= ~SubsectionIgnoreFlag; + } W.printEnum("SubSectionType", SubType, makeArrayRef(SubSectionTypes)); W.printHex("SubSectionSize", SubSectionSize); @@ -1228,13 +1214,15 @@ void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) { } void COFFDumper::mergeCodeViewTypes(MergingTypeTableBuilder &CVIDs, - MergingTypeTableBuilder &CVTypes) { + MergingTypeTableBuilder &CVTypes, + GlobalTypeTableBuilder &GlobalCVIDs, + GlobalTypeTableBuilder &GlobalCVTypes, + bool GHash) { for (const SectionRef &S : Obj->sections()) { StringRef SectionName; error(S.getName(SectionName)); if (SectionName == ".debug$T") { - StringRef Data; - error(S.getContents(Data)); + StringRef Data = unwrapOrError(S.getContents()); uint32_t Magic; error(consume(Data, Magic)); if (Magic != 4) @@ -1249,9 +1237,18 @@ void COFFDumper::mergeCodeViewTypes(MergingTypeTableBuilder &CVIDs, } SmallVector<TypeIndex, 128> SourceToDest; Optional<uint32_t> PCHSignature; - if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, Types, - PCHSignature)) - return error(std::move(EC)); + if (GHash) { + std::vector<GloballyHashedType> Hashes = + GloballyHashedType::hashTypes(Types); + if (auto EC = + mergeTypeAndIdRecords(GlobalCVIDs, GlobalCVTypes, SourceToDest, + Types, Hashes, PCHSignature)) + return error(std::move(EC)); + } else { + if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, Types, + PCHSignature)) + return error(std::move(EC)); + } } } } @@ -1261,8 +1258,7 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName, ListScope D(W, "CodeViewTypes"); W.printNumber("Section", SectionName, Obj->getSectionID(Section)); - StringRef Data; - error(Section.getContents(Data)); + StringRef Data = unwrapOrError(Section.getContents()); if (opts::CodeViewSubsectionBytes) W.printBinaryBlock("Data", Data); @@ -1322,9 +1318,7 @@ void COFFDumper::printSectionHeaders() { if (opts::SectionData && !(Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) { - StringRef Data; - error(Sec.getContents(Data)); - + StringRef Data = unwrapOrError(Sec.getContents()); W.printBinaryBlock("SectionData", Data); } } @@ -1398,15 +1392,11 @@ void COFFDumper::printSymbols() { void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); } -static ErrorOr<StringRef> +static Expected<StringRef> getSectionName(const llvm::object::COFFObjectFile *Obj, int32_t SectionNumber, const coff_section *Section) { - if (Section) { - StringRef SectionName; - if (std::error_code EC = Obj->getSectionName(Section, SectionName)) - return EC; - return SectionName; - } + if (Section) + return Obj->getSectionName(Section); if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) return StringRef("IMAGE_SYM_DEBUG"); if (SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE) @@ -1431,11 +1421,10 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { if (Obj->getSymbolName(Symbol, SymbolName)) SymbolName = ""; - StringRef SectionName = ""; - ErrorOr<StringRef> Res = - getSectionName(Obj, Symbol.getSectionNumber(), Section); - if (Res) - SectionName = *Res; + StringRef SectionName; + if (Expected<StringRef> NameOrErr = + getSectionName(Obj, Symbol.getSectionNumber(), Section)) + SectionName = *NameOrErr; W.printString("Name", SymbolName); W.printNumber("Value", Symbol.getValue()); @@ -1503,16 +1492,12 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { const coff_section *Assoc; StringRef AssocName = ""; - std::error_code EC = Obj->getSection(AuxNumber, Assoc); - ErrorOr<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc); - if (Res) - AssocName = *Res; - if (!EC) - EC = Res.getError(); - if (EC) { - AssocName = ""; + if (std::error_code EC = Obj->getSection(AuxNumber, Assoc)) error(EC); - } + Expected<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc); + if (!Res) + error(Res.takeError()); + AssocName = *Res; W.printNumber("AssocSection", AssocName, AuxNumber); } @@ -1559,7 +1544,8 @@ void COFFDumper::printUnwindInfo() { case COFF::IMAGE_FILE_MACHINE_ARMNT: { ARM::WinEH::Decoder Decoder(W, Obj->getMachine() == COFF::IMAGE_FILE_MACHINE_ARM64); - Decoder.dumpProcedureData(*Obj); + // TODO Propagate the error. + consumeError(Decoder.dumpProcedureData(*Obj)); break; } default: @@ -1581,10 +1567,10 @@ void COFFDumper::printNeededLibraries() { Libs.push_back(Name); } - std::stable_sort(Libs.begin(), Libs.end()); + llvm::stable_sort(Libs); for (const auto &L : Libs) { - outs() << " " << L << "\n"; + W.startLine() << L << "\n"; } } @@ -1674,15 +1660,13 @@ void COFFDumper::printCOFFExports() { void COFFDumper::printCOFFDirectives() { for (const SectionRef &Section : Obj->sections()) { - StringRef Contents; StringRef Name; error(Section.getName(Name)); if (Name != ".drectve") continue; - error(Section.getContents(Contents)); - + StringRef Contents = unwrapOrError(Section.getContents()); W.printString("Directive(s)", Contents); } } @@ -1721,8 +1705,7 @@ void COFFDumper::printCOFFResources() { if (!Name.startswith(".rsrc")) continue; - StringRef Ref; - error(S.getContents(Ref)); + StringRef Ref = unwrapOrError(S.getContents()); if ((Name == ".rsrc") || (Name == ".rsrc$01")) { ResourceSectionRef RSF(Ref); @@ -1777,7 +1760,8 @@ void COFFDumper::printResourceDirectoryTable( SmallString<20> IDStr; raw_svector_ostream OS(IDStr); if (i < Table.NumberOfNameEntries) { - ArrayRef<UTF16> RawEntryNameString = unwrapOrError(RSF.getEntryNameString(Entry)); + ArrayRef<UTF16> RawEntryNameString = + unwrapOrError(RSF.getEntryNameString(Entry)); std::vector<UTF16> EndianCorrectedNameString; if (llvm::sys::IsBigEndianHost) { EndianCorrectedNameString.resize(RawEntryNameString.size() + 1); @@ -1793,9 +1777,8 @@ void COFFDumper::printResourceDirectoryTable( OS << EntryNameString; } else { if (Level == "Type") { - ScopedPrinter Printer(OS); - Printer.printEnum("", Entry.Identifier.ID, - makeArrayRef(ResourceTypeNames)); + OS << ": "; + printResourceTypeName(Entry.Identifier.ID, OS); IDStr = IDStr.slice(0, IDStr.find_first_of(")", 0) + 1); } else { OS << ": (ID " << Entry.Identifier.ID << ")"; @@ -1848,18 +1831,16 @@ void COFFDumper::printStackMap() const { if (StackMapSection == object::SectionRef()) return; - StringRef StackMapContents; - StackMapSection.getContents(StackMapContents); - ArrayRef<uint8_t> StackMapContentsArray( - reinterpret_cast<const uint8_t*>(StackMapContents.data()), - StackMapContents.size()); + StringRef StackMapContents = unwrapOrError(StackMapSection.getContents()); + ArrayRef<uint8_t> StackMapContentsArray = + arrayRefFromStringRef(StackMapContents); if (Obj->isLittleEndian()) prettyPrintStackMap( - W, StackMapV2Parser<support::little>(StackMapContentsArray)); + W, StackMapParser<support::little>(StackMapContentsArray)); else - prettyPrintStackMap(W, - StackMapV2Parser<support::big>(StackMapContentsArray)); + prettyPrintStackMap( + W, StackMapParser<support::big>(StackMapContentsArray)); } void COFFDumper::printAddrsig() { @@ -1876,15 +1857,13 @@ void COFFDumper::printAddrsig() { if (AddrsigSection == object::SectionRef()) return; - StringRef AddrsigContents; - AddrsigSection.getContents(AddrsigContents); - ArrayRef<uint8_t> AddrsigContentsArray( - reinterpret_cast<const uint8_t*>(AddrsigContents.data()), - AddrsigContents.size()); + StringRef AddrsigContents = unwrapOrError(AddrsigSection.getContents()); + ArrayRef<uint8_t> AddrsigContentsArray(AddrsigContents.bytes_begin(), + AddrsigContents.size()); ListScope L(W, "Addrsig"); - auto *Cur = reinterpret_cast<const uint8_t *>(AddrsigContents.begin()); - auto *End = reinterpret_cast<const uint8_t *>(AddrsigContents.end()); + const uint8_t *Cur = AddrsigContents.bytes_begin(); + const uint8_t *End = AddrsigContents.bytes_end(); while (Cur != End) { unsigned Size; const char *Err; @@ -1905,16 +1884,10 @@ void COFFDumper::printAddrsig() { } } -void llvm::dumpCodeViewMergedTypes( - ScopedPrinter &Writer, llvm::codeview::MergingTypeTableBuilder &IDTable, - llvm::codeview::MergingTypeTableBuilder &CVTypes) { - // Flatten it first, then run our dumper on it. - SmallString<0> TypeBuf; - CVTypes.ForEachRecord([&](TypeIndex TI, const CVType &Record) { - TypeBuf.append(Record.RecordData.begin(), Record.RecordData.end()); - }); - - TypeTableCollection TpiTypes(CVTypes.records()); +void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer, + ArrayRef<ArrayRef<uint8_t>> IpiRecords, + ArrayRef<ArrayRef<uint8_t>> TpiRecords) { + TypeTableCollection TpiTypes(TpiRecords); { ListScope S(Writer, "MergedTypeStream"); TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes); @@ -1924,7 +1897,7 @@ void llvm::dumpCodeViewMergedTypes( // Flatten the id stream and print it next. The ID stream refers to names from // the type stream. - TypeTableCollection IpiTypes(IDTable.records()); + TypeTableCollection IpiTypes(IpiRecords); { ListScope S(Writer, "MergedIDStream"); TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes); |