Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions llvm/test/tools/llvm-pdbutil/dbi-section-headers.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# RUN: llvm-pdbutil yaml2pdb %s --pdb=%t.pdb
# RUN: llvm-pdbutil dump --section-headers --section-map %t.pdb | FileCheck --check-prefix=CHECK-YAML2PDB %s

# RUN: llvm-pdbutil pdb2yaml --section-headers %t.pdb > %t.yaml
# RUN: FileCheck --input-file=%t.yaml --check-prefix=CHECK-PDB2YAML %s

# CHECK-YAML2PDB: Section Headers
# CHECK-YAML2PDB: SECTION HEADER #1
# CHECK-YAML2PDB: .text name
# CHECK-YAML2PDB: 47 virtual size
# CHECK-YAML2PDB: 1000 virtual address
# CHECK-YAML2PDB: 200 size of raw data
# CHECK-YAML2PDB: 400 file pointer to raw data
# CHECK-YAML2PDB: 0 file pointer to relocation table
# CHECK-YAML2PDB: 0 file pointer to line numbers
# CHECK-YAML2PDB: 0 number of relocations
# CHECK-YAML2PDB: 0 number of line numbers
# CHECK-YAML2PDB: 60000020 flags
# CHECK-YAML2PDB: IMAGE_SCN_CNT_CODE
# CHECK-YAML2PDB: IMAGE_SCN_MEM_EXECUTE
# CHECK-YAML2PDB: IMAGE_SCN_MEM_READ

# CHECK-YAML2PDB: SECTION HEADER #2
# CHECK-YAML2PDB: .rdata name
# CHECK-YAML2PDB: 64 virtual size
# CHECK-YAML2PDB: 2000 virtual address
# CHECK-YAML2PDB: 200 size of raw data
# CHECK-YAML2PDB: 600 file pointer to raw data
# CHECK-YAML2PDB: 0 file pointer to relocation table
# CHECK-YAML2PDB: 0 file pointer to line numbers
# CHECK-YAML2PDB: 0 number of relocations
# CHECK-YAML2PDB: 0 number of line numbers
# CHECK-YAML2PDB: 40000040 flags
# CHECK-YAML2PDB: IMAGE_SCN_CNT_INITIALIZED_DATA
# CHECK-YAML2PDB: IMAGE_SCN_MEM_READ

# CHECK-YAML2PDB: SECTION HEADER #3
# CHECK-YAML2PDB: .pdata name
# CHECK-YAML2PDB: 18 virtual size
# CHECK-YAML2PDB: 3000 virtual address
# CHECK-YAML2PDB: 200 size of raw data
# CHECK-YAML2PDB: 800 file pointer to raw data
# CHECK-YAML2PDB: 0 file pointer to relocation table
# CHECK-YAML2PDB: 0 file pointer to line numbers
# CHECK-YAML2PDB: 0 number of relocations
# CHECK-YAML2PDB: 0 number of line numbers
# CHECK-YAML2PDB: 40000040 flags
# CHECK-YAML2PDB: IMAGE_SCN_CNT_INITIALIZED_DATA
# CHECK-YAML2PDB: IMAGE_SCN_MEM_READ

# CHECK-YAML2PDB: Section Map
# CHECK-YAML2PDB: Section 0000 | ovl = 0, group = 0, frame = 1, name = 65535
# CHECK-YAML2PDB: class = 65535, offset = 0, size = 71
# CHECK-YAML2PDB: flags = read | execute | 32 bit addr | selector
# CHECK-YAML2PDB: Section 0001 | ovl = 0, group = 0, frame = 2, name = 65535
# CHECK-YAML2PDB: class = 65535, offset = 0, size = 100
# CHECK-YAML2PDB: flags = read | 32 bit addr | selector
# CHECK-YAML2PDB: Section 0002 | ovl = 0, group = 0, frame = 3, name = 65535
# CHECK-YAML2PDB: class = 65535, offset = 0, size = 24
# CHECK-YAML2PDB: flags = read | 32 bit addr | selector
# CHECK-YAML2PDB: Section 0003 | ovl = 0, group = 0, frame = 4, name = 65535
# CHECK-YAML2PDB: class = 65535, offset = 0, size = 4294967295
# CHECK-YAML2PDB: flags = 32 bit addr | absolute addr

