[Lldb-commits] [lldb] [LLDB][NativePDB] Implement `AddSymbols` (PR #154121)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Aug 18 07:07:25 PDT 2025
https://github.com/Nerixyz created https://github.com/llvm/llvm-project/pull/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`.
>From 10b3535afc063552e7d05c8e8096570887a70397 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Mon, 18 Aug 2025 15:56:45 +0200
Subject: [PATCH] [LLDB][NativePDB] Implement `AddSymbols`
---
.../NativePDB/SymbolFileNativePDB.cpp | 43 +++++++++++++-
.../Shell/SymbolFile/NativePDB/symtab.cpp | 59 +++++++++++++++++++
2 files changed, 101 insertions(+), 1 deletion(-)
create mode 100644 lldb/test/Shell/SymbolFile/NativePDB/symtab.cpp
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 112eb06e462fc..ed466d8295f65 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1054,7 +1054,48 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
return TranslateLanguage(item->m_compile_opts->getLanguage());
}
-void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {}
+void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
+ std::set<lldb::addr_t> existing_addresses;
+ for (size_t i = 0; i < symtab.GetNumSymbols(); i++)
+ existing_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress());
+
+ auto *section_list = m_objfile_sp->GetSectionList();
+ if (!section_list)
+ return;
+
+ for (auto pid : m_index->publics().getPublicsTable()) {
+ PdbGlobalSymId global{pid, true};
+ CVSymbol sym = m_index->ReadSymbolRecord(global);
+ auto kind = sym.kind();
+ if (kind != S_PUB32)
+ continue;
+ PublicSym32 pub =
+ llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym));
+
+ auto section_sp = section_list->FindSectionByID(pub.Segment);
+ if (!section_sp)
+ continue;
+
+ lldb::SymbolType type = eSymbolTypeData;
+ if ((pub.Flags & PublicSymFlags::Function) != PublicSymFlags::None ||
+ (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
+ type = eSymbolTypeCode;
+
+ symtab.AddSymbol(Symbol(/*symID=*/pid,
+ /*name=*/pub.Name,
+ /*type=*/type,
+ /*external=*/true,
+ /*is_debug=*/false,
+ /*is_trampoline=*/false,
+ /*is_artificial=*/false,
+ /*section_sp=*/section_sp,
+ /*value=*/pub.Offset,
+ /*size=*/0,
+ /*size_is_valid=*/false,
+ /*contains_linker_annotations=*/false,
+ /*flags=*/0));
+ }
+}
size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/symtab.cpp b/lldb/test/Shell/SymbolFile/NativePDB/symtab.cpp
new file mode 100644
index 0000000000000..81d643d9572d8
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/NativePDB/symtab.cpp
@@ -0,0 +1,59 @@
+// REQUIRES: x86
+
+// Test symtab reading
+// RUN: %build --compiler=clang-cl --arch=64 --nodefaultlib -o %t.exe -- %s
+// RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symtab %t.exe --find-symbols-by-regex=".*" | FileCheck %s
+// RUN: env LLDB_USE_NATIVE_PDB_READER=0 lldb-test symtab %t.exe --find-symbols-by-regex=".*" | FileCheck %s
+
+struct A {
+ void something() {}
+};
+
+namespace ns {
+template <typename T> struct B {
+ struct C {
+ static int static_fn() { return 1; }
+ };
+
+ int b_func() const { return 3; }
+};
+
+struct Dyn {
+ virtual ~Dyn() = default;
+};
+
+int a_function() { return 1; }
+} // namespace ns
+
+void *operator new(unsigned long long n) { return nullptr; }
+void operator delete(void *p, unsigned long long i) {}
+
+A global_a;
+ns::B<long long>::C global_c;
+int global_int;
+
+int main(int argc, char **argv) {
+ A a;
+ a.something();
+ ns::B<int>::C::static_fn();
+ ns::B<bool>::C::static_fn();
+ ns::B<short> b;
+ ns::Dyn dyn;
+ return ns::a_function() + b.b_func();
+}
+
+// CHECK-DAG: Code {{.*}} main
+// CHECK-DAG: Code {{.*}} ?b_func@?$B at F@ns@@QEBAHXZ
+// CHECK-DAG: Code {{.*}} ?something at A@@QEAAXXZ
+// CHECK-DAG: Code {{.*}} ??_GDyn at ns@@UEAAPEAXI at Z
+// CHECK-DAG: Code {{.*}} ??2 at YAPEAX_K@Z
+// CHECK-DAG: Code {{.*}} ??3 at YAXPEAX_K@Z
+// CHECK-DAG: Code {{.*}} ?static_fn at C@?$B at H@ns@@SAHXZ
+// CHECK-DAG: Code {{.*}} ?a_function at ns@@YAHXZ
+// CHECK-DAG: Code {{.*}} ?static_fn at C@?$B at _N@ns@@SAHXZ
+// CHECK-DAG: Code {{.*}} ??1Dyn at ns@@UEAA at XZ
+// CHECK-DAG: Code {{.*}} ??0Dyn at ns@@QEAA at XZ
+// CHECK-DAG: Data {{.*}} ?global_int@@3HA
+// CHECK-DAG: Data {{.*}} ??_7Dyn at ns@@6B@
+// CHECK-DAG: Data {{.*}} ?global_a@@3UA@@A
+// CHECK-DAG: Data {{.*}} ?global_c@@3UC@?$B at _J@ns@@A
More information about the lldb-commits
mailing list