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 <nerix...@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@F@ns@@QEBAHXZ +// CHECK-DAG: Code {{.*}} ?something@A@@QEAAXXZ +// CHECK-DAG: Code {{.*}} ??_GDyn@ns@@UEAAPEAXI@Z +// CHECK-DAG: Code {{.*}} ??2@YAPEAX_K@Z +// CHECK-DAG: Code {{.*}} ??3@YAXPEAX_K@Z +// CHECK-DAG: Code {{.*}} ?static_fn@C@?$B@H@ns@@SAHXZ +// CHECK-DAG: Code {{.*}} ?a_function@ns@@YAHXZ +// CHECK-DAG: Code {{.*}} ?static_fn@C@?$B@_N@ns@@SAHXZ +// CHECK-DAG: Code {{.*}} ??1Dyn@ns@@UEAA@XZ +// CHECK-DAG: Code {{.*}} ??0Dyn@ns@@QEAA@XZ +// CHECK-DAG: Data {{.*}} ?global_int@@3HA +// CHECK-DAG: Data {{.*}} ??_7Dyn@ns@@6B@ +// CHECK-DAG: Data {{.*}} ?global_a@@3UA@@A +// CHECK-DAG: Data {{.*}} ?global_c@@3UC@?$B@_J@ns@@A _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits