* 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 <kai.tietz@onevision.com>
+
+ * 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 <kai.tietz@onevision.com>
* deffilep.y (def_lex): Allow '<' and '>' characters in identifier
-*- text -*-
+* Extend .def file syntax by '== <ID>' 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.
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;
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;
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
#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 *);
%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> ID
%token <digits> DIGITS
%type <number> NUMBER
%type <number> opt_base opt_ordinal
%type <number> attr attr_list opt_number exp_opt_list exp_opt
%type <id> opt_name opt_equal_name dot_name anylang_id opt_id
+%type <id> opt_equalequal_name
%%
/* The opt_comma is necessary to support both the usual
DEF file syntax as well as .drectve syntax which
mandates <expsym>,<expoptlist>. */
- 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
;
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:
| { $$ = ""; }
;
+opt_equalequal_name: EQUAL ID { $$ = $2; }
+ | { $$ = 0; }
+ ;
+
opt_ordinal:
'@' NUMBER { $$ = $2;}
| { $$ = -1;}
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);
}
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);
}
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);
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;
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);
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;
def_exports (const char *external_name,
const char *internal_name,
int ordinal,
- int flags)
+ int flags,
+ const char *its_name)
{
def_file_export *dfe;
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)
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";
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);
}
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);
_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 <name>} command indicates the @emph{internal}
name of the output DLL. If @samp{<name>} does not include a suffix,
EXPORTS
( ( ( <name1> [ = <name2> ] )
| ( <name1> = <module-name> . <external-name>))
- [ @@ <integer> ] [NONAME] [DATA] [CONSTANT] [PRIVATE] ) *
+ [ @@ <integer> ] [NONAME] [DATA] [CONSTANT] [PRIVATE] [== <name3>] ) *
@end example
Declares @samp{<name1>} as an exported symbol from the DLL, or declares
@samp{<name1>} as a "forward" alias for the symbol
@samp{<external-name>} in the DLL @samp{<module-name>}.
Optionally, the symbol may be exported by the specified ordinal
-@samp{<integer>} alias.
+@samp{<integer>} alias. The optional @samp{<name3>} is the to be used
+string in import/export table for the symbol.
The optional keywords that follow the declaration indicate:
{
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. */
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);
}
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);
}
}
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. */
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;
else
fprintf (out, "%d", im->ordinal);
+ if (im->its_name)
+ {
+ fprintf (out, " == ");
+ quoteput (im->its_name, out, 0);
+ }
+
fprintf (out, "\n");
}
}
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);
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);
}
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;
|| (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;