Skip to content

Commit 14c2fa2

Browse files
authored
[llvm-pdbutil] Fix register enum field dumping/parsing (llvm#82299)
This fixes a bug where parsing PDBs with usages of register enums were asserting. The main problem is that printing out the code view register enums are taken care of here: https://github.com/nikitalita/llvm-project/blob/e4888a92402f53000a3a5e79d3792c034fc2f343/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp#L152 Which requires a COFF::header in the IO context for the machine type, which we didn't have when dumping a pdb or parsing a yaml file. So, we make a fake one with the machine type.
1 parent 741136a commit 14c2fa2

File tree

5 files changed

+57
-0
lines changed

5 files changed

+57
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
DbiStream:
3+
VerHeader: V70
4+
Age: 1
5+
BuildNumber: 36363
6+
PdbDllVersion: 0
7+
PdbDllRbld: 0
8+
Flags: 0
9+
MachineType: Amd64
10+
Modules:
11+
- Module: '/tmp/test.obj'
12+
Modi:
13+
Signature: 4
14+
Records:
15+
- Kind: S_REGREL32
16+
RegRelativeSym:
17+
Offset: 56
18+
Type: 4494
19+
Register: RSP
20+
VarName: this
21+
...
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
; RUN: llvm-pdbutil yaml2pdb %p/Inputs/register-records.yaml --pdb=%t.pdb
2+
; RUN: llvm-pdbutil dump --symbols %t.pdb | FileCheck --check-prefix=CHECK_YAML2PDB %s
3+
4+
; RUN: llvm-pdbutil pdb2yaml --module-syms %t.pdb > %t.yaml
5+
; RUN: FileCheck --input-file=%t.yaml --check-prefix=CHECK_PDB2YAML %s
6+
7+
CHECK_YAML2PDB: Symbols
8+
CHECK_YAML2PDB: ============================================================
9+
CHECK_YAML2PDB: Mod 0000 | `/tmp/test.obj`:
10+
CHECK_YAML2PDB: 4 | S_REGREL32 [size = 20] `this`
11+
CHECK_YAML2PDB: type = 0x118E (<unknown UDT>), register = RSP, offset = 56
12+
13+
CHECK_PDB2YAML: - Kind: S_REGREL32
14+
CHECK_PDB2YAML: RegRelativeSym:
15+
CHECK_PDB2YAML: Offset: 56
16+
CHECK_PDB2YAML: Type: 4494
17+
CHECK_PDB2YAML: Register: RSP
18+
CHECK_PDB2YAML: VarName: this

llvm/tools/llvm-pdbutil/PdbYaml.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
155155
IO.mapOptional("PdbDllRbld", Obj.PdbDllRbld, uint16_t(0U));
156156
IO.mapOptional("Flags", Obj.Flags, uint16_t(1U));
157157
IO.mapOptional("MachineType", Obj.MachineType, PDB_Machine::x86);
158+
// This is a workaround for IO not having document context with the
159+
// machine type. The machine type is needed to properly parse Register enums
160+
// in the PDB.
161+
if (!IO.getContext()) {
162+
Obj.FakeHeader.Machine = static_cast<uint16_t>(Obj.MachineType);
163+
IO.setContext(&Obj.FakeHeader);
164+
}
158165
IO.mapOptional("Modules", Obj.ModInfos);
159166
}
160167

llvm/tools/llvm-pdbutil/PdbYaml.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "OutputStyle.h"
1313

14+
#include "llvm/BinaryFormat/COFF.h"
1415
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
1516
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
1617
#include "llvm/DebugInfo/MSF/MSFCommon.h"
@@ -80,6 +81,7 @@ struct PdbDbiStream {
8081
PDB_Machine MachineType = PDB_Machine::x86;
8182

8283
std::vector<PdbDbiModuleInfo> ModInfos;
84+
COFF::header FakeHeader;
8385
};
8486

8587
struct PdbTpiStream {

llvm/tools/llvm-pdbutil/YAMLOutputStyle.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "PdbYaml.h"
1212
#include "llvm-pdbutil.h"
1313

14+
#include "llvm/BinaryFormat/COFF.h"
1415
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
1516
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
1617
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
@@ -73,7 +74,15 @@ Error YAMLOutputStyle::dump() {
7374
if (auto EC = dumpPublics())
7475
return EC;
7576

77+
// Fake Coff header for dumping register enumerations.
78+
COFF::header Header;
79+
auto MachineType =
80+
Obj.DbiStream ? Obj.DbiStream->MachineType : PDB_Machine::Unknown;
81+
Header.Machine = static_cast<uint16_t>(MachineType);
82+
Out.setContext(&Header);
7683
flush();
84+
Out.setContext(nullptr);
85+
7786
return Error::success();
7887
}
7988

0 commit comments

Comments
 (0)