Skip to content

Conversation

mstorsjo
Copy link
Member

9cc9efc changed LLD to use a StringTableBuilder for optimizing the string table, used for long section and symbol names.

That commit had a bug, where the symbol table entry for an import thunk with a long symbol name wouldn't get fetched from the StringTableBuilder, if the base symbol name (without the "_imp" prefix) wasn't over 8 chars.

This should fix issues with Go, which errors out on reading the executables with a broken symbol table, as noted in mstorsjo/llvm-mingw#518 and golang/go#75219.

9cc9efc changed LLD to use a
StringTableBuilder for optimizing the string table, used for
long section and symbol names.

That commit had a bug, where the symbol table entry for an import
thunk with a long symbol name wouldn't get fetched from the
StringTableBuilder, if the base symbol name (without the "__imp_"
prefix) wasn't over 8 chars.

This should fix issues with Go, which errors out on reading the
executables with a broken symbol table, as noted in
mstorsjo/llvm-mingw#518 and
golang/go#75219.
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2025

@llvm/pr-subscribers-lld-coff

@llvm/pr-subscribers-lld

Author: Martin Storsjö (mstorsjo)

Changes

9cc9efc changed LLD to use a StringTableBuilder for optimizing the string table, used for long section and symbol names.

That commit had a bug, where the symbol table entry for an import thunk with a long symbol name wouldn't get fetched from the StringTableBuilder, if the base symbol name (without the "_imp" prefix) wasn't over 8 chars.

This should fix issues with Go, which errors out on reading the executables with a broken symbol table, as noted in mstorsjo/llvm-mingw#518 and golang/go#75219.


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

