public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* LD: Invalid memory access when linking a dll (maybe Bug 29006 revisited)
@ 2022-05-10 17:19 Roland Schwingel
  2022-05-11 12:49 ` Alan Modra
  0 siblings, 1 reply; 2+ messages in thread
From: Roland Schwingel @ 2022-05-10 17:19 UTC (permalink / raw)
  To: Binutils

Hi...

I am building C++20 code on windows and cross on linux for windows.

Unfortunately ld crashes on linking a dll on both windows and linux.There 
is a bug report from Sandro Mani describing maybe the same - or at least - 
a very similar problem.
(https://sourceware.org/bugzilla/show_bug.cgi?id=29006)
The issue got adressed by Nick Clifton who also added a patch to the issue

We are using binutils 2.38 (with and with out the fix of Nick) together 
with some self built GCC 11.2 and 11.3.But it seems it does not make a 
difference.

The bug does not happen always. The concrete circumstances are yet unclear 
to me. The invalid memory access may only happen when I link C++20 code 
compiled by GCC with debug informations (-g) when linking with -O3 (and no 
-g) it appears to work. I got it reproducable in about 10 different cases. 
Valgrind reports around 19110 errors by invalid memory access.

Invocation with valgrind of ld with the patch of nick already applied: 
valgrind 
/ovde_plugins/gcc11/mingwin/lib64/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/bin/ld 
-v 
  --sysroot=/ovde_plugins/gcc11/mingwin -m i386pep 
  --subsystem console --dll -Bdynamic -e DllMainCRTStartup 
--enable-auto-image-base 
  -o /tmp/parser_lib_g.dll 
/ovde_plugins/gcc11/mingwin/lib64/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o 

 
/ovde_plugins/gcc11/mingwin/lib64/gcc/x86_64-w64-mingw32/11.3.0/crtbegin.o 

  <a bunch of -L params>
  /tmp/parser_lib_g.exp 
  -pie --image-base 0x15690000 --enable-auto-import 
  /tmp/parser_lib_dllmain.o /tmp/Parser.o /tmp/Parser_17020R.o <and some 
more .o files>
  --nxcompat --whole-archive -lxml_g -lovcore_g -lhelper_lib_g 
--no-whole-archive -lstdc++ 
  --as-needed -lgomp -luser32 -lkernel32 -lmingwthrd -lmingw32 -lgcc_s 
-lgcc -lmoldname -lmingwex -lmsvcrt -lkernel32 
  /ovde_plugins/gcc11/mingwin/lib64/gcc/x86_64-w64-mingw32/11.3.0/crtend.o

==23381==
GNU ld (GNU Binutils) 2.38
==23381== Invalid read of size 1
==23381==    at 0x508B434: vfprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50B3E63: vasprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50912F6: asprintf (in /lib64/libc-2.17.so)
==23381==    by 0x4432CE: make_runtime_pseudo_reloc (pe-dll.c:2663)
==23381==    by 0x443A81: pep_create_import_fixup (pe-dll.c:2838)
==23381==    by 0x432CA6: make_import_fixup (ei386pep.c:1129)
==23381==    by 0x43F8A5: pe_walk_relocs (pe-dll.c:1349)
==23381==    by 0x43FD95: pep_find_data_imports (pe-dll.c:1497)
==23381==    by 0x433674: gld_i386pep_after_open (ei386pep.c:1408)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==  Address 0x95e2500 is 0 bytes inside a block of size 20 free'd
==23381==    at 0x4C2E10B: free (vg_replace_malloc.c:871)
==23381==    by 0x445199: pep_process_import_defs (pe-dll.c:3324)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==  Block was alloc'd at
==23381==    at 0x4C306F1: malloc (vg_replace_malloc.c:380)
==23381==    by 0x51658B: xmalloc (xmalloc.c:149)
==23381==    by 0x5166BE: xstrdup (xstrdup.c:34)
==23381==    by 0x444ADB: pep_process_import_defs (pe-dll.c:3234)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==
==23381== Invalid read of size 1
==23381==    at 0x50B83A0: _IO_default_xsputn (in /lib64/libc-2.17.so)
==23381==    by 0x508B472: vfprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50B3E63: vasprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50912F6: asprintf (in /lib64/libc-2.17.so)
==23381==    by 0x4432CE: make_runtime_pseudo_reloc (pe-dll.c:2663)
==23381==    by 0x443A81: pep_create_import_fixup (pe-dll.c:2838)
==23381==    by 0x432CA6: make_import_fixup (ei386pep.c:1129)
==23381==    by 0x43F8A5: pe_walk_relocs (pe-dll.c:1349)
==23381==    by 0x43FD95: pep_find_data_imports (pe-dll.c:1497)
==23381==    by 0x433674: gld_i386pep_after_open (ei386pep.c:1408)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==  Address 0x95e2500 is 0 bytes inside a block of size 20 free'd
==23381==    at 0x4C2E10B: free (vg_replace_malloc.c:871)
==23381==    by 0x445199: pep_process_import_defs (pe-dll.c:3324)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==  Block was alloc'd at
==23381==    at 0x4C306F1: malloc (vg_replace_malloc.c:380)
==23381==    by 0x51658B: xmalloc (xmalloc.c:149)
==23381==    by 0x5166BE: xstrdup (xstrdup.c:34)
==23381==    by 0x444ADB: pep_process_import_defs (pe-dll.c:3234)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==
==23381== Invalid read of size 1
==23381==    at 0x50B83AE: _IO_default_xsputn (in /lib64/libc-2.17.so)
==23381==    by 0x508B472: vfprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50B3E63: vasprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50912F6: asprintf (in /lib64/libc-2.17.so)
==23381==    by 0x4432CE: make_runtime_pseudo_reloc (pe-dll.c:2663)
==23381==    by 0x443A81: pep_create_import_fixup (pe-dll.c:2838)
==23381==    by 0x432CA6: make_import_fixup (ei386pep.c:1129)
==23381==    by 0x43F8A5: pe_walk_relocs (pe-dll.c:1349)
==23381==    by 0x43FD95: pep_find_data_imports (pe-dll.c:1497)
==23381==    by 0x433674: gld_i386pep_after_open (ei386pep.c:1408)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==  Address 0x95e2502 is 2 bytes inside a block of size 20 free'd
==23381==    at 0x4C2E10B: free (vg_replace_malloc.c:871)
==23381==    by 0x445199: pep_process_import_defs (pe-dll.c:3324)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==  Block was alloc'd at
==23381==    at 0x4C306F1: malloc (vg_replace_malloc.c:380)
==23381==    by 0x51658B: xmalloc (xmalloc.c:149)
==23381==    by 0x5166BE: xstrdup (xstrdup.c:34)
==23381==    by 0x444ADB: pep_process_import_defs (pe-dll.c:3234)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==
==23381== Invalid read of size 1
==23381==    at 0x508B434: vfprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50B3E63: vasprintf (in /lib64/libc-2.17.so)
==23381==    by 0x50912F6: asprintf (in /lib64/libc-2.17.so)
==23381==    by 0x4436C3: pe_create_runtime_relocator_reference 
(pe-dll.c:2754)
==23381==    by 0x443AD1: pep_create_import_fixup (pe-dll.c:2844)
==23381==    by 0x432CA6: make_import_fixup (ei386pep.c:1129)
==23381==    by 0x43F8A5: pe_walk_relocs (pe-dll.c:1349)
==23381==    by 0x43FD95: pep_find_data_imports (pe-dll.c:1497)
==23381==    by 0x433674: gld_i386pep_after_open (ei386pep.c:1408)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==  Address 0x95e2500 is 0 bytes inside a block of size 20 free'd
==23381==    at 0x4C2E10B: free (vg_replace_malloc.c:871)
==23381==    by 0x445199: pep_process_import_defs (pe-dll.c:3324)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==  Block was alloc'd at
==23381==    at 0x4C306F1: malloc (vg_replace_malloc.c:380)
==23381==    by 0x51658B: xmalloc (xmalloc.c:149)
==23381==    by 0x5166BE: xstrdup (xstrdup.c:34)
==23381==    by 0x444ADB: pep_process_import_defs (pe-dll.c:3234)
==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
==23381==    by 0x422440: main (ldmain.c:497)
==23381==
==23381==
==23381== HEAP SUMMARY:
==23381==     in use at exit: 83,040,828 bytes in 25,511 blocks
==23381==   total heap usage: 96,735 allocs, 71,224 frees, 122,050,867 
bytes allocated
==23381==
==23381== LEAK SUMMARY:
==23381==    definitely lost: 2,432,172 bytes in 1,940 blocks
==23381==    indirectly lost: 194,424 bytes in 1,075 blocks
==23381==      possibly lost: 0 bytes in 0 blocks
==23381==    still reachable: 80,414,232 bytes in 22,496 blocks
==23381==         suppressed: 0 bytes in 0 blocks
==23381== Rerun with --leak-check=full to see details of leaked memory
==23381==
==23381== For lists of detected and suppressed errors, rerun with: -s
==23381== ERROR SUMMARY: 19110 errors from 4 contexts (suppressed: 0 from 
0)

It is maybe related to C++20. I do not have problems linking 
C/C++17/ObjectiveC code. And only when linking code compiled with -g.

From what I understand all symbols are processed in 
pep_process_import_defs() from pe_dll.c. The symbols are temporarily 
stored in the static variable dll_symname (pe-dll.c:3234) and afterwards 
freed (pe-dll.c:3324) but dll_symname remains to an already freed pointer 
afterwards. in make_runtime_pseudo_reloc() (pe-dll.c:2663) this variable 
is by then accessed. What should be the right content of dll_symname in 
this case?

Hope this can help to track down the problem.

Roland

-----------------------------------------------------------------------------------------------------
Roland Schwingel, Head of Research & Development
OneVision Software AG, Dr. Leo-Ritter-Str. 9, 93049 Regensburg, Germany
Phone: +49 941 78004 0 --- email: roland.schwingel@onevision.com
-----------------------------------------------------------------------------------------------------
This email may contain trade secrets or other confidential information. If 
you have received this email inadvertently, please let us know by reply 
and then delete the email entirely from your system. You are explicitly 
prohibited from reviewing, copying, and/or distributing the email to third 
parties.
Sitz der Gesellschaft: Regensburg; Handelsregister: HRB 8015, Amtsgericht 
Regensburg; Vorstand: Hussein Khalil; Vorsitzender des Aufsichtsrats: 
Michael Abels


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: LD: Invalid memory access when linking a dll (maybe Bug 29006 revisited)
  2022-05-10 17:19 LD: Invalid memory access when linking a dll (maybe Bug 29006 revisited) Roland Schwingel
@ 2022-05-11 12:49 ` Alan Modra
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2022-05-11 12:49 UTC (permalink / raw)
  To: Roland Schwingel; +Cc: Binutils

On Tue, May 10, 2022 at 07:19:03PM +0200, Roland Schwingel wrote:
> ==23381== Invalid read of size 1
> ==23381==    at 0x508B434: vfprintf (in /lib64/libc-2.17.so)
> ==23381==    by 0x50B3E63: vasprintf (in /lib64/libc-2.17.so)
> ==23381==    by 0x50912F6: asprintf (in /lib64/libc-2.17.so)
> ==23381==    by 0x4432CE: make_runtime_pseudo_reloc (pe-dll.c:2663)
> ==23381==    by 0x443A81: pep_create_import_fixup (pe-dll.c:2838)
> ==23381==    by 0x432CA6: make_import_fixup (ei386pep.c:1129)
> ==23381==    by 0x43F8A5: pe_walk_relocs (pe-dll.c:1349)
> ==23381==    by 0x43FD95: pep_find_data_imports (pe-dll.c:1497)
> ==23381==    by 0x433674: gld_i386pep_after_open (ei386pep.c:1408)

OK, so we are running pep_find_data_imports and happen to call
make_runtime_pseudo_reloc while inpecting relocs.
make_runtime_pseudo_reloc uses dll_symname, which has been cleared

> ==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
> ==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
> ==23381==    by 0x422440: main (ldmain.c:497)
> ==23381==  Address 0x95e2500 is 0 bytes inside a block of size 20 free'd
> ==23381==    at 0x4C2E10B: free (vg_replace_malloc.c:871)
> ==23381==    by 0x445199: pep_process_import_defs (pe-dll.c:3324)

