Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH 08/27] gdb/testsuite: Export all DLL symbols on windows-msvc via generated .def
Date: Thu, 23 Jul 2026 14:00:59 +0100	[thread overview]
Message-ID: <20260723130118.206735-9-pedro@palves.net> (raw)
In-Reply-To: <20260723130118.206735-1-pedro@palves.net>

When building a shared library for a test, gdb_compile_shlib arranges
for the DLL's symbols to be exported and for an import library to be
produced, so that the test executable can link against the DLL.  With
GNU ld this works implicitly: linking a DLL exports all of its symbols
by default.

lld-link, which is the linker clang drives on a windows-msvc target,
does not do that.  It exports nothing unless explicitly told to, via
__declspec(dllexport) in the sources, a /EXPORT switch per symbol, or
a module-definition (.def) file.  The testsuite's shared-library
sources carry (almost) no dllexport annotations, so the import library
comes out empty and linking the test executable fails, e.g.:

 lld-link: error: undefined symbol: pendfunc

Fix this by restoring the export-all-symbols behavior by generating a
.def file that lists every defined, external symbol in the DLL's
objects, and passing it to lld-link with /DEF.  The symbol list is
collected with nm.

FWIW, this is the same approach CMake takes for its
WINDOWS_EXPORT_ALL_SYMBOLS target property.

Change-Id: I1a9638259986910d473c4f02fbf60437e3653e04
---
 gdb/testsuite/lib/future.exp |  8 +++++
 gdb/testsuite/lib/gdb.exp    | 64 +++++++++++++++++++++++++++++++++++-
 2 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/gdb/testsuite/lib/future.exp b/gdb/testsuite/lib/future.exp
index ca37fdaaf52..e308bef0a60 100644
--- a/gdb/testsuite/lib/future.exp
+++ b/gdb/testsuite/lib/future.exp
@@ -224,6 +224,14 @@ proc gdb_find_readelf {} {
     return [gdb_transform_tool readelf]
 }
 
+proc gdb_find_nm {} {
+    global NM_FOR_TARGET
+    if {[info exists NM_FOR_TARGET]} {
+	return $NM_FOR_TARGET
+    }
+    return [gdb_transform_tool nm]
+}
+
 proc gdb_find_windres {} {
     global WINDRES_FOR_TARGET
     if {[info exists WINDRES_FOR_TARGET]} {
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index c9ee8e9753d..b3588f0edec 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -6812,7 +6812,11 @@ proc gdb_compile {source dest type options} {
 	    }
 	    if { $shlib_found == 0 } {
 		set shlib_found 1
-		if { [is_pecoff_target] } {
+		# lld-link does not understand GNU ld's
+		# --enable-auto-import.  On windows-msvc the DLL's
+		# symbols are exported via a generated .def instead.
+		# See gdb_windows_gen_def_file.
+		if { [is_pecoff_target] && ![istarget "*-*-windows-msvc*"] } {
 		    lappend new_options "ldflags=-Wl,--enable-auto-import"
 		}
 		if { [test_compiler_info "gcc-*"] || [test_compiler_info "clang-*"] } {
@@ -7208,6 +7212,50 @@ proc gdb_compile_pthreads {source dest type options} {
     }
 }
 
+# Write a module-definition (.def) file to DEFFILE that exports every
+# defined, external symbol found in OBJECTS, and return DEFFILE.
+# Unlike GNU ld, which auto-exports a DLL's symbols, lld-link exports
+# nothing unless told to, so the import library it produces would be
+# empty and executables linking against the DLL would fail with
+# undefined symbols.  Feeding lld-link this generated .def restores
+# the export-all-symbols behavior the testsuite relies on.  Returns
+# empty string on failure.
+
+proc gdb_windows_gen_def_file {objects deffile} {
+    set nm [gdb_find_nm]
+
+    set exports {}
+    foreach obj $objects {
+	if {[catch {exec $nm $obj} output]} {
+	    verbose -log "gdb_windows_gen_def_file: nm $obj failed: $output"
+	    return ""
+	}
+	foreach line [split $output "\n"] {
+	    # nm prints "<value> <type> <name>".  A defined external
+	    # symbol has an uppercase type letter, undefined (U) has a
+	    # blank value, and local symbols use lowercase letters.
+	    # Export text/weak as code and data/bss/rodata/common as
+	    # DATA.
+	    if {![regexp {^\S* +(\S) +(\S+)$} $line -> type name]} {
+		continue
+	    }
+	    switch -- $type {
+		"T" - "W" { lappend exports $name }
+		"D" - "B" - "R" - "C" { lappend exports "$name DATA" }
+	    }
+	}
+    }
+
+    set f [open $deffile w]
+    puts $f "EXPORTS"
+    foreach e [lsort -unique $exports] {
+	puts $f "    $e"
+    }
+    close $f
+
+    return $deffile
+}
+
 # Build a shared library from SOURCES.
 
 proc gdb_compile_shlib_1 {sources dest options} {
@@ -7310,6 +7358,20 @@ proc gdb_compile_shlib_1 {sources dest options} {
 	    }
 	    if { [istarget "*-*-windows-msvc*"] } {
 		lappend link_options "ldflags=-Wl,/IMPLIB:${name}.a"
+
+		# lld-link exports nothing by default, so generate a
+		# .def listing every symbol and feed it in, to get the
+		# export-all-symbols behavior GNU ld gives us
+		# implicitly.
+		set deffile [gdb_windows_gen_def_file $objects ${dest}.def]
+		if { $deffile eq "" } {
+		    return -1
+		}
+		# Pass the path in Windows-native form so MSYS2's
+		# argument conversion doesn't mangle the "/DEF:/..."
+		# value.
+		set deffile [host_file_normalize $deffile]
+		lappend link_options "ldflags=-Wl,/DEF:${deffile}"
 	    } else {
 		lappend link_options "ldflags=-Wl,--out-implib,${name}.a"
 	    }
-- 
2.54.0


  parent reply	other threads:[~2026-07-23 13:05 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 13:00 [PATCH 00/27] Teach the testsuite about the Windows/MSVC target Pedro Alves
2026-07-23 13:00 ` [PATCH 01/27] gdb/testsuite: Don't link with -lm on windows-msvc Pedro Alves
2026-07-23 13:00 ` [PATCH 02/27] gdb/testsuite: Use unprefixed runtest for a native Windows/MSVC build Pedro Alves
2026-07-23 13:00 ` [PATCH 03/27] gdb/testsuite: Find host binutils in a native Windows/MSVC config Pedro Alves
2026-07-23 13:00 ` [PATCH 04/27] gdb/testsuite: Compile with -Wno-deprecated-declarations on windows-msvc Pedro Alves
2026-07-23 13:00 ` [PATCH 05/27] gdb/testsuite: Recognize windows-msvc across lib/gdb.exp procedures Pedro Alves
2026-07-23 13:00 ` [PATCH 06/27] gdb/testsuite: Don't pass -fPIC on PE/COFF targets Pedro Alves
2026-07-23 13:00 ` [PATCH 07/27] gdb/testsuite: Use /IMPLIB on windows-msvc to name import libraries Pedro Alves
2026-07-23 13:00 ` Pedro Alves [this message]
2026-07-23 13:01 ` [PATCH 09/27] gdb/testsuite: Restrict --no-as-needed to ELF targets Pedro Alves
2026-07-23 13:01 ` [PATCH 10/27] gdb.base/set-cwd.exp: Use is_windows_native_target Pedro Alves
2026-07-23 13:01 ` [PATCH 11/27] gdb.base/exitsignal.exp: " Pedro Alves
2026-07-23 13:01 ` [PATCH 12/27] gdb.base/exitsignal.exp: Relax SIGSEGV second-chance pattern Pedro Alves
2026-07-23 13:01 ` [PATCH 13/27] gdb/testsuite: Skip -Ttext-segment on PE Pedro Alves
2026-07-23 13:01 ` [PATCH 14/27] gdb/testsuite: Support text_segment on windows-msvc via /BASE Pedro Alves
2026-07-23 13:01 ` [PATCH 15/27] gdb.base/shreloc.exp: Use gdb_compile text_segment to set image base Pedro Alves
2026-07-23 13:01 ` [PATCH 16/27] gdb/coffread: Don't relocate absolute symbols Pedro Alves
2026-07-23 13:01 ` [PATCH 17/27] gdb.base/shreloc.exp: Test absolute symbols portably Pedro Alves
2026-07-23 13:01 ` [PATCH 18/27] gdb: %p => host_address_to_string, target-section owner token Pedro Alves
2026-07-23 13:01 ` [PATCH 19/27] gdb: %p => host_address_to_string, dump_for_expression Pedro Alves
2026-07-23 13:01 ` [PATCH 20/27] gdb: %p => host_address_to_string, find_symtab_matching_filename Pedro Alves
2026-07-23 13:01 ` [PATCH 21/27] gdb: %p => host_address_to_string, handle_output_debug_string Pedro Alves
2026-07-23 13:01 ` [PATCH 22/27] gdb.base/maint-info-sections.exp: Match exec file name with optional .exe Pedro Alves
2026-07-23 13:01 ` [PATCH 23/27] gdb.base/maint-info-sections.exp: Remove stale Windows DATA xfail Pedro Alves
2026-07-23 13:01 ` [PATCH 24/27] gdb.base/solib-weak.exp: Skip on all PE/COFF targets Pedro Alves
2026-07-23 13:01 ` [PATCH 25/27] gdb.server/wrapper.exp: Skip on all Windows targets Pedro Alves
2026-07-23 13:01 ` [PATCH 26/27] gdb/testsuite: Factor out dlopen/LoadLibrary shim into lib/gdb-dlfcn.h Pedro Alves
2026-07-23 13:01 ` [PATCH 27/27] gdb/testsuite/lib/gdb-dlfcn.h: __WIN32__ => _WIN32 Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260723130118.206735-9-pedro@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox