[PATCH] ld: pe-dll: Fix MS link.exe linking against two ld generated import libraries
Martin Storsjö
martin@martin.st
Tue Jan 4 20:14:25 GMT 2022
MS link.exe can successfully link against import libraries generated
by ld (via the --out-implib option). However, if linking against more
than one such import library at a time, then MS link.exe produces
intermixed import tables for those DLL files.
MS link.exe seems to sort the individual object files in the import
library based on their member names, without taking library
boundaries into consideration. E.g. when both libfoo.a and libbar.a
contain object files named d000.o, d001.o, d002.o, MS link.exe orders
them as libfoo.a(d000.o) libbar.a(d000.o) libfoo.a(d001.o) libbar.a(d001.o)
etc. This breaks the implicit assumption that these object files need
to be grouped tightly together within one import library.
This has not been an issue when MS link.exe links against import
libraries produced by dlltool, as the object files there use a
pseudorandom prefix (based on the dlltool process ID).
Thus this avoids needing to regenerate import libraries with dlltool, if
linking a DLL which is going to be linked against by MS link.exe.
Signed-off-by: Martin Storsjö <martin@martin.st>
---
ld/pe-dll.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 907fafc6208..4e47abd9b24 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1972,6 +1972,7 @@ 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
@@ -2082,8 +2083,8 @@ make_head (bfd *parent)
char *oname;
bfd *abfd;
- oname = xmalloc (20);
- sprintf (oname, "d%06d.o", tmp_seq);
+ oname = xmalloc (20 + dll_symname_len);
+ sprintf (oname, "%s_d%06d.o", dll_symname, tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2171,8 +2172,8 @@ make_tail (bfd *parent)
char *oname;
bfd *abfd;
- oname = xmalloc (20);
- sprintf (oname, "d%06d.o", tmp_seq);
+ oname = xmalloc (20 + dll_symname_len);
+ sprintf (oname, "%s_d%06d.o", dll_symname, tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2322,8 +2323,8 @@ make_one (def_file_export *exp, bfd *parent, bool include_jmp_stub)
}
}
- oname = xmalloc (20);
- sprintf (oname, "d%06d.o", tmp_seq);
+ oname = xmalloc (20 + dll_symname_len);
+ sprintf (oname, "%s_d%06d.o", dll_symname, tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2508,8 +2509,8 @@ make_singleton_name_thunk (const char *import, bfd *parent)
char *oname;
bfd *abfd;
- oname = xmalloc (20);
- sprintf (oname, "nmth%06d.o", tmp_seq);
+ oname = xmalloc (20 + dll_symname_len);
+ sprintf (oname, "%s_nmth%06d.o", dll_symname, tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2584,8 +2585,8 @@ make_import_fixup_entry (const char *name,
char *oname;
bfd *abfd;
- oname = xmalloc (20);
- sprintf (oname, "fu%06d.o", tmp_seq);
+ oname = xmalloc (20 + dll_symname_len);
+ sprintf (oname, "%s_fu%06d.o", dll_symname, tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2638,8 +2639,8 @@ make_runtime_pseudo_reloc (const char *name ATTRIBUTE_UNUSED,
bfd *abfd;
bfd_size_type size;
- oname = xmalloc (20);
- sprintf (oname, "rtr%06d.o", tmp_seq);
+ oname = xmalloc (20 + dll_symname_len);
+ sprintf (oname, "%s_rtr%06d.o", dll_symname, tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2725,8 +2726,8 @@ pe_create_runtime_relocator_reference (bfd *parent)
char *oname;
bfd *abfd;
- oname = xmalloc (20);
- sprintf (oname, "ertr%06d.o", tmp_seq);
+ oname = xmalloc (20 + dll_symname_len);
+ sprintf (oname, "%s_ertr%06d.o", dll_symname, tmp_seq);
tmp_seq++;
abfd = bfd_create (oname, parent);
@@ -2833,6 +2834,7 @@ pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_
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] = '_';
@@ -3201,6 +3203,7 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *linfo)
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] = '_';
--
2.25.1
More information about the Binutils
mailing list