after finishing pep_process_import_defs.  These two functions are
called in close proximity.  See emultempl/pep.em.  My guess is that
this broke with commit c4a8df19ba0a.

> ==23381==    by 0x433648: gld_i386pep_after_open (ei386pep.c:1405)
> ==23381==    by 0x428FCB: ldemul_after_open (ldemul.c:65)
> ==23381==    by 0x41D9F2: lang_process (ldlang.c:8162)
> ==23381==    by 0x422440: main (ldmain.c:497)

Looks like we need to set up dll_symname earlier now.  Please try
this patch.

	PR 29006
	* pe-dll.c (dll_name): Delete, replacing with..
	(dll_filename): ..this, moved earlier in file.
	(generate_edata): Delete parameters.  Don't set up dll_name here..
	(pe_process_import_defs): ..instead set up dll_filename and
	dll_symname here before returning.
	(dll_symname_len): Delete write-only variable.
	(pe_dll_generate_implib): Don't set up dll_symname here.

diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index ed68f66a95b..4cf8ed23672 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -505,7 +505,7 @@ static int export_table_size;
 static int count_exported;
 static int count_exported_byname;
 static int count_with_ordinals;
-static const char *dll_name;
+static const char *dll_filename;
 static int min_ordinal, max_ordinal;
 static int *exported_symbols;
 
@@ -1066,25 +1066,13 @@ build_filler_bfd (int include_edata)
 /* Gather all the exported symbols and build the .edata section.  */
 
 static void
-generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
+generate_edata (void)
 {
   int i, next_ordinal;
   int name_table_size = 0;
-  const char *dlnp;
 
   /* First, we need to know how many exported symbols there are,
      and what the range of ordinals is.  */
-  if (pe_def_file->name)
-    dll_name = pe_def_file->name;
-  else
-    {
-      dll_name = bfd_get_filename (abfd);
-
-      for (dlnp = dll_name; *dlnp; dlnp++)
-	if (*dlnp == '\\' || *dlnp == '/' || *dlnp == ':')
-	  dll_name = dlnp + 1;
-    }
-
   if (count_with_ordinals && max_ordinal > count_exported)
     {
       if (min_ordinal > max_ordinal - count_exported + 1)
@@ -1159,7 +1147,7 @@ generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
 	      + 4 * export_table_size		/* addresses */
 	      + 4 * count_exported_byname	/* name ptrs */
 	      + 2 * count_exported_byname	/* ordinals */
-	      + name_table_size + strlen (dll_name) + 1);
+	      + name_table_size + strlen (dll_filename) + 1);
 }
 
 /* Fill the exported symbol offsets. The preliminary work has already
@@ -1232,7 +1220,7 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
     }
 
   bfd_put_32 (abfd, ERVA (enamestr), edata_d + 12);
-  strcpy (enamestr, dll_name);
+  strcpy (enamestr, dll_filename);
   enamestr += strlen (enamestr) + 1;
   bfd_put_32 (abfd, min_ordinal, edata_d + 16);
   bfd_put_32 (abfd, export_table_size, edata_d + 20);
@@ -1971,9 +1959,7 @@ pe_dll_generate_def_file (const char *pe_out_def_filename)
 static asymbol **symtab;
 static int symptr;
 static int tmp_seq;
-static const char *dll_filename;
 static char *dll_symname;
-static int dll_symname_len;
 
 #define UNDSEC bfd_und_section_ptr
 
@@ -2835,7 +2821,8 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend, char *name,
 	printf ("creating runtime pseudo-reloc entry for %s (addend=%d)\n",
 		fixup_name, (int) addend);
 
-      b = make_runtime_pseudo_reloc (name, fixup_name, addend, rel->howto->bitsize,
+      b = make_runtime_pseudo_reloc (name, fixup_name, addend,
+				     rel->howto->bitsize,
 				     link_info.output_bfd);
       add_bfd_to_link (b, bfd_get_filename (b), &link_info);
 
@@ -2861,13 +2848,6 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_
   bfd *ibfd;
   bfd *head = 0;
 
-  dll_filename = (def->name) ? def->name : dll_name;
-  dll_symname = xstrdup (dll_filename);
-  dll_symname_len = strlen (dll_symname);
-  for (i = 0; dll_symname[i]; i++)
-    if (!ISALNUM (dll_symname[i]))
-      dll_symname[i] = '_';
-
   unlink_if_ordinary (impfilename);
 
   outarch = bfd_openw (impfilename, 0);
@@ -2995,8 +2975,7 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_
 	  }
       }
 
-      n = make_one (def->exports + i, outarch,
-		    ! (def->exports + i)->flag_data);
+      n = make_one (def->exports + i, outarch, !(def->exports + i)->flag_data);
       n->archive_next = head;
       head = n;
       def->exports[i].internal_name = internal;
@@ -3208,128 +3187,145 @@ add_bfd_to_link (bfd *abfd, const char *name, struct bfd_link_info *linfo)
 void
 pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
 {
-  int i, j;
-  def_file_module *module;
-  def_file_import *imp;
-
   pe_dll_id_target (bfd_get_target (output_bfd));
 
-  if (!pe_def_file)
-    return;
-
-  imp = pe_def_file->imports;
-
-  pe_create_undef_table ();
-
-  for (module = pe_def_file->modules; module; module = module->next)
+  if (pe_def_file)
     {
-      int do_this_dll = 0;
+      int i, j;
+      def_file_module *module;
+      def_file_import *imp;
 
-      for (i = 0; i < pe_def_file->num_imports && imp[i].module != module; i++)
-	;
-      if (i >= pe_def_file->num_imports)
-	continue;
+      imp = pe_def_file->imports;
 
-      dll_filename = module->name;
-      dll_symname = xstrdup (module->name);
-      dll_symname_len = strlen (dll_symname);
-      for (j = 0; dll_symname[j]; j++)
-	if (!ISALNUM (dll_symname[j]))
-	  dll_symname[j] = '_';
+      pe_create_undef_table ();
 
-      for (; i < pe_def_file->num_imports && imp[i].module == module; i++)
+      for (module = pe_def_file->modules; module; module = module->next)
 	{
-	  def_file_export exp;
-	  struct bfd_link_hash_entry *blhe;
-	  int lead_at = (*imp[i].internal_name == '@');
-	  /* See if we need this import.  */
-	  size_t len = strlen (imp[i].internal_name);
-	  char *name = xmalloc (len + 2 + 6);
-	  bool include_jmp_stub = false;
-	  bool is_cdecl = false;
-	  bool is_undef = false;
-
-	  if (!lead_at && strchr (imp[i].internal_name, '@') == NULL)
-	      is_cdecl = true;
-
-	  if (lead_at)
-	    sprintf (name, "%s", imp[i].internal_name);
-	  else
-	    sprintf (name, "%s%s",U (""), imp[i].internal_name);
+	  int do_this_dll = 0;
 