# CHECK-PDB2YAML:DbiStream:
# CHECK-PDB2YAML: SectionHeaders:
# CHECK-PDB2YAML: - Name: .text
# CHECK-PDB2YAML: VirtualSize: 71
# CHECK-PDB2YAML: VirtualAddress: 4096
# CHECK-PDB2YAML: SizeOfRawData: 512
# CHECK-PDB2YAML: PointerToRawData: 1024
# CHECK-PDB2YAML: PointerToRelocations: 0
# CHECK-PDB2YAML: PointerToLinenumbers: 0
# CHECK-PDB2YAML: NumberOfRelocations: 0
# CHECK-PDB2YAML: NumberOfLinenumbers: 0
# CHECK-PDB2YAML: Characteristics: 1610612768
# CHECK-PDB2YAML: - Name: .rdata
# CHECK-PDB2YAML: VirtualSize: 100
# CHECK-PDB2YAML: VirtualAddress: 8192
# CHECK-PDB2YAML: SizeOfRawData: 512
# CHECK-PDB2YAML: PointerToRawData: 1536
# CHECK-PDB2YAML: PointerToRelocations: 0
# CHECK-PDB2YAML: PointerToLinenumbers: 0
# CHECK-PDB2YAML: NumberOfRelocations: 0
# CHECK-PDB2YAML: NumberOfLinenumbers: 0
# CHECK-PDB2YAML: Characteristics: 1073741888
# CHECK-PDB2YAML: - Name: .pdata
# CHECK-PDB2YAML: VirtualSize: 24
# CHECK-PDB2YAML: VirtualAddress: 12288
# CHECK-PDB2YAML: SizeOfRawData: 512
# CHECK-PDB2YAML: PointerToRawData: 2048
# CHECK-PDB2YAML: PointerToRelocations: 0
# CHECK-PDB2YAML: PointerToLinenumbers: 0
# CHECK-PDB2YAML: NumberOfRelocations: 0
# CHECK-PDB2YAML: NumberOfLinenumbers: 0
# CHECK-PDB2YAML: Characteristics: 1073741888

---
DbiStream:
SectionHeaders:
- Name: .text
VirtualSize: 71
VirtualAddress: 4096
SizeOfRawData: 512
PointerToRawData: 1024
PointerToRelocations: 0
PointerToLinenumbers: 0
NumberOfRelocations: 0
NumberOfLinenumbers: 0
Characteristics: 1610612768
- Name: .rdata
VirtualSize: 100
VirtualAddress: 8192
SizeOfRawData: 512
PointerToRawData: 1536
PointerToRelocations: 0
PointerToLinenumbers: 0
NumberOfRelocations: 0
NumberOfLinenumbers: 0
Characteristics: 1073741888
- Name: .pdata
VirtualSize: 24
VirtualAddress: 12288
SizeOfRawData: 512
PointerToRawData: 2048
PointerToRelocations: 0
PointerToLinenumbers: 0
NumberOfRelocations: 0
NumberOfLinenumbers: 0
Characteristics: 1073741888
...
45 changes: 45 additions & 0 deletions llvm/tools/llvm-pdbutil/PdbYaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ using namespace llvm::yaml;

LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::CoffSectionHeader)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::pdb::PdbRaw_FeatureSig)

Expand Down Expand Up @@ -135,6 +136,49 @@ void MappingTraits<msf::SuperBlock>::mapping(IO &IO, msf::SuperBlock &SB) {
IO.mapOptional("BlockMapAddr", SB.BlockMapAddr, u32(0U));
}

CoffSectionHeader::CoffSectionHeader() = default;

CoffSectionHeader::CoffSectionHeader(const object::coff_section &Section)
: Name(Section.Name), VirtualSize(Section.VirtualSize),
VirtualAddress(Section.VirtualAddress),
SizeOfRawData(Section.SizeOfRawData),
PointerToRawData(Section.PointerToRawData),
PointerToRelocations(Section.PointerToRelocations),
PointerToLinenumbers(Section.PointerToLinenumbers),
NumberOfRelocations(Section.NumberOfRelocations),
NumberOfLinenumbers(Section.NumberOfLinenumbers),
Characteristics(Section.Characteristics) {}

