]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: fix 32-bit mingw DLL symbol export bug
authorOleg Tolmatcev <oleg.tolmatcev@gmail.com>
Fri, 19 Jan 2024 15:02:45 +0000 (15:02 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 19 Jan 2024 15:02:45 +0000 (15:02 +0000)
I think there's a bug in ld on 32-bit Windows.  Here is a tiny project for reproducing the problem:
https://github.com/oltolm/ld-mingw32-bug

A 32-bit DLL exports two stdcall functions "myfunc" and "myfunc64". The functions would normally get
exported as "myfunc@0" and "myfunc64@0". The "DEF" file exports them as "myfunc" and "myfunc64"
without the decorations. When you run the executable it shows an error message saying that it cannot
find "myfunc64".

I think it happens because the sorting in ld is wrong. I think it should use the exported names
"myfunc" and "myfunc64", but instead it uses the decorated names "myfunc@0" or "myfunc65@0". The
ordering of functions in the DLL is different depending on which names you use.

My patch changes ld to use undecorated exported names for sorting and it seems to fix the problem.
When I execute ctest in my project, it runs successfully.

ld/deffilep.y

index 4967ff116c5ad181b1e1e320053756a28b569d58..fb12e6dc7b858d604d8bdd26b14f4e3f70becb92 100644 (file)
@@ -610,12 +610,11 @@ cmp_export_elem (const def_file_export *e, const char *ex_name,
 {
   int r;
 
-  if ((r = are_names_equal (ex_name, e->name)) != 0)
+  if ((r = are_names_equal (its_name ? its_name : ex_name,
+                           e->its_name ? e->its_name : e->name)) != 0)
     return r;
   if ((r = are_names_equal (in_name, e->internal_name)) != 0)
     return r;
-  if ((r = are_names_equal (its_name, e->its_name)) != 0)
-    return r;
   return (ord - e->ordinal);
 }