-	  blhe = bfd_link_hash_lookup (linfo->hash, name,
-				       false, false, false);
+	  for (i = 0; i < pe_def_file->num_imports; i++)
+	    if (imp[i].module == module)
+	      break;
+	  if (i >= pe_def_file->num_imports)
+	    continue;
+
+	  dll_filename = module->name;
+	  dll_symname = xstrdup (module->name);
+	  for (j = 0; dll_symname[j]; j++)
+	    if (!ISALNUM (dll_symname[j]))
+	      dll_symname[j] = '_';
 
-	  /* Include the jump stub for <sym> only if the <sym>
-	     is undefined.  */
-	  if (!blhe || (blhe && blhe->type != bfd_link_hash_undefined))
+	  for (; i < pe_def_file->num_imports && imp[i].module == module; i++)
 	    {
+	      def_file_export exp;
+	      struct bfd_link_hash_entry *blhe;
+	      int lead_at = (*imp[i].internal_name == '@');
+	      /* See if we need this import.  */
+	      size_t len = strlen (imp[i].internal_name);
+	      char *name = xmalloc (len + 2 + 6);
+	      bool include_jmp_stub = false;
+	      bool is_cdecl = false;
+	      bool is_undef = false;
+
+	      if (!lead_at && strchr (imp[i].internal_name, '@') == NULL)
+		is_cdecl = true;
+
 	      if (lead_at)
-		sprintf (name, "%s%s", "__imp_", imp[i].internal_name);
+		sprintf (name, "%s", imp[i].internal_name);
 	      else
-		sprintf (name, "%s%s%s", "__imp_", U (""),
-			 imp[i].internal_name);
+		sprintf (name, "%s%s",U (""), imp[i].internal_name);
 
 	      blhe = bfd_link_hash_lookup (linfo->hash, name,
 					   false, false, false);
-	      if (blhe)
-		is_undef = (blhe->type == bfd_link_hash_undefined);
-	    }
-	  else
-	    {
-	      include_jmp_stub = true;
-	      is_undef = (blhe->type == bfd_link_hash_undefined);
-	    }
 
-	  if (is_cdecl && (!blhe || (blhe && blhe->type != bfd_link_hash_undefined)))
-	    {
-	      sprintf (name, "%s%s",U (""), imp[i].internal_name);
-	      blhe = pe_find_cdecl_alias_match (linfo, name);
-	      include_jmp_stub = true;
-	      if (blhe)
-		is_undef = (blhe->type == bfd_link_hash_undefined);
-	    }
+	      /* Include the jump stub for <sym> only if the <sym>
+		 is undefined.  */
+	      if (!blhe || (blhe && blhe->type != bfd_link_hash_undefined))
+		{
+		  if (lead_at)
+		    sprintf (name, "%s%s", "__imp_", imp[i].internal_name);
+		  else
+		    sprintf (name, "%s%s%s", "__imp_", U (""),
+			     imp[i].internal_name);
+
+		  blhe = bfd_link_hash_lookup (linfo->hash, name,
+					       false, false, false);
+		  if (blhe)
+		    is_undef = (blhe->type == bfd_link_hash_undefined);
+		}
+	      else
+		{
+		  include_jmp_stub = true;
+		  is_undef = (blhe->type == bfd_link_hash_undefined);
+		}
+
+	      if (is_cdecl
+		  && (!blhe || (blhe && blhe->type != bfd_link_hash_undefined)))
+		{
+		  sprintf (name, "%s%s",U (""), imp[i].internal_name);
+		  blhe = pe_find_cdecl_alias_match (linfo, name);
+		  include_jmp_stub = true;
+		  if (blhe)
+		    is_undef = (blhe->type == bfd_link_hash_undefined);
+		}
 