object::coff_section CoffSectionHeader::toCoffSection() const {
object::coff_section Sec;
std::memset(Sec.Name, 0, COFF::NameSize);
std::memcpy(Sec.Name, Name.data(),
std::min(static_cast<size_t>(COFF::NameSize), Name.size()));
Sec.VirtualSize = VirtualSize;
Sec.VirtualAddress = VirtualAddress;
Sec.SizeOfRawData = SizeOfRawData;
Sec.PointerToRawData = PointerToRawData;
Sec.PointerToRelocations = PointerToRelocations;
Sec.PointerToLinenumbers = PointerToLinenumbers;
Sec.NumberOfRelocations = NumberOfRelocations;
Sec.NumberOfLinenumbers = NumberOfLinenumbers;
Sec.Characteristics = Characteristics;
return Sec;
}

void MappingTraits<CoffSectionHeader>::mapping(IO &IO, CoffSectionHeader &Obj) {
IO.mapRequired("Name", Obj.Name);
IO.mapOptional("VirtualSize", Obj.VirtualSize);
IO.mapOptional("VirtualAddress", Obj.VirtualAddress);
IO.mapOptional("SizeOfRawData", Obj.SizeOfRawData);
IO.mapOptional("PointerToRawData", Obj.PointerToRawData);
IO.mapOptional("PointerToRelocations", Obj.PointerToRelocations);
IO.mapOptional("PointerToLinenumbers", Obj.PointerToLinenumbers);
IO.mapOptional("NumberOfRelocations", Obj.NumberOfRelocations);
IO.mapOptional("NumberOfLinenumbers", Obj.NumberOfLinenumbers);
IO.mapOptional("Characteristics", Obj.Characteristics);
}

void MappingTraits<StreamBlockList>::mapping(IO &IO, StreamBlockList &SB) {
IO.mapRequired("Stream", SB.Blocks);
}
Expand Down Expand Up @@ -163,6 +207,7 @@ void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
IO.setContext(&Obj.FakeHeader);
}
IO.mapOptional("Modules", Obj.ModInfos);
IO.mapOptional("SectionHeaders", Obj.SectionHeaders);
}

void MappingTraits<PdbTpiStream>::mapping(IO &IO,
Expand Down
21 changes: 21 additions & 0 deletions llvm/tools/llvm-pdbutil/PdbYaml.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Object/COFF.h"
#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
Expand All @@ -40,6 +41,24 @@ struct MSFHeaders {
uint64_t FileSize = 0;
};

struct CoffSectionHeader {
CoffSectionHeader();
CoffSectionHeader(const object::coff_section &Section);

object::coff_section toCoffSection() const;

StringRef Name;
uint32_t VirtualSize = 0;
uint32_t VirtualAddress = 0;
uint32_t SizeOfRawData = 0;
uint32_t PointerToRawData = 0;
uint32_t PointerToRelocations = 0;
uint32_t PointerToLinenumbers = 0;
uint16_t NumberOfRelocations = 0;
uint16_t NumberOfLinenumbers = 0;
uint32_t Characteristics = 0;
};

struct StreamBlockList {
std::vector<uint32_t> Blocks;
};
Expand Down Expand Up @@ -82,6 +101,7 @@ struct PdbDbiStream {

std::vector<PdbDbiModuleInfo> ModInfos;
COFF::header FakeHeader;
std::vector<CoffSectionHeader> SectionHeaders;
};

struct PdbTpiStream {
Expand Down Expand Up @@ -115,6 +135,7 @@ struct PdbObject {

LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::PdbObject)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::MSFHeaders)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::CoffSectionHeader)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(msf::SuperBlock)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::StreamBlockList)
LLVM_YAML_DECLARE_MAPPING_TRAITS_PRIVATE(pdb::yaml::PdbInfoStream)
Expand Down
18 changes: 18 additions & 0 deletions llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,24 @@ Error YAMLOutputStyle::dumpDbiStream() {
}
}
}

