Index: src/ld/deffile.h =================================================================== --- src.orig/ld/deffile.h 2009-10-22 19:52:34.000000000 +0200 +++ src/ld/deffile.h 2009-10-22 19:49:01.990986700 +0200 @@ -35,6 +35,7 @@ typedef struct def_file_export { char *name; /* always set */ char *internal_name; /* always set, may == name */ + char *its_name; /* optional export table name refered to. */ int ordinal; /* -1 if not specified */ int hint; char flag_private, flag_constant, flag_noname, flag_data, flag_forward; @@ -50,6 +51,7 @@ char *internal_name; /* always set */ def_file_module *module; /* always set */ char *name; /* may be NULL; either this or ordinal will be set */ + char *its_name; /* optional import table name refered to. */ int ordinal; /* may be -1 */ int data; /* = 1 if data */ } def_file_import; @@ -102,9 +104,11 @@ extern def_file *def_file_parse (const char *, def_file *); extern void def_file_free (def_file *); extern def_file_export *def_file_add_export (def_file *, const char *, - const char *, int); + const char *, int, + const char *); extern def_file_import *def_file_add_import (def_file *, const char *, - const char *, int, const char *); + const char *, int, const char *, + const char *); extern void def_file_add_directive (def_file *, const char *, int); extern def_file_module *def_get_module (def_file *, const char *); #ifdef DEF_FILE_PRINT Index: src/ld/deffilep.y =================================================================== --- src.orig/ld/deffilep.y 2009-10-22 19:52:35.000000000 +0200 +++ src/ld/deffilep.y 2009-10-23 12:13:17.113387800 +0200 @@ -79,10 +79,10 @@ #define yycheck def_yycheck static void def_description (const char *); -static void def_exports (const char *, const char *, int, int); +static void def_exports (const char *, const char *, int, int, const char *); static void def_heapsize (int, int); static void def_import (const char *, const char *, const char *, const char *, - int); + int, const char *); static void def_image_name (const char *, int, int); static void def_section (const char *, int); static void def_section_alt (const char *, const char *); @@ -109,7 +109,7 @@ %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL %token PRIVATEU PRIVATEL ALIGNCOMM -%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE +%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL %token ID %token DIGITS %type NUMBER @@ -117,6 +117,7 @@ %type opt_base opt_ordinal %type attr attr_list opt_number exp_opt_list exp_opt %type opt_name opt_equal_name dot_name anylang_id opt_id +%type opt_equalequal_name %% @@ -152,8 +153,8 @@ /* The opt_comma is necessary to support both the usual DEF file syntax as well as .drectve syntax which mandates ,. */ - dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list - { def_exports ($1, $2, $3, $5); } + dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name + { def_exports ($1, $2, $3, $5, $7); } ; exp_opt_list: /* The opt_comma is necessary to support both the usual @@ -178,12 +179,18 @@ ; impline: - ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); } - | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); } - | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); } - | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); } - | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); } - | ID '.' ID { def_import ( 0, $1, 0, $3, -1); } + ID '=' ID '.' ID '.' ID opt_equalequal_name + { def_import ($1, $3, $5, $7, -1, $8); } + | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name + { def_import ($1, $3, $5, 0, $7, $8); } + | ID '=' ID '.' ID opt_equalequal_name + { def_import ($1, $3, 0, $5, -1, $6); } + | ID '=' ID '.' NUMBER opt_equalequal_name + { def_import ($1, $3, 0, 0, $5, $6); } + | ID '.' ID '.' ID opt_equalequal_name + { def_import( 0, $1, $3, $5, -1, $6); } + | ID '.' ID opt_equalequal_name + { def_import ( 0, $1, 0, $3, -1, $4); } ; seclist: @@ -226,6 +233,10 @@ | { $$ = ""; } ; +opt_equalequal_name: EQUAL ID { $$ = $2; } + | { $$ = 0; } + ; + opt_ordinal: '@' NUMBER { $$ = $2;} | { $$ = -1;} @@ -378,6 +389,8 @@ free (def->exports[i].internal_name); if (def->exports[i].name) free (def->exports[i].name); + if (def->exports[i].its_name) + free (def->exports[i].its_name); } free (def->exports); } @@ -391,6 +404,8 @@ free (def->imports[i].internal_name); if (def->imports[i].name) free (def->imports[i].name); + if (def->imports[i].its_name) + free (def->imports[i].its_name); } free (def->imports); } @@ -503,7 +518,8 @@ def_file_add_export (def_file *def, const char *external_name, const char *internal_name, - int ordinal) + int ordinal, + const char *its_name) { def_file_export *e; int max_exports = ROUND_UP(def->num_exports, 32); @@ -525,6 +541,7 @@ internal_name = external_name; e->name = xstrdup (external_name); e->internal_name = xstrdup (internal_name); + e->its_name = (its_name ? xstrdup (its_name) : NULL); e->ordinal = ordinal; def->num_exports++; return e; @@ -562,7 +579,8 @@ const char *name, const char *module, int ordinal, - const char *internal_name) + const char *internal_name, + const char *its_name) { def_file_import *i; int max_imports = ROUND_UP (def->num_imports, 16); @@ -588,6 +606,7 @@ i->internal_name = xstrdup (internal_name); else i->internal_name = i->name; + i->its_name = (its_name ? xstrdup (its_name) : NULL); def->num_imports++; return i; @@ -805,7 +824,8 @@ def_exports (const char *external_name, const char *internal_name, int ordinal, - int flags) + int flags, + const char *its_name) { def_file_export *dfe; @@ -815,7 +835,8 @@ printf ("def_exports, ext=%s int=%s\n", external_name, internal_name); #endif - dfe = def_file_add_export (def, external_name, internal_name, ordinal); + dfe = def_file_add_export (def, external_name, internal_name, ordinal, + its_name); if (flags & 1) dfe->flag_noname = 1; if (flags & 2) @@ -831,7 +852,8 @@ const char *module, const char *dllext, const char *name, - int ordinal) + int ordinal, + const char *its_name) { char *buf = 0; const char *ext = dllext ? dllext : "dll"; @@ -840,7 +862,7 @@ sprintf (buf, "%s.%s", module, ext); module = buf; - def_file_add_import (def, name, module, ordinal, internal_name); + def_file_add_import (def, name, module, ordinal, internal_name, its_name); if (buf) free (buf); } @@ -1102,7 +1124,23 @@ return ID; } - if (c == '=' || c == '.' || c == ',') + if ( c == '=') + { + c = def_getc (); + if (c == '=') + { +#if TRACE + printf ("lex: `==' returns EQUAL\n"); +#endif + return EQUAL; + } + def_ungetc (c); +#if TRACE + printf ("lex: `=' returns itself\n"); +#endif + return '='; + } + if (c == '.' || c == ',') { #if TRACE printf ("lex: `%c' returns itself\n", c); Index: src/ld/pe-dll.c =================================================================== --- src.orig/ld/pe-dll.c 2009-10-22 19:52:35.000000000 +0200 +++ src/ld/pe-dll.c 2009-10-23 11:44:13.269387800 +0200 @@ -442,8 +442,14 @@ { const def_file_export *a = va; const def_file_export *b = vb; + char *an = a->name; + char *bn = b->name; + if (a->its_name) + an = a->its_name; + if (b->its_name) + bn = b->its_name; - return strcmp (a->name, b->name); + return strcmp (an, bn); } /* Read and process the .DEF file. */ @@ -732,7 +738,7 @@ if (auto_export (b, pe_def_file, sn)) { def_file_export *p; - p=def_file_add_export (pe_def_file, sn, 0, -1); + p=def_file_add_export (pe_def_file, sn, 0, -1, NULL); /* Fill data flag properly, from dlltool.c. */ p->flag_data = !(symbols[j]->flags & BSF_FUNCTION); } @@ -788,7 +794,7 @@ if (auto_export (NULL, pe_def_file, tmp)) def_file_add_export (pe_def_file, tmp, pe_def_file->exports[i].internal_name, - -1); + -1, NULL); else free (tmp); } @@ -1049,7 +1055,10 @@ } exported_symbols[ei] = i; } - name_table_size += strlen (pe_def_file->exports[i].name) + 1; + if (pe_def_file->exports[i].its_name) + name_table_size += strlen (pe_def_file->exports[i].its_name) + 1; + else + name_table_size += strlen (pe_def_file->exports[i].name) + 1; } /* Reserve space for the forward name. */ @@ -1195,6 +1204,8 @@ if (!pe_def_file->exports[s].flag_noname) { char *ename = pe_def_file->exports[s].name; + if (pe_def_file->exports[s].its_name) + ename = pe_def_file->exports[s].its_name; bfd_put_32 (abfd, ERVA (enamestr), enameptrs); enameptrs += 4; @@ -1677,6 +1688,12 @@ else fprintf (out, "%d", im->ordinal); + if (im->its_name) + { + fprintf (out, " == "); + quoteput (im->its_name, out, 0); + } + fprintf (out, "\n"); } } @@ -2183,7 +2200,10 @@ else { /* { short, asciz } */ - len = 2 + strlen (exp->name) + 1; + if (exp->its_name) + len = 2 + strlen (exp->its_name) + 1; + else + len = 2 + strlen (exp->name) + 1; if (len & 1) len++; bfd_set_section_size (abfd, id6, len); @@ -2192,7 +2212,10 @@ memset (d6, 0, len); d6[0] = exp->hint & 0xff; d6[1] = exp->hint >> 8; - strcpy ((char *) d6 + 2, exp->name); + if (exp->its_name) + strcpy ((char*) d6 + 2, exp->its_name); + else + strcpy ((char *) d6 + 2, exp->name); } bfd_set_symtab (abfd, symtab, symptr); @@ -2827,6 +2850,7 @@ } exp.internal_name = pe_def_file->imports[i].internal_name; exp.name = pe_def_file->imports[i].name; + exp.its_name = pe_def_file->imports[i].its_name; exp.ordinal = pe_def_file->imports[i].ordinal; exp.hint = exp.ordinal >= 0 ? exp.ordinal : 0; exp.flag_private = 0; @@ -3057,7 +3081,7 @@ || (func_rva >= bss_start && func_rva < bss_end); imp = def_file_add_import (pe_def_file, erva + name_rva, - dll_name, i, 0); + dll_name, i, 0, NULL); /* Mark symbol type. */ imp->data = is_data; Index: src/ld/ld.texinfo =================================================================== --- src.orig/ld/ld.texinfo 2009-10-20 21:13:58.000000000 +0200 +++ src/ld/ld.texinfo 2009-10-23 11:57:38.128387800 +0200 @@ -6672,14 +6672,19 @@ _bar = bar another_foo = abc.dll.afoo var1 DATA +doo = foo == foo2 +eoo DATA == var1 @end example -This example defines a DLL with a non-default base address and five +This example defines a DLL with a non-default base address and seven symbols in the export table. The third exported symbol @code{_bar} is an alias for the second. The fourth symbol, @code{another_foo} is resolved by "forwarding" to another module and treating it as an alias for @code{afoo} exported from the DLL @samp{abc.dll}. The final symbol -@code{var1} is declared to be a data object. +@code{var1} is declared to be a data object. The @samp{doo} symbol in +export library is an alias of @samp{foo}, which gets the string name +in export table @samp{foo2}. The @samp{eoo} symbol is an data export +symbol, which gets in export table the name @samp{var1}. The optional @code{LIBRARY } command indicates the @emph{internal} name of the output DLL. If @samp{} does not include a suffix, @@ -6704,7 +6709,7 @@ EXPORTS ( ( ( [ = ] ) | ( = . )) - [ @@ ] [NONAME] [DATA] [CONSTANT] [PRIVATE] ) * + [ @@ ] [NONAME] [DATA] [CONSTANT] [PRIVATE] [== ] ) * @end example Declares @samp{} as an exported symbol from the DLL, or declares @@ -6712,7 +6717,8 @@ @samp{} as a "forward" alias for the symbol @samp{} in the DLL @samp{}. Optionally, the symbol may be exported by the specified ordinal -@samp{} alias. +@samp{} alias. The optional @samp{} is the to be used +string in import/export table for the symbol. The optional keywords that follow the declaration indicate: