From 491cc40d3acf5c236f4acb8fcbfa535f46ed47b3 Mon Sep 17 00:00:00 2001 From: Kai Tietz Date: Fri, 23 Oct 2009 11:40:16 +0000 Subject: [PATCH] 2009-10-23 Kai Tietz * deffile.h (def_file_export): New member its_name. (def_file_import): Likewise. (def_file_add_export): Add argument its_name. (def_file_add_import): Likewise. * deffilep.y (def_exports): Add argument its_name. (def_import): Likewise. (EQUAL): Add new token for '=='. (opt_equalequal_name): New rule. (expline): Add rule opt_equalequal_name. (impline): Likewise. (def_file_free): Free for exports and imports the optional member its_name. (def_lex): Add scan of '==' as EQUAL. * pe-dll.c (pe_export_sort): Sort for its_name too. (process_def_file_and_drectve): Adjust calls to def_file_add_export. (generate_edata): Take its_name in account. (make_one): Likewise. (pe_process_import_defs): Likewise. (pe_dll_generate_def_file): Add print of new '==' option. * ld.texinfo: Extend documentation about .def file syntax. * NEWS: Mention new feature. --- ld/ChangeLog | 25 ++++++++++++++++++++ ld/NEWS | 3 +++ ld/deffile.h | 8 +++++-- ld/deffilep.y | 74 ++++++++++++++++++++++++++++++++++++++++++++--------------- ld/ld.texinfo | 14 +++++++---- ld/pe-dll.c | 40 +++++++++++++++++++++++++------- 6 files changed, 132 insertions(+), 32 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index ce25b055f..250ec27aa 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,30 @@ 2009-10-23 Kai Tietz + * deffile.h (def_file_export): New member its_name. + (def_file_import): Likewise. + (def_file_add_export): Add argument its_name. + (def_file_add_import): Likewise. + * deffilep.y (def_exports): Add argument its_name. + (def_import): Likewise. + (EQUAL): Add new token for '=='. + (opt_equalequal_name): New rule. + (expline): Add rule opt_equalequal_name. + (impline): Likewise. + (def_file_free): Free for exports and imports + the optional member its_name. + (def_lex): Add scan of '==' as EQUAL. + * pe-dll.c (pe_export_sort): Sort for its_name too. + (process_def_file_and_drectve): Adjust calls to + def_file_add_export. + (generate_edata): Take its_name in account. + (make_one): Likewise. + (pe_process_import_defs): Likewise. + (pe_dll_generate_def_file): Add print of new '==' option. + * ld.texinfo: Extend documentation about .def file syntax. + * NEWS: Mention new feature. + +2009-10-23 Kai Tietz + * deffilep.y (def_lex): Allow '<' and '>' characters in identifier strings. diff --git a/ld/NEWS b/ld/NEWS index 76b674972..10a4ed39c 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Extend .def file syntax by '== ' for imports and exports. This allows + to alias the import/export table name written in PE image. + * Add --exlcude-all-symbols option to PE based linkers. This prevents all symbols from automatically being exported. diff --git a/ld/deffile.h b/ld/deffile.h index d3354b1a1..8ddd070e2 100644 --- a/ld/deffile.h +++ b/ld/deffile.h @@ -35,6 +35,7 @@ typedef struct def_file_section { 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 @@ typedef struct def_file_import { 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_empty (void); 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 diff --git a/ld/deffilep.y b/ld/deffilep.y index 706ad374d..672c18674 100644 --- a/ld/deffilep.y +++ b/ld/deffilep.y @@ -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 @@ static const char *lex_parse_string_end = 0; %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 @@ static const char *lex_parse_string_end = 0; %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 @@ expline: /* 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 @@ implist: ; 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_name: ID { $$ = $1; } | { $$ = ""; } ; +opt_equalequal_name: EQUAL ID { $$ = $2; } + | { $$ = 0; } + ; + opt_ordinal: '@' NUMBER { $$ = $2;} | { $$ = -1;} @@ -378,6 +389,8 @@ def_file_free (def_file *def) 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 @@ def_file_free (def_file *def) 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_export * 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 @@ def_file_add_export (def_file *def, 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 @@ def_file_add_import (def_file *def, 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 @@ def_file_add_import (def_file *def, 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 @@ static void 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 @@ def_exports (const char *external_name, 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 @@ def_import (const char *internal_name, 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 @@ def_import (const char *internal_name, 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 @@ def_lex (void) 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); diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 4899d613d..9e9d1f164 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -6672,14 +6672,19 @@ bar _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 @@ The complete specification of an export symbol is: 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 @@ Declares @samp{} as an exported symbol from the DLL, or declares @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: diff --git a/ld/pe-dll.c b/ld/pe-dll.c index ce5d6a39f..dbf1b5e46 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -442,8 +442,14 @@ pe_export_sort (const void *va, const void *vb) { const def_file_export *a = va; const def_file_export *b = vb; - - return strcmp (a->name, b->name); + 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 (an, bn); } /* Read and process the .DEF file. */ @@ -732,7 +738,7 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info * 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 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info * 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 @@ generate_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) } 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 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) 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 @@ pe_dll_generate_def_file (const char *pe_out_def_filename) 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 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) 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 @@ make_one (def_file_export *exp, bfd *parent, bfd_boolean include_jmp_stub) 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 @@ pe_process_import_defs (bfd *output_bfd, struct bfd_link_info *link_info) } 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 @@ pe_implied_import_dll (const char *filename) || (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; -- 2.11.4.GIT