2 Files Affected:

  • (modified) lld/COFF/Writer.cpp (+1-1)
  • (modified) lld/test/COFF/strtab.s (+19-3)
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index b4f00996319b1..258a82e371f3a 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1620,7 +1620,7 @@ void Writer::createSymbolAndStringTable() {
             dthunk->wrappedSym->writtenToSymtab = true;
             if (std::optional<coff_symbol16> sym =
                     createSymbol(dthunk->wrappedSym)) {
-              if (d->getName().size() > COFF::NameSize)
+              if (dthunk->wrappedSym->getName().size() > COFF::NameSize)
                 longNameSymbols.emplace_back(outputSymtab.size(),
                                              dthunk->wrappedSym->getName());
               outputSymtab.push_back(*sym);
diff --git a/lld/test/COFF/strtab.s b/lld/test/COFF/strtab.s
index fbdd8df52d540..9edc13e19e825 100644
--- a/lld/test/COFF/strtab.s
+++ b/lld/test/COFF/strtab.s
@@ -1,17 +1,32 @@
 # REQUIRES: x86
 # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj
-# RUN: lld-link -out:%t.exe -entry:main %t.obj -debug:dwarf
+# RUN: lld-link -machine:x64 -def:%S/Inputs/library.def -implib:%t.lib
+# RUN: lld-link -out:%t.exe -entry:main %t.obj %t.lib -debug:dwarf
 # RUN: llvm-readobj --string-table %t.exe | FileCheck %s
+# RUN: llvm-nm %t.exe | FileCheck %s --check-prefix=SYMBOLS
+
+# Note, for this test to have the intended test coverage, the imported symbol
+# "function" needs to be such that the symbol name itself is <= 8 chars, while
+# "__imp_"+name is >8 chars.
 
 # CHECK:      StringTable {
-# CHECK-NEXT:   Length: 87
+# CHECK-NEXT:   Length: 102
 # CHECK-NEXT:   [     4] .debug_abbrev
 # CHECK-NEXT:   [    12] .debug_line
 # CHECK-NEXT:   [    1e] long_name_symbolz
 # CHECK-NEXT:   [    30] .debug_abbrez
-# CHECK-NEXT:   [    3e] __impl_long_name_symbolA
+# CHECK-NEXT:   [    3e] __imp_function
+# CHECK-NEXT:   [    4d] __impl_long_name_symbolA
 # CHECK-NEXT: }
 
+# SYMBOLS:      140001000 N .debug_abbrez
+# SYMBOLS-NEXT: 140002070 R __imp_function
+# SYMBOLS-NEXT: 140001000 t __impl_long_name_symbolA
+# SYMBOLS-NEXT: 140001010 T function
+# SYMBOLS-NEXT: 140001000 t long_name_symbolA
+# SYMBOLS-NEXT: 140001000 t long_name_symbolz
+# SYMBOLS-NEXT: 140001000 T main
+# SYMBOLS-NEXT: 140001000 t name_symbolA
 
 .global main
 .text
@@ -21,6 +36,7 @@ long_name_symbolA:
 __impl_long_name_symbolA:
 name_symbolA:
 .debug_abbrez:
+  call function
   ret
 
 .section        .debug_abbrev,"dr"

@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2025

@llvm/pr-subscribers-platform-windows

Author: Martin Storsjö (mstorsjo)

Changes

9cc9efc changed LLD to use a StringTableBuilder for optimizing the string table, used for long section and symbol names.

That commit had a bug, where the symbol table entry for an import thunk with a long symbol name wouldn't get fetched from the StringTableBuilder, if the base symbol name (without the "_imp" prefix) wasn't over 8 chars.

This should fix issues with Go, which errors out on reading the executables with a broken symbol table, as noted in mstorsjo/llvm-mingw#518 and golang/go#75219.


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

2 Files Affected:

  • (modified) lld/COFF/Writer.cpp (+1-1)
  • (modified) lld/test/COFF/strtab.s (+19-3)
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index b4f00996319b1..258a82e371f3a 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1620,7 +1620,7 @@ void Writer::createSymbolAndStringTable() {
             dthunk->wrappedSym->writtenToSymtab = true;
             if (std::optional<coff_symbol16> sym =
                     createSymbol(dthunk->wrappedSym)) {
-              if (d->getName().size() > COFF::NameSize)
+              if (dthunk->wrappedSym->getName().size() > COFF::NameSize)
                 longNameSymbols.emplace_back(outputSymtab.size(),
                                              dthunk->wrappedSym->getName());
               outputSymtab.push_back(*sym);
diff --git a/lld/test/COFF/strtab.s b/lld/test/COFF/strtab.s
index fbdd8df52d540..9edc13e19e825 100644
--- a/lld/test/COFF/strtab.s
+++ b/lld/test/COFF/strtab.s
@@ -1,17 +1,32 @@
 # REQUIRES: x86
 # RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t.obj
-# RUN: lld-link -out:%t.exe -entry:main %t.obj -debug:dwarf
+# RUN: lld-link -machine:x64 -def:%S/Inputs/library.def -implib:%t.lib
+# RUN: lld-link -out:%t.exe -entry:main %t.obj %t.lib -debug:dwarf
 # RUN: llvm-readobj --string-table %t.exe | FileCheck %s
+# RUN: llvm-nm %t.exe | FileCheck %s --check-prefix=SYMBOLS
+
+# Note, for this test to have the intended test coverage, the imported symbol
+# "function" needs to be such that the symbol name itself is <= 8 chars, while
+# "__imp_"+name is >8 chars.
 
 # CHECK:      StringTable {
-# CHECK-NEXT:   Length: 87
+# CHECK-NEXT:   Length: 102
 # CHECK-NEXT:   [     4] .debug_abbrev
 # CHECK-NEXT:   [    12] .debug_line
 # CHECK-NEXT:   [    1e] long_name_symbolz
 # CHECK-NEXT:   [    30] .debug_abbrez
-# CHECK-NEXT:   [    3e] __impl_long_name_symbolA
+# CHECK-NEXT:   [    3e] __imp_function
+# CHECK-NEXT:   [    4d] __impl_long_name_symbolA
 # CHECK-NEXT: }
 
+# SYMBOLS:      140001000 N .debug_abbrez
+# SYMBOLS-NEXT: 140002070 R __imp_function
+# SYMBOLS-NEXT: 140001000 t __impl_long_name_symbolA
+# SYMBOLS-NEXT: 140001010 T function
+# SYMBOLS-NEXT: 140001000 t long_name_symbolA
+# SYMBOLS-NEXT: 140001000 t long_name_symbolz
+# SYMBOLS-NEXT: 140001000 T main
+# SYMBOLS-NEXT: 140001000 t name_symbolA
 
 .global main
 .text
@@ -21,6 +36,7 @@ long_name_symbolA:
 __impl_long_name_symbolA:
 name_symbolA:
 .debug_abbrez:
+  call function
   ret
 
 .section        .debug_abbrev,"dr"

@mstorsjo mstorsjo merged commit 0d6af2d into llvm:main Sep 25, 2025
13 checks passed
@mstorsjo mstorsjo deleted the lld-imp-symbol-name branch September 25, 2025 20:11
@mstorsjo mstorsjo added this to the LLVM 21.x Release milestone Sep 25, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Sep 25, 2025
@mstorsjo
Copy link
Member Author

/cherry-pick 0d6af2d

@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2025

/pull-request #160770

@llvmbot llvmbot moved this from Needs Triage to Done in LLVM Release Status Sep 25, 2025
dyung pushed a commit to llvmbot/llvm-project that referenced this pull request Oct 1, 2025
9cc9efc changed LLD to use a
StringTableBuilder for optimizing the string table, used for long
section and symbol names.

That commit had a bug, where the symbol table entry for an import thunk
with a long symbol name wouldn't get fetched from the
StringTableBuilder, if the base symbol name (without the "__imp_"
prefix) wasn't over 8 chars.

This should fix issues with Go, which errors out on reading the
executables with a broken symbol table, as noted in
mstorsjo/llvm-mingw#518 and
golang/go#75219.

(cherry picked from commit 0d6af2d)
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
9cc9efc changed LLD to use a
StringTableBuilder for optimizing the string table, used for long
section and symbol names.

That commit had a bug, where the symbol table entry for an import thunk
with a long symbol name wouldn't get fetched from the
StringTableBuilder, if the base symbol name (without the "__imp_"
prefix) wasn't over 8 chars.

This should fix issues with Go, which errors out on reading the
executables with a broken symbol table, as noted in
mstorsjo/llvm-mingw#518 and
golang/go#75219.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

3 participants