diff --git a/llvm/test/tools/llvm-pdbutil/Inputs/register-records.yaml b/llvm/test/tools/llvm-pdbutil/Inputs/register-records.yaml new file mode 100644 index 0000000000000..2e7d707529eba --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/Inputs/register-records.yaml @@ -0,0 +1,21 @@ +--- +DbiStream: + VerHeader: V70 + Age: 1 + BuildNumber: 36363 + PdbDllVersion: 0 + PdbDllRbld: 0 + Flags: 0 + MachineType: Amd64 + Modules: + - Module: '/tmp/test.obj' + Modi: + Signature: 4 + Records: + - Kind: S_REGREL32 + RegRelativeSym: + Offset: 56 + Type: 4494 + Register: RSP + VarName: this +... diff --git a/llvm/test/tools/llvm-pdbutil/register-records.test b/llvm/test/tools/llvm-pdbutil/register-records.test new file mode 100644 index 0000000000000..60a02732ba94d --- /dev/null +++ b/llvm/test/tools/llvm-pdbutil/register-records.test @@ -0,0 +1,18 @@ +; RUN: llvm-pdbutil yaml2pdb %p/Inputs/register-records.yaml --pdb=%t.pdb +; RUN: llvm-pdbutil dump --symbols %t.pdb | FileCheck --check-prefix=CHECK_YAML2PDB %s + +; RUN: llvm-pdbutil pdb2yaml --module-syms %t.pdb > %t.yaml +; RUN: FileCheck --input-file=%t.yaml --check-prefix=CHECK_PDB2YAML %s + +CHECK_YAML2PDB: Symbols +CHECK_YAML2PDB: ============================================================ +CHECK_YAML2PDB: Mod 0000 | `/tmp/test.obj`: +CHECK_YAML2PDB: 4 | S_REGREL32 [size = 20] `this` +CHECK_YAML2PDB: type = 0x118E (), register = RSP, offset = 56 + +CHECK_PDB2YAML: - Kind: S_REGREL32 +CHECK_PDB2YAML: RegRelativeSym: +CHECK_PDB2YAML: Offset: 56 +CHECK_PDB2YAML: Type: 4494 +CHECK_PDB2YAML: Register: RSP +CHECK_PDB2YAML: VarName: this diff --git a/llvm/tools/llvm-pdbutil/PdbYaml.cpp b/llvm/tools/llvm-pdbutil/PdbYaml.cpp index a26241967b5ad..fac1d89321610 100644 --- a/llvm/tools/llvm-pdbutil/PdbYaml.cpp +++ b/llvm/tools/llvm-pdbutil/PdbYaml.cpp @@ -155,6 +155,13 @@ void MappingTraits::mapping(IO &IO, PdbDbiStream &Obj) { IO.mapOptional("PdbDllRbld", Obj.PdbDllRbld, uint16_t(0U)); IO.mapOptional("Flags", Obj.Flags, uint16_t(1U)); IO.mapOptional("MachineType", Obj.MachineType, PDB_Machine::x86); + // This is a workaround for IO not having document context with the + // machine type. The machine type is needed to properly parse Register enums + // in the PDB. + if (!IO.getContext()) { + Obj.FakeHeader.Machine = static_cast(Obj.MachineType); + IO.setContext(&Obj.FakeHeader); + } IO.mapOptional("Modules", Obj.ModInfos); } diff --git a/llvm/tools/llvm-pdbutil/PdbYaml.h b/llvm/tools/llvm-pdbutil/PdbYaml.h index 4382e91e20973..b0c0f6a00c499 100644 --- a/llvm/tools/llvm-pdbutil/PdbYaml.h +++ b/llvm/tools/llvm-pdbutil/PdbYaml.h @@ -11,6 +11,7 @@ #include "OutputStyle.h" +#include "llvm/BinaryFormat/COFF.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/MSF/MSFCommon.h" @@ -80,6 +81,7 @@ struct PdbDbiStream { PDB_Machine MachineType = PDB_Machine::x86; std::vector ModInfos; + COFF::header FakeHeader; }; struct PdbTpiStream { diff --git a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp index 80b76657facc7..ecb4c2175e49a 100644 --- a/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp @@ -11,6 +11,7 @@ #include "PdbYaml.h" #include "llvm-pdbutil.h" +#include "llvm/BinaryFormat/COFF.h" #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h" @@ -73,7 +74,15 @@ Error YAMLOutputStyle::dump() { if (auto EC = dumpPublics()) return EC; + // Fake Coff header for dumping register enumerations. + COFF::header Header; + auto MachineType = + Obj.DbiStream ? Obj.DbiStream->MachineType : PDB_Machine::Unknown; + Header.Machine = static_cast(MachineType); + Out.setContext(&Header); flush(); + Out.setContext(nullptr); + return Error::success(); }