if (opts::pdb2yaml::DumpSectionHeaders) {
for (const auto &Section : DS.getSectionHeaders()) {
yaml::CoffSectionHeader Hdr;
Hdr.Name = Section.Name;
Hdr.VirtualSize = Section.VirtualSize;
Hdr.VirtualAddress = Section.VirtualAddress;
Hdr.SizeOfRawData = Section.SizeOfRawData;
Hdr.PointerToRawData = Section.PointerToRawData;
Hdr.PointerToRelocations = Section.PointerToRelocations;
Hdr.PointerToLinenumbers = Section.PointerToLinenumbers;
Hdr.NumberOfRelocations = Section.NumberOfRelocations;
Hdr.NumberOfLinenumbers = Section.NumberOfLinenumbers;
Hdr.Characteristics = Section.Characteristics;
Obj.DbiStream->SectionHeaders.emplace_back(Hdr);
}
}

return Error::success();
}

Expand Down
21 changes: 21 additions & 0 deletions llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,10 @@ cl::list<ModuleSubsection> DumpModuleSubsections(
cl::opt<bool> DumpModuleSyms("module-syms", cl::desc("dump module symbols"),
cl::cat(FileOptions),
cl::sub(PdbToYamlSubcommand));
cl::opt<bool> DumpSectionHeaders("section-headers",
cl::desc("Dump section headers."),
cl::cat(FileOptions),
cl::sub(PdbToYamlSubcommand));

cl::list<std::string> InputFilename(cl::Positional,
cl::desc("<input PDB file>"), cl::Required,
Expand Down Expand Up @@ -865,6 +869,19 @@ static void yamlToPdb(StringRef Path) {
}
}

std::vector<object::coff_section> Sections;
if (!Dbi.SectionHeaders.empty()) {
for (const auto &Hdr : Dbi.SectionHeaders) {
Sections.emplace_back(Hdr.toCoffSection());
}

DbiBuilder.createSectionMap(Sections);
ExitOnErr(DbiBuilder.addDbgStream(
pdb::DbgHeaderType::SectionHdr,
ArrayRef<uint8_t>{(const uint8_t *)Sections.data(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArrayRef supports constructing from a std::vector directly, you could probably just do ArrayRef(Sections)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't do it here, because Sections is a std::vector<object::coff_section> and the function expects an ArrayRef<uint8_t> (i.e. the element type doesn't match).

Copy link
Member

@aganea aganea Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes the downcasting from object::coff_section * to uint_8_t * must be explicit. The reason I mentionned it is that I think boilerplate like this doesn't belong in high level code. We should probably have something like arrayRefFromStringRef, but for downcasting any ArrayRef<T> to a ArrayRef<uint8_t>. We can probably do that in a follow-up PR, since this should be a separate discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. Should I create an issue for this? I can't think of a good name for this function/method(?).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure github issues are really meant as a code cleanup backlog; at least a FIXME comment above would be enough for now.

Sections.size() * sizeof(object::coff_section)}));
}

auto &TpiBuilder = Builder.getTpiBuilder();
const auto &Tpi = YamlObj.TpiStream.value_or(DefaultTpiStream);
TpiBuilder.setVersionHeader(Tpi.Version);
Expand Down Expand Up @@ -1541,6 +1558,7 @@ int main(int Argc, const char **Argv) {
opts::pdb2yaml::DumpModules = true;
opts::pdb2yaml::DumpModuleFiles = true;
opts::pdb2yaml::DumpModuleSyms = true;
opts::pdb2yaml::DumpSectionHeaders = true;
opts::pdb2yaml::DumpModuleSubsections.push_back(
opts::ModuleSubsection::All);
}
Expand All @@ -1551,6 +1569,9 @@ int main(int Argc, const char **Argv) {

if (opts::pdb2yaml::DumpModules)
opts::pdb2yaml::DbiStream = true;

if (opts::pdb2yaml::DumpSectionHeaders)
opts::pdb2yaml::DbiStream = true;
}

llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
Expand Down
1 change: 1 addition & 0 deletions llvm/tools/llvm-pdbutil/llvm-pdbutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ extern llvm::cl::opt<bool> DumpModules;
extern llvm::cl::opt<bool> DumpModuleFiles;
extern llvm::cl::list<ModuleSubsection> DumpModuleSubsections;
extern llvm::cl::opt<bool> DumpModuleSyms;
extern llvm::cl::opt<bool> DumpSectionHeaders;
} // namespace pdb2yaml

namespace explain {
Expand Down