-	  free (name);
+	      free (name);
 
-	  if (is_undef)
-	    {
-	      bfd *one;
-	      /* We do.  */
-	      if (!do_this_dll)
+	      if (is_undef)
 		{
-		  bfd *ar_head = make_head (output_bfd);
-		  add_bfd_to_link (ar_head, bfd_get_filename (ar_head), linfo);
-		  do_this_dll = 1;
+		  bfd *one;
+		  /* We do.  */
+		  if (!do_this_dll)
+		    {
+		      bfd *ar_head = make_head (output_bfd);
+		      add_bfd_to_link (ar_head, bfd_get_filename (ar_head),
+				       linfo);
+		      do_this_dll = 1;
+		    }
+		  exp.internal_name = imp[i].internal_name;
+		  exp.name = imp[i].name;
+		  exp.its_name = imp[i].its_name;
+		  exp.ordinal = imp[i].ordinal;
+		  exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0;
+		  exp.flag_private = 0;
+		  exp.flag_constant = 0;
+		  exp.flag_data = imp[i].data;
+		  exp.flag_noname = exp.name ? 0 : 1;
+		  one = make_one (&exp, output_bfd,
+				  !exp.flag_data && include_jmp_stub);
+		  add_bfd_to_link (one, bfd_get_filename (one), linfo);
 		}
-	      exp.internal_name = imp[i].internal_name;
-	      exp.name = imp[i].name;
-	      exp.its_name = imp[i].its_name;
-	      exp.ordinal = imp[i].ordinal;
-	      exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0;
-	      exp.flag_private = 0;
-	      exp.flag_constant = 0;
-	      exp.flag_data = imp[i].data;
-	      exp.flag_noname = exp.name ? 0 : 1;
-	      one = make_one (&exp, output_bfd, (! exp.flag_data) && include_jmp_stub);
-	      add_bfd_to_link (one, bfd_get_filename (one), linfo);
 	    }
+	  if (do_this_dll)
+	    {
+	      bfd *ar_tail = make_tail (output_bfd);
+	      add_bfd_to_link (ar_tail, bfd_get_filename (ar_tail), linfo);
+	    }
+
+	  free (dll_symname);
 	}
-      if (do_this_dll)
+
+      while (undef_count)
 	{
-	  bfd *ar_tail = make_tail (output_bfd);
-	  add_bfd_to_link (ar_tail, bfd_get_filename (ar_tail), linfo);
+	  --undef_count;
+	  free (udef_table[undef_count].key);
 	}
-
-      free (dll_symname);
+      free (udef_table);
     }
 
-  while (undef_count)
+  if (pe_def_file && pe_def_file->name)
+    dll_filename = pe_def_file->name;
+  else
     {
-      --undef_count;
-      free (udef_table[undef_count].key);
+      dll_filename = bfd_get_filename (output_bfd);
+      for (const char *p = dll_filename; *p; p++)
+	if (*p == '\\' || *p == '/' || *p == ':')
+	  dll_filename = p + 1;
     }
-  free (udef_table);
+  dll_symname = xstrdup (dll_filename);
+  for (int i = 0; dll_symname[i]; i++)
+    if (!ISALNUM (dll_symname[i]))
+      dll_symname[i] = '_';
 }
 
 /* We were handed a *.DLL file.  Parse it and turn it into a set of
@@ -3629,7 +3625,7 @@ pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info)
       return;
     }
 
-  generate_edata (abfd, info);
+  generate_edata ();
   build_filler_bfd (1);
   pe_output_file_set_long_section_names (filler_bfd);
 }

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-05-11 12:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-10 17:19 LD: Invalid memory access when linking a dll (maybe Bug 29006 revisited) Roland Schwingel
2022-05-11 12:49 ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).