Skip to content

Conversation

Nerixyz
Copy link
Contributor

@Nerixyz Nerixyz commented Sep 7, 2025

pdb2yaml dumps the public symbols, but yaml2pdb didn't create these in the exported PDB. With this PR, they're added to the final PDB.

@Nerixyz Nerixyz requested a review from rnk September 7, 2025 20:25
@llvmbot
Copy link
Member

llvmbot commented Sep 7, 2025

@llvm/pr-subscribers-debuginfo

Author: nerix (Nerixyz)

Changes

pdb2yaml dumps the public symbols, but yaml2pdb didn't create these in the exported PDB. With this PR, they're added to the final PDB.


Full diff: https://github.com/llvm/llvm-project/pull/157362.diff

3 Files Affected:

  • (added) llvm/test/tools/llvm-pdbutil/Inputs/publics.yaml (+22)
  • (added) llvm/test/tools/llvm-pdbutil/publics-yaml2pdb.test (+31)
  • (modified) llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp (+20)
diff --git a/llvm/test/tools/llvm-pdbutil/Inputs/publics.yaml b/llvm/test/tools/llvm-pdbutil/Inputs/publics.yaml
new file mode 100644
index 0000000000000..ab1570e5dff1e
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbutil/Inputs/publics.yaml
@@ -0,0 +1,22 @@
+---
+PublicsStream:
+  Records:
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [ Function ]
+        Offset:          480
+        Segment:         1
+        Name:            '?AMethod@AClass@@QEAAXHPEAD@Z'
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [  ]
+        Offset:          0
+        Segment:         2
+        Name:            '??_7Base@@6B@'
+    - Kind:            S_PUB32
+      PublicSym32:
+        Flags:           [ Function ]
+        Offset:          0
+        Segment:         1
+        Name:            '??0Base@@QEAA@XZ'
+...
diff --git a/llvm/test/tools/llvm-pdbutil/publics-yaml2pdb.test b/llvm/test/tools/llvm-pdbutil/publics-yaml2pdb.test
new file mode 100644
index 0000000000000..192ae25ce8344
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbutil/publics-yaml2pdb.test
@@ -0,0 +1,31 @@
+; RUN: llvm-pdbutil yaml2pdb %p/Inputs/publics.yaml --pdb=%t.pdb
+; RUN: llvm-pdbutil dump --publics %t.pdb | FileCheck --check-prefix=CHECK-YAML2PDB %s
+
+; RUN: llvm-pdbutil pdb2yaml --publics-stream %t.pdb > %t.yaml
+; RUN: FileCheck --input-file=%t.yaml --check-prefix=CHECK-PDB2YAML %s
+
+CHECK-YAML2PDB: S_PUB32 [size = 44] `?AMethod@AClass@@QEAAXHPEAD@Z`
+CHECK-YAML2PDB:      flags = function, addr = 0001:0480
+CHECK-YAML2PDB: S_PUB32 [size = 28] `??_7Base@@6B@`
+CHECK-YAML2PDB:      flags = none, addr = 0002:0000
+CHECK-YAML2PDB: S_PUB32 [size = 32] `??0Base@@QEAA@XZ`
+CHECK-YAML2PDB:      flags = function, addr = 0001:0000
+
+CHECK-PDB2YAML: - Kind:            S_PUB32
+CHECK-PDB2YAML:   PublicSym32:
+CHECK-PDB2YAML:     Flags:           [ Function ]
+CHECK-PDB2YAML:     Offset:          480
+CHECK-PDB2YAML:     Segment:         1
+CHECK-PDB2YAML:     Name:            '?AMethod@AClass@@QEAAXHPEAD@Z'
+CHECK-PDB2YAML: - Kind:            S_PUB32
+CHECK-PDB2YAML:   PublicSym32:
+CHECK-PDB2YAML:     Flags:           [  ]
+CHECK-PDB2YAML:     Offset:          0
+CHECK-PDB2YAML:     Segment:         2
+CHECK-PDB2YAML:     Name:            '??_7Base@@6B@'
+CHECK-PDB2YAML: - Kind:            S_PUB32
+CHECK-PDB2YAML:   PublicSym32:
+CHECK-PDB2YAML:     Flags:           [ Function ]
+CHECK-PDB2YAML:     Offset:          0
+CHECK-PDB2YAML:     Segment:         1
+CHECK-PDB2YAML:     Name:            '??0Base@@QEAA@XZ'
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index e50d19a994b6f..9e90033216a3b 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -38,6 +38,7 @@
 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
 #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
 #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -49,6 +50,7 @@
 #include "llvm/DebugInfo/PDB/IPDBSession.h"
 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/InputFile.h"
@@ -818,6 +820,7 @@ static void yamlToPdb(StringRef Path) {
   pdb::yaml::PdbDbiStream DefaultDbiStream;
   pdb::yaml::PdbTpiStream DefaultTpiStream;
   pdb::yaml::PdbTpiStream DefaultIpiStream;
+  pdb::yaml::PdbPublicsStream DefaultPublicsStream;
 
   const auto &Info = YamlObj.PdbStream.value_or(DefaultInfoStream);
 
@@ -880,6 +883,23 @@ static void yamlToPdb(StringRef Path) {
     IpiBuilder.addTypeRecord(Type.RecordData, std::nullopt);
   }
 
+  auto &GsiBuilder = Builder.getGsiBuilder();
+  const auto &Publics = YamlObj.PublicsStream.value_or(DefaultPublicsStream);
+  std::vector<BulkPublic> BulkPublics;
+  for (const auto &P : Publics.PubSyms) {
+    CVSymbol CV = P.toCodeViewSymbol(Allocator, CodeViewContainer::Pdb);
+    auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(CV));
+
+    BulkPublic BP;
+    BP.Name = PS.Name.data();
+    BP.NameLen = PS.Name.size();
+    BP.setFlags(PS.Flags);
+    BP.Offset = PS.Offset;
+    BP.Segment = PS.Segment;
+    BulkPublics.emplace_back(BP);
+  }
+  GsiBuilder.addPublicSymbols(std::move(BulkPublics));
+
   Builder.getStringTableBuilder().setStrings(*Strings.strings());
 
   codeview::GUID IgnoredOutGuid;

Copy link
Member

@aganea aganea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@Nerixyz Nerixyz merged commit 3751b6b into llvm:main Sep 10, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants