Index: include/llvm/DebugInfo/PDB/Raw/DbiStream.h =================================================================== --- include/llvm/DebugInfo/PDB/Raw/DbiStream.h +++ include/llvm/DebugInfo/PDB/Raw/DbiStream.h @@ -22,6 +22,10 @@ #include "llvm/Support/Error.h" namespace llvm { +namespace object { +struct coff_section; +} + namespace pdb { class PDBFile; class ISectionContribVisitor; @@ -56,11 +60,14 @@ ArrayRef modules() const; + codeview::FixedStreamArray getSectionHeaders(); + codeview::FixedStreamArray getSectionMap() const; void visitSectionContributions(ISectionContribVisitor &Visitor) const; private: Error initializeSectionContributionData(); + Error initializeSectionHeadersData(); Error initializeSectionMapData(); Error initializeFileInfo(); @@ -84,6 +91,9 @@ codeview::FixedStreamArray SectionContribs2; codeview::FixedStreamArray SectionMap; + std::unique_ptr SectionHeaderStream; + codeview::FixedStreamArray SectionHeaders; + const HeaderInfo *Header; }; } Index: lib/DebugInfo/PDB/Raw/DbiStream.cpp =================================================================== --- lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -6,6 +6,7 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + #include "llvm/DebugInfo/PDB/Raw/DbiStream.h" #include "llvm/DebugInfo/CodeView/StreamArray.h" @@ -18,6 +19,7 @@ #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" #include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/Object/COFF.h" using namespace llvm; using namespace llvm::codeview; @@ -180,7 +182,8 @@ if (auto EC = initializeSectionContributionData()) return EC; - + if (auto EC = initializeSectionHeadersData()) + return EC; if (auto EC = initializeSectionMapData()) return EC; @@ -244,6 +247,11 @@ return static_cast(Machine); } +codeview::FixedStreamArray +DbiStream::getSectionHeaders() { + return SectionHeaders; +} + ArrayRef DbiStream::modules() const { return ModuleInfos; } codeview::FixedStreamArray DbiStream::getSectionMap() const { return SectionMap; @@ -274,6 +282,24 @@ "Unsupported DBI Section Contribution version"); } +// Initializes this->SectionHeaders. +Error DbiStream::initializeSectionHeadersData() { + uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr); + SectionHeaderStream.reset(new MappedBlockStream(StreamNum, Pdb)); + + size_t StreamLen = SectionHeaderStream->getLength(); + if (StreamLen % sizeof(object::coff_section)) + return make_error(raw_error_code::corrupt_file, + "Corrupted section header stream."); + + size_t NumSections = StreamLen / sizeof(object::coff_section); + codeview::StreamReader Reader(*SectionHeaderStream); + if (auto EC = Reader.readArray(SectionHeaders, NumSections)) + return make_error(raw_error_code::corrupt_file, + "Could not read a bitmap."); + return Error::success(); +} + Error DbiStream::initializeSectionMapData() { StreamReader SMReader(SecMapSubstream); const SecMapHeader *Header; Index: test/DebugInfo/PDB/pdbdump-headers.test =================================================================== --- test/DebugInfo/PDB/pdbdump-headers.test +++ test/DebugInfo/PDB/pdbdump-headers.test @@ -1,7 +1,7 @@ ; RUN: llvm-pdbdump -raw-headers -raw-tpi-records -raw-tpi-record-bytes -raw-module-syms \ ; RUN: -raw-sym-record-bytes -raw-publics -raw-module-files -raw-stream-name=/names \ ; RUN: -raw-stream-summary -raw-stream-blocks -raw-ipi-records -raw-ipi-record-bytes \ -; RUN: -raw-section-contribs -raw-section-map %p/Inputs/empty.pdb \ +; RUN: -raw-section-contribs -raw-section-map -raw-section-headers %p/Inputs/empty.pdb \ ; RUN: | FileCheck -check-prefix=EMPTY %s ; RUN: llvm-pdbdump -raw-all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s ; RUN: llvm-pdbdump -raw-headers -raw-stream-name=/names -raw-modules -raw-module-files \ @@ -804,6 +804,56 @@ ; EMPTY-NEXT: } ; EMPTY-NEXT: ] ; EMPTY-NEXT: } +; EMPTY-NEXT: Section Headers [ +; EMPTY-NEXT: { +; EMPTY-NEXT: Name: .text +; EMPTY-NEXT: Virtual Size: 4122 +; EMPTY-NEXT: Virtual Address: 4096 +; EMPTY-NEXT: Size of Raw Data: 4608 +; EMPTY-NEXT: File Pointer to Raw Data: 1024 +; EMPTY-NEXT: File Pointer to Relocations: 0 +; EMPTY-NEXT: File Pointer to Linenumbers: 0 +; EMPTY-NEXT: Number of Relocations: 0 +; EMPTY-NEXT: Number of Linenumbers: 0 +; EMPTY-NEXT: Characteristics: 1610612768 +; EMPTY-NEXT: } +; EMPTY-NEXT: { +; EMPTY-NEXT: Name: .rdata +; EMPTY-NEXT: Virtual Size: 690 +; EMPTY-NEXT: Virtual Address: 12288 +; EMPTY-NEXT: Size of Raw Data: 1024 +; EMPTY-NEXT: File Pointer to Raw Data: 5632 +; EMPTY-NEXT: File Pointer to Relocations: 0 +; EMPTY-NEXT: File Pointer to Linenumbers: 0 +; EMPTY-NEXT: Number of Relocations: 0 +; EMPTY-NEXT: Number of Linenumbers: 0 +; EMPTY-NEXT: Characteristics: 1073741888 +; EMPTY-NEXT: } +; EMPTY-NEXT: { +; EMPTY-NEXT: Name: .data +; EMPTY-NEXT: Virtual Size: 4 +; EMPTY-NEXT: Virtual Address: 16384 +; EMPTY-NEXT: Size of Raw Data: 0 +; EMPTY-NEXT: File Pointer to Raw Data: 0 +; EMPTY-NEXT: File Pointer to Relocations: 0 +; EMPTY-NEXT: File Pointer to Linenumbers: 0 +; EMPTY-NEXT: Number of Relocations: 0 +; EMPTY-NEXT: Number of Linenumbers: 0 +; EMPTY-NEXT: Characteristics: 3221225536 +; EMPTY-NEXT: } +; EMPTY-NEXT: { +; EMPTY-NEXT: Name: .reloc +; EMPTY-NEXT: Virtual Size: 8 +; EMPTY-NEXT: Virtual Address: 20480 +; EMPTY-NEXT: Size of Raw Data: 512 +; EMPTY-NEXT: File Pointer to Raw Data: 6656 +; EMPTY-NEXT: File Pointer to Relocations: 0 +; EMPTY-NEXT: File Pointer to Linenumbers: 0 +; EMPTY-NEXT: Number of Relocations: 0 +; EMPTY-NEXT: Number of Linenumbers: 0 +; EMPTY-NEXT: Characteristics: 1107296320 +; EMPTY-NEXT: } +; EMPTY-NEXT: ] ; ALL: FileHeaders { ; ALL: BlockSize: 4096 @@ -1085,7 +1135,7 @@ ; ALL: { ; ALL: Name: * Linker * ; ALL: Debug Stream Index: 14 -; ALL: Object File Name: +; ALL: Object File Name: ; ALL: Num Files: 0 ; ALL: Source File Name Idx: 0 ; ALL: Pdb File Name Idx: 1 @@ -1455,6 +1505,56 @@ ; ALL: } ; ALL: ] ; ALL: } +; ALL: Section Headers [ +; ALL: { +; ALL: Name: .text +; ALL: Virtual Size: 4122 +; ALL: Virtual Address: 4096 +; ALL: Size of Raw Data: 4608 +; ALL: File Pointer to Raw Data: 1024 +; ALL: File Pointer to Relocations: 0 +; ALL: File Pointer to Linenumbers: 0 +; ALL: Number of Relocations: 0 +; ALL: Number of Linenumbers: 0 +; ALL: Characteristics: 1610612768 +; ALL: } +; ALL: { +; ALL: Name: .rdata +; ALL: Virtual Size: 690 +; ALL: Virtual Address: 12288 +; ALL: Size of Raw Data: 1024 +; ALL: File Pointer to Raw Data: 5632 +; ALL: File Pointer to Relocations: 0 +; ALL: File Pointer to Linenumbers: 0 +; ALL: Number of Relocations: 0 +; ALL: Number of Linenumbers: 0 +; ALL: Characteristics: 1073741888 +; ALL: } +; ALL: { +; ALL: Name: .data +; ALL: Virtual Size: 4 +; ALL: Virtual Address: 16384 +; ALL: Size of Raw Data: 0 +; ALL: File Pointer to Raw Data: 0 +; ALL: File Pointer to Relocations: 0 +; ALL: File Pointer to Linenumbers: 0 +; ALL: Number of Relocations: 0 +; ALL: Number of Linenumbers: 0 +; ALL: Characteristics: 3221225536 +; ALL: } +; ALL: { +; ALL: Name: .reloc +; ALL: Virtual Size: 8 +; ALL: Virtual Address: 20480 +; ALL: Size of Raw Data: 512 +; ALL: File Pointer to Raw Data: 6656 +; ALL: File Pointer to Relocations: 0 +; ALL: File Pointer to Linenumbers: 0 +; ALL: Number of Relocations: 0 +; ALL: Number of Linenumbers: 0 +; ALL: Characteristics: 1107296320 +; ALL: } +; ALL: ] ; BIG: FileHeaders { ; BIG-NEXT: BlockSize: 4096 Index: tools/llvm-pdbdump/llvm-pdbdump.cpp =================================================================== --- tools/llvm-pdbdump/llvm-pdbdump.cpp +++ tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -53,6 +53,7 @@ #include "llvm/DebugInfo/PDB/Raw/RawError.h" #include "llvm/DebugInfo/PDB/Raw/RawSession.h" #include "llvm/DebugInfo/PDB/Raw/TpiStream.h" +#include "llvm/Object/COFF.h" #include "llvm/Support/COM.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" @@ -149,6 +150,10 @@ DumpSymRecordBytes("raw-sym-record-bytes", cl::desc("dump CodeView symbol record raw bytes"), cl::cat(NativeOptions)); +cl::opt DumpSectionHeaders("raw-section-headers", + cl::desc("dump section headers"), + cl::cat(NativeOptions)); + cl::opt RawAll("raw-all", cl::desc("Implies most other options in 'Native Options' category"), @@ -691,6 +696,36 @@ return Error::success(); } +static Error dumpSectionHeaders(ScopedPrinter &P, PDBFile &File, + codeview::CVTypeDumper &TD) { + if (!opts::DumpSectionHeaders) + return Error::success(); + + auto DbiS = File.getPDBDbiStream(); + if (auto EC = DbiS.takeError()) + return EC; + DbiStream &DS = DbiS.get(); + + ListScope D(P, "Section Headers"); + for (const object::coff_section &Section : DS.getSectionHeaders()) { + DictScope DD(P, ""); + + // If a name is 8 characters long, there is no NUL character at end. + StringRef Name(Section.Name, strnlen(Section.Name, sizeof(Section.Name))); + P.printString("Name", Name); + P.printNumber("Virtual Size", Section.VirtualSize); + P.printNumber("Virtual Address", Section.VirtualAddress); + P.printNumber("Size of Raw Data", Section.SizeOfRawData); + P.printNumber("File Pointer to Raw Data", Section.PointerToRawData); + P.printNumber("File Pointer to Relocations", Section.PointerToRelocations); + P.printNumber("File Pointer to Linenumbers", Section.PointerToLinenumbers); + P.printNumber("Number of Relocations", Section.NumberOfRelocations); + P.printNumber("Number of Linenumbers", Section.NumberOfLinenumbers); + P.printNumber("Characteristics", Section.Characteristics); + } + return Error::success(); +} + static Error dumpStructure(RawSession &RS) { PDBFile &File = RS.getPDBFile(); ScopedPrinter P(outs()); @@ -716,6 +751,7 @@ codeview::CVTypeDumper TD(&P, false); if (auto EC = dumpTpiStream(P, File, TD, StreamTPI)) return EC; + if (auto EC = dumpTpiStream(P, File, TD, StreamIPI)) return EC; @@ -731,6 +767,8 @@ if (auto EC = dumpPublicsStream(P, File, TD)) return EC; + if (auto EC = dumpSectionHeaders(P, File, TD)) + return EC; return Error::success(); } @@ -927,6 +965,7 @@ opts::DumpModuleFiles = true; opts::DumpModuleSyms = true; opts::DumpPublics = true; + opts::DumpSectionHeaders = true; opts::DumpStreamSummary = true; opts::DumpStreamBlocks = true; opts::DumpTpiRecords = true;