Skip to content

Commit 6578772

Browse files
authored
[LLDB][NativePDB] Implement AddSymbols (#154121)
This PR implements `SymbolFileNativePDB::AddSymbols` which adds public symbols to the symbol table. These symbols are found in the publics stream. It contains mangled names coupled with addresses. Addresses are a pair of (segment, offset). If I understood correctly, then the segment is the section ID from the COFF header. Sections are already [constructed](https://github.com/llvm/llvm-project/blob/c48ec7fb60b5e0b4100731d75f82ea63c0ec7b45/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp#L1048) using this 1-based index ([MS docs](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers)). This allows us to use `section_list->FindSectionByID`.
1 parent 82218fb commit 6578772

File tree

7 files changed

+138
-5
lines changed

7 files changed

+138
-5
lines changed

lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,44 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
10541054
return TranslateLanguage(item->m_compile_opts->getLanguage());
10551055
}
10561056

1057-
void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {}
1057+
void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
1058+
auto *section_list = m_objfile_sp->GetSectionList();
1059+
if (!section_list)
1060+
return;
1061+
1062+
for (auto pid : m_index->publics().getPublicsTable()) {
1063+
PdbGlobalSymId global{pid, true};
1064+
CVSymbol sym = m_index->ReadSymbolRecord(global);
1065+
auto kind = sym.kind();
1066+
if (kind != S_PUB32)
1067+
continue;
1068+
PublicSym32 pub =
1069+
llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym));
1070+
1071+
auto section_sp = section_list->FindSectionByID(pub.Segment);
1072+
if (!section_sp)
1073+
continue;
1074+
1075+
lldb::SymbolType type = eSymbolTypeData;
1076+
if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||
1077+
(pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
1078+
type = eSymbolTypeCode;
1079+
1080+
symtab.AddSymbol(Symbol(/*symID=*/pid,
1081+
/*name=*/pub.Name,
1082+
/*type=*/type,
1083+
/*external=*/true,
1084+
/*is_debug=*/true,
1085+
/*is_trampoline=*/false,
1086+
/*is_artificial=*/false,
1087+
/*section_sp=*/section_sp,
1088+
/*value=*/pub.Offset,
1089+
/*size=*/0,
1090+
/*size_is_valid=*/false,
1091+
/*contains_linker_annotations=*/false,
1092+
/*flags=*/0));
1093+
}
1094+
}
10581095

10591096
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
10601097
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());

lldb/test/Shell/SymbolFile/NativePDB/disassembly.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ int main(int argc, char **argv) {
1818

1919

2020
// CHECK: (lldb) disassemble --flavor=intel -m -n main
21-
// CHECK: 12 int foo() { return 42; }
22-
// CHECK-NEXT: 13
23-
// CHECK-NEXT: ** 14 int main(int argc, char **argv) {
21+
// CHECK: ** 14 int main(int argc, char **argv) {
2422
// CHECK: disassembly.cpp.tmp.exe`main:
2523
// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+0>: sub rsp, 0x38
2624
// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+4>: mov dword ptr [rsp + 0x34], 0x0

lldb/test/Shell/SymbolFile/NativePDB/inline_sites.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x0000000140001046)
6262
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
6363
# CHECK: LineEntry: [0x0000000140001000-0x0000000140001004): /tmp/a.cpp:2
64+
# CHECK-NEXT: Symbol: id = {{.*}}, range = [0x0000000140001000-0x0000000140001046), name="main"
6465
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
6566
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
6667

@@ -71,6 +72,7 @@
7172
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
7273
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
7374
# CHECK: LineEntry: [0x0000000140001004-0x000000014000100c): /tmp/a.h:5
75+
# CHECK-NEXT: Symbol: id = {{.*}}, range = [0x0000000140001000-0x0000000140001046), name="main"
7476
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
7577
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
7678
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
@@ -84,6 +86,7 @@
8486
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
8587
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
8688
# CHECK: LineEntry: [0x0000000140001010-0x0000000140001018): /tmp/a.h:7
89+
# CHECK-NEXT: Symbol: id = {{.*}}, range = [0x0000000140001000-0x0000000140001046), name="main"
8790
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
8891
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
8992
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
@@ -99,6 +102,7 @@
99102
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
100103
# CHECK-NEXT: id = {{.*}}, range = [0x14000101c-0x140001039), name = "Class1::bar", decl = b.h:4
101104
# CHECK: LineEntry: [0x000000014000101c-0x0000000140001022): /tmp/b.h:5
105+
# CHECK-NEXT: Symbol: id = {{.*}}, range = [0x0000000140001000-0x0000000140001046), name="main"
102106
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x000000014000101e) -> DW_OP_reg24 XMM7
103107
# CHECK-NEXT: Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x0000000140001039) -> DW_OP_breg7 RSP+52
104108
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
@@ -118,6 +122,7 @@
118122
# CHECK-NEXT: id = {{.*}}, range = [0x14000101c-0x140001039), name = "Class1::bar", decl = b.h:4
119123
# CHECK-NEXT: id = {{.*}}, range = [0x14000102a-0x140001039), name = "Namespace2::Class2::func", decl = c.h:4
120124
# CHECK: LineEntry: [0x000000014000102a-0x0000000140001031): /tmp/c.h:5
125+
# CHECK-NEXT: Symbol: id = {{.*}}, range = [0x0000000140001000-0x0000000140001046), name="main"
121126
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = [0x000000014000102a, 0x0000000140001039) -> DW_OP_reg24 XMM7
122127
# CHECK-NEXT: Variable: id = {{.*}}, name = "func_local", type = "int", valid ranges = <block>, location = [0x000000014000102a, 0x0000000140001039) -> DW_OP_breg7 RSP+48
123128
# CHECK-NEXT: Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x0000000140001039) -> DW_OP_breg7 RSP+52
@@ -132,6 +137,7 @@
132137
# CHECK: Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x0000000140001046)
133138
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
134139
# CHECK: LineEntry: [0x0000000140001039-0x000000014000103d): /tmp/a.cpp:3
140+
# CHECK-NEXT: Symbol: id = {{.*}}, range = [0x0000000140001000-0x0000000140001046), name="main"
135141
# CHECK-NEXT: Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
136142
# CHECK-NEXT: Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
137143

@@ -142,6 +148,7 @@
142148
# CHECK: Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
143149
# CHECK-NEXT: id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
144150
# CHECK: LineEntry: [0x0000000140001044-0x0000000140001046): /tmp/a.h:8
151+
# CHECK-NEXT: Symbol: id = {{.*}}, range = [0x0000000140001000-0x0000000140001046), name="main"
145152
# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
146153
# CHECK-NEXT: Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001044, 0x0000000140001046) -> DW_OP_breg7 RSP+44
147154
# CHECK-NEXT: Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001044, 0x0000000140001045) -> DW_OP_reg26 XMM9

0 commit comments

Comments
 (0)