This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH,PE-COFF,PR11603] Allow ld to export symbols containing dots from DLLs.
- From: Dave Korn <dave dot korn dot cygwin at googlemail dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Sat, 15 May 2010 15:06:26 +0100
- Subject: [PATCH,PE-COFF,PR11603] Allow ld to export symbols containing dots from DLLs.
Hi all,
In GCC PR44139(*) - now relocated to sourceware bugzilla as PR 11603(**) -
a failure was reported when exporting emutls symbols from a DLL.
The cause turns out to be the presence of a dot in the exported symbol name
(in this case the name of an emulated tls control variable): this is the
standard syntax in a windows DEF file for declaring a "forwarded export", a
kind of alias by which a DLL may export a function that is actually defined in
a different DLL.
There isn't actually any problem with exporting a symbol that contains a
dot; it's not actually the presence of the dot that causes the run-time loader
to interpret a particular export as a forwarder rather than a normal export,
but where the export table entry points to: if it points to an address that is
inside the export section itself, this means that it is a forwarder and points
to an ASCII string of a forwarded name; an export address that points anywhere
else in the DLL is assumed to be a regular function or data export.
At the moment, when ld sees a dot in the name, it always generates the
forwarder form of export table entry, regardless that there may in fact really
be a matching symbol containing a dot in the DLL in being linked. The simple
solution seemed to me to be that we test for a real defined symbol export
first, before we even consider whether there is a dot in the symbol name or
not; if so, we let it generate a regular export for that symbol.
ld/ChangeLog:
PR ld/11603
* pe-dll.c (process_def_file_and_drectve): Reorder check for
forwarded export name after check for ordinary export.
I'll give this a day or three of testing before I commit it, to give time
for any hiccups to manifest themselves or for anyone who has any comments or
objections to speak up.
cheers,
DaveK
--
(*) - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44139
(**) - http://sourceware.org/bugzilla/show_bug.cgi?id=11603
Index: ld/pe-dll.c
===================================================================
RCS file: /cvs/src/src/ld/pe-dll.c,v
retrieving revision 1.129
diff -p -u -r1.129 pe-dll.c
--- ld/pe-dll.c 28 Apr 2010 15:24:22 -0000 1.129
+++ ld/pe-dll.c 15 May 2010 10:15:40 -0000
@@ -865,28 +865,6 @@ process_def_file_and_drectve (bfd *abfd
for (i = 0; i < NE; i++)
{
char *name;
-
- /* Check for forward exports */
- if (strchr (pe_def_file->exports[i].internal_name, '.'))
- {
- count_exported++;
- if (!pe_def_file->exports[i].flag_noname)
- count_exported_byname++;
-
- pe_def_file->exports[i].flag_forward = 1;
-
- if (pe_def_file->exports[i].ordinal != -1)
- {
- if (max_ordinal < pe_def_file->exports[i].ordinal)
- max_ordinal = pe_def_file->exports[i].ordinal;
- if (min_ordinal > pe_def_file->exports[i].ordinal)
- min_ordinal = pe_def_file->exports[i].ordinal;
- count_with_ordinals++;
- }
-
- continue;
- }
-
name = xmalloc (strlen (pe_def_file->exports[i].internal_name) + 2);
if (pe_details->underscored
&& (*pe_def_file->exports[i].internal_name != '@'))
@@ -926,6 +904,28 @@ process_def_file_and_drectve (bfd *abfd
count_with_ordinals++;
}
}
+ /* Check for forward exports. These are indicated in DEF files by an
+ export directive of the form NAME1 = MODULE-NAME.EXTERNAL-NAME
+ but we must take care not to be fooled when the user wants to export
+ a symbol that actually really has a dot in it, so we only check
+ for them here, after real defined symbols have already been matched. */
+ else if (strchr (pe_def_file->exports[i].internal_name, '.'))
+ {
+ count_exported++;
+ if (!pe_def_file->exports[i].flag_noname)
+ count_exported_byname++;
+
+ pe_def_file->exports[i].flag_forward = 1;
+
+ if (pe_def_file->exports[i].ordinal != -1)
+ {
+ if (max_ordinal < pe_def_file->exports[i].ordinal)
+ max_ordinal = pe_def_file->exports[i].ordinal;
+ if (min_ordinal > pe_def_file->exports[i].ordinal)
+ min_ordinal = pe_def_file->exports[i].ordinal;
+ count_with_ordinals++;
+ }
+ }
else if (blhe && blhe->type == bfd_link_hash_undefined)
{
/* xgettext:c-format */