2009-10-23 Kai Tietz <kai.tietz@onevision.com>
authorKai Tietz <kai.tietz@onevision.com>
Fri, 23 Oct 2009 11:40:17 +0000 (11:40 +0000)
committerKai Tietz <kai.tietz@onevision.com>
Fri, 23 Oct 2009 11:40:17 +0000 (11:40 +0000)
* 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
ld/NEWS
ld/deffile.h
ld/deffilep.y
ld/ld.texinfo
ld/pe-dll.c

index ce25b055fb2e5d4e7b48b68879cf6b26b435dfb5..250ec27aaa71c56f23053582c18efcb9e6673ed2 100644 (file)
@@ -1,3 +1,28 @@
+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
diff --git a/ld/NEWS b/ld/NEWS
index 76b674972c01b4788b8c73b2b622a0e4328679c8..10a4ed39c33a8d23272288ab2b7adbab0415ccdf 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
 -*- 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.
 
index d3354b1a12ca8ab2b2a8e1ba1337e0e1062b9667..8ddd070e2151c72347e90eb40505d889c551a5f3 100644 (file)
@@ -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
index 706ad374d032519cbbb38ef369daa5e94450394d..672c18674a1ec1441233e72bfd28363c844b0906 100644 (file)
 #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> ID
 %token <digits> DIGITS
 %type  <number> NUMBER
@@ -117,6 +117,7 @@ static const char *lex_parse_string_end = 0;
 %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
 
 %%
 
@@ -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 <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
@@ -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);
index 4899d613d59454cd31f3b4b6f663fcbcb4f2c64f..9e9d1f164c4f6a491886cd2860e3d42ab30bc219 100644 (file)
@@ -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 <name>} command indicates the @emph{internal}
 name of the output DLL. If @samp{<name>} does not include a suffix,
@@ -6704,7 +6709,7 @@ The complete specification of an export symbol is:
 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
@@ -6712,7 +6717,8 @@ 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:
 
index ce5d6a39fbbf622fefe7e8ee5fb35d26634b5c0c..dbf1b5e467e59ef64eb92b3eb123fc9f7491d4ab 100644 (file)
@@ -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;