diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:13 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:13 +0000 |
commit | a303c417bbdb53703c2c17398b08486bde78f1f6 (patch) | |
tree | 98366d6b93d863cefdc53f16c66c0c5ae7fb2261 /tools/llvm-readobj | |
parent | 12f3ca4cdb95b193af905a00e722a4dcb40b3de3 (diff) |
Notes
Diffstat (limited to 'tools/llvm-readobj')
-rw-r--r-- | tools/llvm-readobj/COFFDumper.cpp | 204 | ||||
-rw-r--r-- | tools/llvm-readobj/ELFDumper.cpp | 58 | ||||
-rw-r--r-- | tools/llvm-readobj/ObjDumper.h | 1 | ||||
-rw-r--r-- | tools/llvm-readobj/WasmDumper.cpp | 33 | ||||
-rw-r--r-- | tools/llvm-readobj/llvm-readobj.cpp | 6 |
5 files changed, 137 insertions, 165 deletions
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 9836c137ed2ca..a7088c1c7419a 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -25,6 +25,9 @@ #include "llvm/DebugInfo/CodeView/CVTypeDumper.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" @@ -38,11 +41,12 @@ #include "llvm/Object/COFF.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Format.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/SourceMgr.h" @@ -78,6 +82,7 @@ public: void printCOFFDirectives() override; void printCOFFBaseReloc() override; void printCOFFDebugDirectory() override; + void printCOFFResources() override; void printCodeViewDebugInfo() override; void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs, llvm::codeview::TypeTableBuilder &CVTypes) override; @@ -496,19 +501,19 @@ WeakExternalCharacteristics[] = { }; static const EnumEntry<uint32_t> SubSectionTypes[] = { - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Symbols), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Lines), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, StringTable), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FileChecksums), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FrameData), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, InlineeLines), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeImports), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeExports), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, ILLines), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FuncMDTokenMap), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, TypeMDTokenMap), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, MergedAssemblyInput), - LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CoffSymbolRVA), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, Symbols), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, Lines), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, StringTable), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FileChecksums), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FrameData), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, InlineeLines), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CrossScopeImports), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CrossScopeExports), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, ILLines), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, FuncMDTokenMap), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, TypeMDTokenMap), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, MergedAssemblyInput), + LLVM_READOBJ_ENUM_CLASS_ENT(ModuleDebugFragmentKind, CoffSymbolRVA), }; static const EnumEntry<uint32_t> FrameDataFlags[] = { @@ -730,11 +735,11 @@ void COFFDumper::initializeFileAndStringTables(StringRef Data) { error(consume(Data, SubSectionSize)); if (SubSectionSize > Data.size()) return error(object_error::parse_failed); - switch (ModuleSubstreamKind(SubType)) { - case ModuleSubstreamKind::FileChecksums: + switch (ModuleDebugFragmentKind(SubType)) { + case ModuleDebugFragmentKind::FileChecksums: CVFileChecksumTable = Data.substr(0, SubSectionSize); break; - case ModuleSubstreamKind::StringTable: + case ModuleDebugFragmentKind::StringTable: CVStringTable = Data.substr(0, SubSectionSize); break; default: @@ -800,20 +805,20 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, printBinaryBlockWithRelocs("SubSectionContents", Section, SectionContents, Contents); - switch (ModuleSubstreamKind(SubType)) { - case ModuleSubstreamKind::Symbols: + switch (ModuleDebugFragmentKind(SubType)) { + case ModuleDebugFragmentKind::Symbols: printCodeViewSymbolsSubsection(Contents, Section, SectionContents); break; - case ModuleSubstreamKind::InlineeLines: + case ModuleDebugFragmentKind::InlineeLines: printCodeViewInlineeLines(Contents); break; - case ModuleSubstreamKind::FileChecksums: + case ModuleDebugFragmentKind::FileChecksums: printCodeViewFileChecksums(Contents); break; - case ModuleSubstreamKind::Lines: { + case ModuleDebugFragmentKind::Lines: { // Holds a PC to file:line table. Some data to parse this subsection is // stored in the other subsections, so just check sanity and store the // pointers for deferred processing. @@ -839,7 +844,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, FunctionNames.push_back(LinkageName); break; } - case ModuleSubstreamKind::FrameData: { + case ModuleDebugFragmentKind::FrameData: { // First four bytes is a relocation against the function. BinaryByteStream S(Contents, llvm::support::little); BinaryStreamReader SR(S); @@ -890,45 +895,29 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, ListScope S(W, "FunctionLineTable"); W.printString("LinkageName", Name); - DataExtractor DE(FunctionLineTables[Name], true, 4); - uint32_t Offset = 6; // Skip relocations. - uint16_t Flags = DE.getU16(&Offset); - W.printHex("Flags", Flags); - bool HasColumnInformation = Flags & codeview::LineFlags::HaveColumns; - uint32_t FunctionSize = DE.getU32(&Offset); - W.printHex("CodeSize", FunctionSize); - while (DE.isValidOffset(Offset)) { - // For each range of lines with the same filename, we have a segment - // 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), - NumLines = DE.getU32(&Offset), - FullSegmentSize = DE.getU32(&Offset); - - uint32_t ColumnOffset = Offset + 8 * NumLines; - DataExtractor ColumnDE(DE.getData(), true, 4); - - if (FullSegmentSize != - 12 + 8 * NumLines + (HasColumnInformation ? 4 * NumLines : 0)) { - error(object_error::parse_failed); - return; - } + BinaryByteStream LineTableInfo(FunctionLineTables[Name], support::little); + BinaryStreamReader Reader(LineTableInfo); + + ModuleDebugLineFragmentRef LineInfo; + error(LineInfo.initialize(Reader)); + + W.printHex("Flags", LineInfo.header()->Flags); + W.printHex("CodeSize", LineInfo.header()->CodeSize); + for (const auto &Entry : LineInfo) { ListScope S(W, "FilenameSegment"); - printFileNameForOffset("Filename", OffsetInIndex); - for (unsigned LineIdx = 0; - LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) { - // Then go the (PC, LineNumber) pairs. The line number is stored in the - // least significant 31 bits of the respective word in the table. - uint32_t PC = DE.getU32(&Offset), LineData = DE.getU32(&Offset); - if (PC >= FunctionSize) { + printFileNameForOffset("Filename", Entry.NameIndex); + uint32_t ColumnIndex = 0; + for (const auto &Line : Entry.LineNumbers) { + if (Line.Offset >= LineInfo.header()->CodeSize) { error(object_error::parse_failed); return; } - char Buffer[32]; - format("+0x%X", PC).snprint(Buffer, 32); - ListScope PCScope(W, Buffer); - LineInfo LI(LineData); + + std::string PC = formatv("+{0:X}", uint32_t(Line.Offset)); + ListScope PCScope(W, PC); + codeview::LineInfo LI(Line.Flags); + if (LI.isAlwaysStepInto()) W.printString("StepInto", StringRef("Always")); else if (LI.isNeverStepInto()) @@ -937,19 +926,10 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, W.printNumber("LineNumberStart", LI.getStartLine()); W.printNumber("LineNumberEndDelta", LI.getLineDelta()); W.printBoolean("IsStatement", LI.isStatement()); - if (HasColumnInformation && - ColumnDE.isValidOffsetForDataOfSize(ColumnOffset, 4)) { - uint16_t ColStart = ColumnDE.getU16(&ColumnOffset); - W.printNumber("ColStart", ColStart); - uint16_t ColEnd = ColumnDE.getU16(&ColumnOffset); - W.printNumber("ColEnd", ColEnd); - } - } - // Skip over the column data. - if (HasColumnInformation) { - for (unsigned LineIdx = 0; - LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) { - DE.getU32(&Offset); + if (LineInfo.hasColumnInfo()) { + W.printNumber("ColStart", Entry.Columns[ColumnIndex].StartColumn); + W.printNumber("ColEnd", Entry.Columns[ColumnIndex].EndColumn); + ++ColumnIndex; } } } @@ -985,56 +965,42 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { BinaryByteStream S(Subsection, llvm::support::little); BinaryStreamReader SR(S); - while (!SR.empty()) { + ModuleDebugFileChecksumFragmentRef Checksums; + error(Checksums.initialize(SR)); + + for (auto &FC : Checksums) { DictScope S(W, "FileChecksum"); - const FileChecksum *FC; - error(SR.readObject(FC)); - if (FC->FileNameOffset >= CVStringTable.size()) + + if (FC.FileNameOffset >= CVStringTable.size()) error(object_error::parse_failed); StringRef Filename = - CVStringTable.drop_front(FC->FileNameOffset).split('\0').first; - W.printHex("Filename", Filename, FC->FileNameOffset); - W.printHex("ChecksumSize", FC->ChecksumSize); - W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind), + CVStringTable.drop_front(FC.FileNameOffset).split('\0').first; + W.printHex("Filename", Filename, FC.FileNameOffset); + W.printHex("ChecksumSize", FC.Checksum.size()); + W.printEnum("ChecksumKind", uint8_t(FC.Kind), makeArrayRef(FileChecksumKindNames)); - if (FC->ChecksumSize >= SR.bytesRemaining()) - error(object_error::parse_failed); - ArrayRef<uint8_t> ChecksumBytes; - error(SR.readBytes(ChecksumBytes, FC->ChecksumSize)); - W.printBinary("ChecksumBytes", ChecksumBytes); - unsigned PaddedSize = alignTo(FC->ChecksumSize + sizeof(FileChecksum), 4) - - sizeof(FileChecksum); - PaddedSize -= ChecksumBytes.size(); - if (PaddedSize > SR.bytesRemaining()) - error(object_error::parse_failed); - error(SR.skip(PaddedSize)); + + W.printBinary("ChecksumBytes", FC.Checksum); } } void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) { BinaryByteStream S(Subsection, llvm::support::little); BinaryStreamReader SR(S); - uint32_t Signature; - error(SR.readInteger(Signature)); - bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles); + ModuleDebugInlineeLineFragmentRef Lines; + error(Lines.initialize(SR)); - while (!SR.empty()) { - const InlineeSourceLine *ISL; - error(SR.readObject(ISL)); + for (auto &Line : Lines) { DictScope S(W, "InlineeSourceLine"); - printTypeIndex("Inlinee", ISL->Inlinee); - printFileNameForOffset("FileID", ISL->FileID); - W.printNumber("SourceLineNum", ISL->SourceLineNum); - - if (HasExtraFiles) { - uint32_t ExtraFileCount; - error(SR.readInteger(ExtraFileCount)); - W.printNumber("ExtraFileCount", ExtraFileCount); + printTypeIndex("Inlinee", Line.Header->Inlinee); + printFileNameForOffset("FileID", Line.Header->FileID); + W.printNumber("SourceLineNum", Line.Header->SourceLineNum); + + if (Lines.hasExtraFiles()) { + W.printNumber("ExtraFileCount", Line.ExtraFiles.size()); ListScope ExtraFiles(W, "ExtraFiles"); - for (unsigned I = 0; I < ExtraFileCount; ++I) { - uint32_t FileID; - error(SR.readInteger(FileID)); - printFileNameForOffset("FileID", FileID); + for (const auto &FID : Line.ExtraFiles) { + printFileNameForOffset("FileID", FID); } } } @@ -1527,6 +1493,30 @@ void COFFDumper::printCOFFBaseReloc() { } } +void COFFDumper::printCOFFResources() { + ListScope ResourcesD(W, "Resources"); + for (const SectionRef &S : Obj->sections()) { + StringRef Name; + error(S.getName(Name)); + if (!Name.startswith(".rsrc")) + continue; + + StringRef Ref; + error(S.getContents(Ref)); + + if ((Name == ".rsrc") || (Name == ".rsrc$01")) { + auto Table = + reinterpret_cast<const coff_resource_dir_table *>(Ref.data()); + char FormattedTime[20]; + time_t TDS = time_t(Table->TimeDateStamp); + strftime(FormattedTime, sizeof(FormattedTime), "%Y-%m-%d %H:%M:%S", + gmtime(&TDS)); + W.printHex("Time/Date Stamp", FormattedTime, Table->TimeDateStamp); + } + W.printBinaryBlock(Name.str() + " Data", Ref); + } +} + void COFFDumper::printStackMap() const { object::SectionRef StackMapSection; for (auto Sec : Obj->sections()) { diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 7893eea5d2209..2e9e01d9642b1 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -983,57 +983,6 @@ static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = { { "AMDGPU_HSA_METADATA", ELF::STT_AMDGPU_HSA_METADATA } }; -static const char *getElfSectionType(unsigned Arch, unsigned Type) { - switch (Arch) { - case ELF::EM_ARM: - switch (Type) { - LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); - } - case ELF::EM_HEXAGON: - switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); } - case ELF::EM_X86_64: - switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } - case ELF::EM_MIPS: - case ELF::EM_MIPS_RS3_LE: - switch (Type) { - LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_DWARF); - } - } - - switch (Type) { - LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed ); - LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym ); - default: return ""; - } -} - static const char *getGroupType(uint32_t Flag) { if (Flag & ELF::GRP_COMDAT) return "COMDAT"; @@ -3635,9 +3584,10 @@ template <class ELFT> void LLVMStyle<ELFT>::printSections(const ELFO *Obj) { DictScope SectionD(W, "Section"); W.printNumber("Index", SectionIndex); W.printNumber("Name", Name, Sec.sh_name); - W.printHex("Type", - getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type), - Sec.sh_type); + W.printHex( + "Type", + object::getELFSectionTypeName(Obj->getHeader()->e_machine, Sec.sh_type), + Sec.sh_type); std::vector<EnumEntry<unsigned>> SectionFlags(std::begin(ElfSectionFlags), std::end(ElfSectionFlags)); switch (Obj->getHeader()->e_machine) { diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index ff780dae57843..48f825c527c16 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -67,6 +67,7 @@ public: virtual void printCOFFDirectives() { } virtual void printCOFFBaseReloc() { } virtual void printCOFFDebugDirectory() { } + virtual void printCOFFResources() {} virtual void printCodeViewDebugInfo() { } virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs, llvm::codeview::TypeTableBuilder &CVTypes) {} diff --git a/tools/llvm-readobj/WasmDumper.cpp b/tools/llvm-readobj/WasmDumper.cpp index e27da3b96e5d5..21614297e4671 100644 --- a/tools/llvm-readobj/WasmDumper.cpp +++ b/tools/llvm-readobj/WasmDumper.cpp @@ -81,17 +81,30 @@ void WasmDumper::printRelocation(const SectionRef &Section, Reloc.getTypeName(RelocTypeName); const wasm::WasmRelocation &WasmReloc = Obj->getWasmRelocation(Reloc); + bool HasAddend = false; + switch (RelocType) { + case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB: + case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB: + case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32: + HasAddend = true; + break; + default: + break; + } if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); W.printNumber("Type", RelocTypeName, RelocType); W.printHex("Offset", Reloc.getOffset()); W.printHex("Index", WasmReloc.Index); - W.printHex("Addend", WasmReloc.Addend); + if (HasAddend) + W.printNumber("Addend", WasmReloc.Addend); } else { raw_ostream& OS = W.startLine(); OS << W.hex(Reloc.getOffset()) - << " " << RelocTypeName << "[" << WasmReloc.Index << "]" - << " " << W.hex(WasmReloc.Addend) << "\n"; + << " " << RelocTypeName << "[" << WasmReloc.Index << "]"; + if (HasAddend) + OS << " " << WasmReloc.Addend; + OS << "\n"; } } @@ -137,8 +150,20 @@ void WasmDumper::printSections() { W.printEnum("Type", WasmSec.Type, makeArrayRef(WasmSectionTypes)); W.printNumber("Size", (uint64_t)WasmSec.Content.size()); W.printNumber("Offset", WasmSec.Offset); - if (WasmSec.Type == wasm::WASM_SEC_CUSTOM) { + switch (WasmSec.Type) { + case wasm::WASM_SEC_CUSTOM: W.printString("Name", WasmSec.Name); + break; + case wasm::WASM_SEC_MEMORY: + ListScope Group(W, "Memories"); + for (const wasm::WasmLimits &Memory : Obj->memories()) { + DictScope Group(W, "Memory"); + W.printNumber("InitialPages", Memory.Initial); + if (Memory.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) { + W.printNumber("MaxPages", WasmSec.Offset); + } + } + break; } if (opts::SectionRelocations) { diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index bc2a62e799ab0..8a9d7bc720c3f 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -214,6 +214,10 @@ namespace opts { COFFDebugDirectory("coff-debug-directory", cl::desc("Display the PE/COFF debug directory")); + // -coff-resources + cl::opt<bool> COFFResources("coff-resources", + cl::desc("Display the PE/COFF .rsrc section")); + // -macho-data-in-code cl::opt<bool> MachODataInCode("macho-data-in-code", @@ -445,6 +449,8 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printCOFFBaseReloc(); if (opts::COFFDebugDirectory) Dumper->printCOFFDebugDirectory(); + if (opts::COFFResources) + Dumper->printCOFFResources(); if (opts::CodeView) Dumper->printCodeViewDebugInfo(); if (opts::CodeViewMergedTypes) |