[lld] [LLD][COFF] Add S_THUNK32 PDB records for all ARM64EC import thunks (PR #115310)

Jacek Caban via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 8 02:20:35 PST 2024


https://github.com/cjacek updated https://github.com/llvm/llvm-project/pull/115310

>From 54e7fa217962dd49de11c5bdae9beebca2542e1b Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Thu, 7 Nov 2024 00:38:59 +0100
Subject: [PATCH] [LLD][COFF] Add S_THUNK32 PDB records for all ARM64EC import
 thunks

---
 lld/COFF/PDB.cpp               | 66 +++++++++++++++++++---------------
 lld/test/COFF/arm64ec-pdb.test | 14 ++++++--
 2 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index c20b54a5d42e4f..985528ed4294c5 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1537,7 +1537,7 @@ void PDBLinker::addImportFilesToPDB() {
     if (!file->thunkSym)
       continue;
 
-    if (!file->thunkSym->isLive())
+    if (!file->thunkSym->isLive() && !file->impchkThunk)
       continue;
 
     std::string dll = StringRef(file->dllName).lower();
@@ -1562,53 +1562,61 @@ void PDBLinker::addImportFilesToPDB() {
       mod->setObjFileName(libPath);
     }
 
-    DefinedImportThunk *thunk = cast<DefinedImportThunk>(file->thunkSym);
-    Chunk *thunkChunk = thunk->getChunk();
-    OutputSection *thunkOS = ctx.getOutputSection(thunkChunk);
-
     ObjNameSym ons(SymbolRecordKind::ObjNameSym);
     Compile3Sym cs(SymbolRecordKind::Compile3Sym);
-    Thunk32Sym ts(SymbolRecordKind::Thunk32Sym);
-    ScopeEndSym es(SymbolRecordKind::ScopeEndSym);
 
     ons.Name = file->dllName;
     ons.Signature = 0;
 
     fillLinkerVerRecord(cs, ctx.config.machine);
 
-    ts.Name = thunk->getName();
-    ts.Parent = 0;
-    ts.End = 0;
-    ts.Next = 0;
-    ts.Thunk = ThunkOrdinal::Standard;
-    ts.Length = thunkChunk->getSize();
-    ts.Segment = thunkOS->sectionIndex;
-    ts.Offset = thunkChunk->getRVA() - thunkOS->getRVA();
-
     llvm::BumpPtrAllocator &bAlloc = lld::bAlloc();
     mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(
         ons, bAlloc, CodeViewContainer::Pdb));
     mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(
         cs, bAlloc, CodeViewContainer::Pdb));
 
-    CVSymbol newSym = codeview::SymbolSerializer::writeOneSymbol(
-        ts, bAlloc, CodeViewContainer::Pdb);
+    auto addThunk = [&](Symbol *sym, Chunk *chunk) {
+      OutputSection *thunkOS = ctx.getOutputSection(chunk);
+
+      Thunk32Sym ts(SymbolRecordKind::Thunk32Sym);
+      ScopeEndSym es(SymbolRecordKind::ScopeEndSym);
+
+      ts.Name = sym->getName();
+      ts.Parent = 0;
+      ts.End = 0;
+      ts.Next = 0;
+      ts.Thunk = ThunkOrdinal::Standard;
+      ts.Length = chunk->getSize();
+      ts.Segment = thunkOS->sectionIndex;
+      ts.Offset = chunk->getRVA() - thunkOS->getRVA();
 
-    // Write ptrEnd for the S_THUNK32.
-    ScopeRecord *thunkSymScope =
-        getSymbolScopeFields(const_cast<uint8_t *>(newSym.data().data()));
+      CVSymbol newSym = codeview::SymbolSerializer::writeOneSymbol(
+          ts, bAlloc, CodeViewContainer::Pdb);
 
-    mod->addSymbol(newSym);
+      // Write ptrEnd for the S_THUNK32.
+      ScopeRecord *thunkSymScope =
+          getSymbolScopeFields(const_cast<uint8_t *>(newSym.data().data()));
 
-    newSym = codeview::SymbolSerializer::writeOneSymbol(es, bAlloc,
-                                                        CodeViewContainer::Pdb);
-    thunkSymScope->ptrEnd = mod->getNextSymbolOffset();
+      mod->addSymbol(newSym);
 
-    mod->addSymbol(newSym);
+      newSym = codeview::SymbolSerializer::writeOneSymbol(
+          es, bAlloc, CodeViewContainer::Pdb);
+      thunkSymScope->ptrEnd = mod->getNextSymbolOffset();
+
+      mod->addSymbol(newSym);
+
+      pdb::SectionContrib sc =
+          createSectionContrib(ctx, chunk, mod->getModuleIndex());
+      mod->setFirstSectionContrib(sc);
+    };
 
