bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/24574] extern symbols in dlls are misleading under debugger


From: martin at martin dot st
Subject: [Bug ld/24574] extern symbols in dlls are misleading under debugger
Date: Sat, 03 Aug 2019 20:59:19 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=24574

--- Comment #9 from Martin Storsjö <martin at martin dot st> ---
I went ahead and dug into this a little bit more. First off, props for the
great testcase, it was great to even have the gdb test routine automated.

I haven't dug into the gdb sources to figure out exactly how/why it does
resolve those symbols, but the difference between what ld.bfd produces is
easily visible.

With ld.bfd before the referenced commit, the symbol table for the linked
test.dll looks like this:
$ x86_64-w64-mingw32-nm test.dll | grep pcode_st
000000006bec4260 R __fu0_pcode_st
000000006bec9300 I __imp_pcode_st
000000006bec9300 I __imp_pcode_st
000000006bec95ac I __nm_pcode_st
000000006bec4260 r .rdata$.refptr.pcode_st
000000006bec4260 R .refptr.pcode_st 

Note that there's two symbols with the name __imp_pcode_st.

With ld.bfd after that referenced commit, the symbol table looks like this:
$ x86_64-w64-mingw32-nm test.dll | grep pcode_st
000000006bec4260 R __fu0_pcode_st
000000006bec9300 I __imp_pcode_st
000000006bec95ac I __nm_pcode_st
000000006bec9300 I pcode_st
000000006bec4260 r .rdata$.refptr.pcode_st
000000006bec4260 R .refptr.pcode_st 

Now there's one symbol named __imp_pcode_st and one named pcode_st, but both
with the same address. The unprefixed symbol probably is what gbb (rightly)
picks up and considers the real address of the symbol, even if it points to the
import address table.

Likewise if LLD links against an import library generated by ld.bfd (LLD
doesn't support linking directly against DLLs), gdb also picks up the wrong
address of the symbol (using the IAT address instead), and the symbol table
contains this:
$ x86_64-w64-mingw32-nm test.dll | grep pcode_st
00000001800038e0 R __imp_pcode_st
0000000180003b8c R __nm_pcode_st
00000001800038e0 R pcode_st
00000001800030b0 r .rdata$.refptr.pcode_st
00000001800030b0 R .refptr.pcode_st 

Now I can easily make LLD stop including the unprefixed symbol in the symbol
table, and then gdb manages to figure out the address of the symbol correctly.
I'll send a patch to LLD for this after I've made an accompanying mandatory
testcase, but the fix essentially looks like this:

diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp
index 3da8b98d3..e157d6dff 100644
--- a/COFF/Writer.cpp
+++ b/COFF/Writer.cpp
@@ -1095,6 +1095,9 @@ Optional<coff_symbol16> Writer::createSymbol(Defined
*def) { 
   }
   }

+  if (def->isRuntimePseudoReloc)
+    return None;
+ 
   StringRef name = def->getName();
   if (name.size() > COFF::NameSize) {
     sym.Name.Offset.Zeroes = 0;


Even more surprisingly though, if I compile test.cpp with clang instead of gcc,
the gdb test succeeds, with both LLD (without this fix) and ld.bfd after the
change. Not sure if this stems from slightly different structure of .refptr and
similar structures, or different debug info that gdb manages to use better wrt
this.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]