-    pdb::SectionContrib sc =
-        createSectionContrib(ctx, thunk->getChunk(), mod->getModuleIndex());
-    mod->setFirstSectionContrib(sc);
+    if (file->auxThunkSym && file->auxThunkSym->isLive())
+      addThunk(file->thunkSym, file->auxThunkSym->getChunk());
+    if (file->impchkThunk)
+      addThunk(file->impchkThunk->sym, file->impchkThunk);
+    if (file->thunkSym->isLive())
+      addThunk(file->thunkSym, file->thunkSym->getChunk());
   }
 }
 
diff --git a/lld/test/COFF/arm64ec-pdb.test b/lld/test/COFF/arm64ec-pdb.test
index 97b77039153c6f..2739a1f7f75da3 100644
--- a/lld/test/COFF/arm64ec-pdb.test
+++ b/lld/test/COFF/arm64ec-pdb.test
@@ -11,7 +11,7 @@ RUN: llvm-pdbutil dump out.pdb -all | FileCheck %s
 
 CHECK:                             Streams
 CHECK-NEXT: ============================================================
-CHECK:        Stream 10 ( 104 bytes): [Module "Import:test.dll"]
+CHECK:        Stream 10 ( 184 bytes): [Module "Import:test.dll"]
 CHECK-NEXT:              Blocks: [9]
 CHECK-NEXT:   Stream 11 ({{[ 0-9]+}} bytes): [Module "* Linker *"]
 CHECK-NEXT:              Blocks: [10]
@@ -27,7 +27,7 @@ CHECK-NEXT:   Mod 2 (debug info not present): [{{.*}}loadconfig-arm64ec.obj]
 CHECK-NEXT: Mod 0003 | `test.dll`:
 CHECK-NEXT:   Mod 3 (debug info not present): [test.dll]
 CHECK-NEXT: Mod 0004 | `Import:test.dll`:
-CHECK-NEXT:   Stream 10, 104 bytes
+CHECK-NEXT:   Stream 10, 184 bytes
 
 CHECK:                                Modules
 CHECK-NEXT: ============================================================
@@ -127,8 +127,16 @@ CHECK-NEXT:          frontend = 0.0.0.0, backend = 14.10.25019.0
 CHECK-NEXT:          flags = none
 CHECK-NEXT:     64 | S_THUNK32 [size = 32] `func`
 CHECK-NEXT:          parent = 0, end = 96, next = 0
-CHECK-NEXT:          kind = thunk, size = 6, addr = 0001:4096
+CHECK-NEXT:          kind = thunk, size = 12, addr = 0001:0008
 CHECK-NEXT:     96 | S_END [size = 4]
+CHECK-NEXT:    100 | S_THUNK32 [size = 40] `__impchk_func`
+CHECK-NEXT:          parent = 0, end = 140, next = 0
+CHECK-NEXT:          kind = thunk, size = 20, addr = 0001:0020
+CHECK-NEXT:    140 | S_END [size = 4]
+CHECK-NEXT:    144 | S_THUNK32 [size = 32] `func`
+CHECK-NEXT:          parent = 0, end = 176, next = 0
+CHECK-NEXT:          kind = thunk, size = 6, addr = 0001:4096
+CHECK-NEXT:    176 | S_END [size = 4]
 CHECK-NEXT: Mod 0005 | `* Linker *`:
 CHECK-NEXT:      4 | S_OBJNAME [size = 20] sig=0, `* Linker *`
 CHECK-NEXT:     24 | S_COMPILE3 [size = 40]



More information about the llvm-commits mailing list