* dlltool.c (make_one_lib): Test if internal_name was specified
[platform/upstream/binutils.git] / binutils / dlltool.c
index 19a7e1f..c9a6738 100644 (file)
@@ -1,5 +1,5 @@
 /* dlltool.c -- tool to generate stuff for PE style DLLs
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -49,7 +49,7 @@
 
    EXPORTS  ( (  ( <name1> [ = <name2> ] )
                | ( <name1> = <module-name> . <external-name>))
-            [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
+            [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) *
    Declares name1 as an exported symbol from the
    DLL, with optional ordinal number <integer>.
    Or declares name1 as an alias (forward) of the function <external-name>
@@ -60,7 +60,7 @@
    Declares that <external-name> or the exported function whoes ordinal number
    is <integer> is to be imported from the file <module-name>.  If
    <internal-name> is specified then this is the name that the imported
-   function will be refered to in the body of the DLL.
+   function will be refereed to in the body of the DLL.
 
    DESCRIPTION <string>
    Puts <string> into output .exp file in the .rdata section
 #endif
 
 /* Forward references.  */
-static char *look_for_prog
-  PARAMS ((const char *, const char *, int));
-static char *deduce_name
-  PARAMS ((const char *));
+static char *look_for_prog (const char *, const char *, int);
+static char *deduce_name (const char *);
 
 #ifdef DLLTOOL_MCORE_ELF
-static void mcore_elf_cache_filename
-  PARAMS ((char *));
-static void mcore_elf_gen_out_file
-  PARAMS ((void));
+static void mcore_elf_cache_filename (char *);
+static void mcore_elf_gen_out_file (void);
 #endif
 
 #ifdef HAVE_SYS_WAIT_H
@@ -350,6 +346,8 @@ static iheadtype *import_list = NULL;
 static char *as_name = NULL;
 static char * as_flags = "";
 
+static char *tmp_prefix;
+
 static int no_idata4;
 static int no_idata5;
 static char *exp_name;
@@ -384,6 +382,7 @@ extern char * program_name;
 static int machine;
 static int killat;
 static int add_stdcall_alias;
+static const char *ext_prefix_alias;
 static int verbose;
 static FILE *output_def;
 static FILE *base_file;
@@ -431,14 +430,21 @@ static char * mcore_elf_linker_flags = NULL;
 
 #define PATHMAX 250            /* What's the right name for this ?  */
 
-#define TMP_ASM                "dc.s"
-#define TMP_HEAD_S     "dh.s"
-#define TMP_HEAD_O     "dh.o"
-#define TMP_TAIL_S     "dt.s"
-#define TMP_TAIL_O     "dt.o"
-#define TMP_STUB       "ds"
-
-/* This bit of assemly does jmp * ....  */
+char *tmp_asm_buf;
+char *tmp_head_s_buf;
+char *tmp_head_o_buf;
+char *tmp_tail_s_buf;
+char *tmp_tail_o_buf;
+char *tmp_stub_buf;
+
+#define TMP_ASM                dlltmp (&tmp_asm_buf, "%sc.s")
+#define TMP_HEAD_S     dlltmp (&tmp_head_s_buf, "%sh.s")
+#define TMP_HEAD_O     dlltmp (&tmp_head_o_buf, "%sh.o")
+#define TMP_TAIL_S     dlltmp (&tmp_tail_s_buf, "%st.s")
+#define TMP_TAIL_O     dlltmp (&tmp_tail_o_buf, "%st.o")
+#define TMP_STUB       dlltmp (&tmp_stub_buf, "%ss")
+
+/* This bit of assembly does jmp * ....  */
 static const unsigned char i386_jtab[] =
 {
   0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
@@ -638,7 +644,8 @@ typedef struct export
     const char *internal_name;
     int ordinal;
     int constant;
-    int noname;
+    int noname;                /* Don't put name in image file.  */
+    int private;       /* Don't put reference in import lib.  */
     int data;
     int hint;
     int forward;       /* Number of forward label, 0 means no forward.  */
@@ -656,91 +663,75 @@ struct string_list
 
 static struct string_list *excludes;
 
-static const char *rvaafter
-  PARAMS ((int));
-static const char *rvabefore
-  PARAMS ((int));
-static const char *asm_prefix
-  PARAMS ((int));
-static void process_def_file
-  PARAMS ((const char *));
-static void new_directive
-  PARAMS ((char *));
-static void append_import
-  PARAMS ((const char *, const char *, int));
-static void run
-  PARAMS ((const char *, char *));
-static void scan_drectve_symbols
-  PARAMS ((bfd *));
-static void scan_filtered_symbols
-  PARAMS ((bfd *, PTR, long, unsigned int));
-static void add_excludes
-  PARAMS ((const char *));
-static bfd_boolean match_exclude
-  PARAMS ((const char *));
-static void set_default_excludes
-  PARAMS ((void));
-static long filter_symbols
-  PARAMS ((bfd *, PTR, long, unsigned int));
-static void scan_all_symbols
-  PARAMS ((bfd *));
-static void scan_open_obj_file
-  PARAMS ((bfd *));
-static void scan_obj_file
-  PARAMS ((const char *));
-static void dump_def_info
-  PARAMS ((FILE *));
-static int sfunc
-  PARAMS ((const void *, const void *));
-static void flush_page
-  PARAMS ((FILE *, long *, int, int));
-static void gen_def_file
-  PARAMS ((void));
-static void generate_idata_ofile
-  PARAMS ((FILE *));
-static void assemble_file
-  PARAMS ((const char *, const char *));
-static void gen_exp_file
-  PARAMS ((void));
-static const char *xlate
-  PARAMS ((const char *));
+static const char *rvaafter (int);
+static const char *rvabefore (int);
+static const char *asm_prefix (int, const char *);
+static void process_def_file (const char *);
+static void new_directive (char *);
+static void append_import (const char *, const char *, int);
+static void run (const char *, char *);
+static void scan_drectve_symbols (bfd *);
+static void scan_filtered_symbols (bfd *, void *, long, unsigned int);
+static void add_excludes (const char *);
+static bfd_boolean match_exclude (const char *);
+static void set_default_excludes (void);
+static long filter_symbols (bfd *, void *, long, unsigned int);
+static void scan_all_symbols (bfd *);
+static void scan_open_obj_file (bfd *);
+static void scan_obj_file (const char *);
+static void dump_def_info (FILE *);
+static int sfunc (const void *, const void *);
+static void flush_page (FILE *, long *, int, int);
+static void gen_def_file (void);
+static void generate_idata_ofile (FILE *);
+static void assemble_file (const char *, const char *);
+static void gen_exp_file (void);
+static const char *xlate (const char *);
 #if 0
-static void dump_iat
-  PARAMS ((FILE *, export_type *));
+static void dump_iat (FILE *, export_type *);
 #endif
-static char *make_label
-  PARAMS ((const char *, const char *));
-static char *make_imp_label
-  PARAMS ((const char *, const char *));
-static bfd *make_one_lib_file
-  PARAMS ((export_type *, int));
-static bfd *make_head
-  PARAMS ((void));
-static bfd *make_tail
-  PARAMS ((void));
-static void gen_lib_file
-  PARAMS ((void));
-static int pfunc
-  PARAMS ((const void *, const void *));
-static int nfunc
-  PARAMS ((const void *, const void *));
-static void remove_null_names
-  PARAMS ((export_type **));
-static void dtab
-  PARAMS ((export_type **));
-static void process_duplicates
-  PARAMS ((export_type **));
-static void fill_ordinals
-  PARAMS ((export_type **));
-static int alphafunc
-  PARAMS ((const void *, const void *));
-static void mangle_defs
-  PARAMS ((void));
-static void usage
-  PARAMS ((FILE *, int));
-static void inform
-  PARAMS ((const char *, ...));
+static char *make_label (const char *, const char *);
+static char *make_imp_label (const char *, const char *);
+static bfd *make_one_lib_file (export_type *, int);
+static bfd *make_head (void);
+static bfd *make_tail (void);
+static void gen_lib_file (void);
+static int pfunc (const void *, const void *);
+static int nfunc (const void *, const void *);
+static void remove_null_names (export_type **);
+static void dtab (export_type **);
+static void process_duplicates (export_type **);
+static void fill_ordinals (export_type **);
+static int alphafunc (const void *, const void *);
+static void mangle_defs (void);
+static void usage (FILE *, int);
+static void inform (const char *, ...);
 
+static char *
+prefix_encode (char *start, unsigned code)
+{
+  static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
+  static char buf[32];
+  char *p;
+  strcpy (buf, start);
+  p = strchr (buf, '\0');
+  do
+    *p++ = alpha[code % sizeof (alpha)];
+  while ((code /= sizeof (alpha)) != 0);
+  *p = '\0';
+  return buf;
+}
+
+static char *
+dlltmp (char **buf, const char *fmt)
+{
+  if (!*buf)
+    {
+      *buf = malloc (strlen (tmp_prefix) + 64);
+      sprintf (*buf, fmt, tmp_prefix);
+    }
+  return *buf;
+}
 
 static void
 inform VPARAMS ((const char * message, ...))
@@ -757,8 +748,7 @@ inform VPARAMS ((const char * message, ...))
 }
 
 static const char *
-rvaafter (machine)
-     int machine;
+rvaafter (int machine)
 {
   switch (machine)
     {
@@ -782,8 +772,7 @@ rvaafter (machine)
 }
 
 static const char *
-rvabefore (machine)
-     int machine;
+rvabefore (int machine)
 {
   switch (machine)
     {
@@ -807,8 +796,7 @@ rvabefore (machine)
 }
 
 static const char *
-asm_prefix (machine)
-     int machine;
+asm_prefix (int machine, const char *name)
 {
   switch (machine)
     {
@@ -823,7 +811,11 @@ asm_prefix (machine)
     case MARM_EPOC:
       break;
     case M386:
-      return "_";
+      /* Symbol names starting with ? do not have a leading underscore. */
+      if (name && *name == '?')
+        break;
+      else
+        return "_";
     default:
       /* xgettext:c-format */
       fatal (_("Internal error: Unknown machine type: %d"), machine);
@@ -832,32 +824,31 @@ asm_prefix (machine)
   return "";
 }
 
-#define ASM_BYTE       mtable[machine].how_byte
-#define ASM_SHORT      mtable[machine].how_short
-#define ASM_LONG       mtable[machine].how_long
-#define ASM_TEXT       mtable[machine].how_asciz
-#define ASM_C          mtable[machine].how_comment
-#define ASM_JUMP       mtable[machine].how_jump
-#define ASM_GLOBAL     mtable[machine].how_global
-#define ASM_SPACE      mtable[machine].how_space
-#define ASM_ALIGN_SHORT mtable[machine].how_align_short
-#define ASM_RVA_BEFORE         rvabefore(machine)
-#define ASM_RVA_AFTER          rvaafter(machine)
-#define ASM_PREFIX     asm_prefix(machine)
-#define ASM_ALIGN_LONG  mtable[machine].how_align_long
-#define HOW_BFD_READ_TARGET  0  /* always default*/
-#define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
-#define HOW_BFD_ARCH    mtable[machine].how_bfd_arch
-#define HOW_JTAB        mtable[machine].how_jtab
-#define HOW_JTAB_SIZE   mtable[machine].how_jtab_size
-#define HOW_JTAB_ROFF   mtable[machine].how_jtab_roff
-#define ASM_SWITCHES    mtable[machine].how_default_as_switches
+#define ASM_BYTE               mtable[machine].how_byte
+#define ASM_SHORT              mtable[machine].how_short
+#define ASM_LONG               mtable[machine].how_long
+#define ASM_TEXT               mtable[machine].how_asciz
+#define ASM_C                  mtable[machine].how_comment
+#define ASM_JUMP               mtable[machine].how_jump
+#define ASM_GLOBAL             mtable[machine].how_global
+#define ASM_SPACE              mtable[machine].how_space
+#define ASM_ALIGN_SHORT                mtable[machine].how_align_short
+#define ASM_RVA_BEFORE         rvabefore (machine)
+#define ASM_RVA_AFTER          rvaafter (machine)
+#define ASM_PREFIX(NAME)       asm_prefix (machine, (NAME))
+#define ASM_ALIGN_LONG         mtable[machine].how_align_long
+#define HOW_BFD_READ_TARGET    0  /* Always default.  */
+#define HOW_BFD_WRITE_TARGET   mtable[machine].how_bfd_target
+#define HOW_BFD_ARCH           mtable[machine].how_bfd_arch
+#define HOW_JTAB               mtable[machine].how_jtab
+#define HOW_JTAB_SIZE          mtable[machine].how_jtab_size
+#define HOW_JTAB_ROFF          mtable[machine].how_jtab_roff
+#define ASM_SWITCHES           mtable[machine].how_default_as_switches
 
 static char **oav;
 
 static void
-process_def_file (name)
-     const char *name;
+process_def_file (const char *name)
 {
   FILE *f = fopen (name, FOPEN_RT);
 
@@ -894,8 +885,7 @@ static int d_is_dll;
 static int d_is_exe;
 
 int
-yyerror (err)
-     const char * err ATTRIBUTE_UNUSED;
+yyerror (const char * err ATTRIBUTE_UNUSED)
 {
   /* xgettext:c-format */
   non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber);
@@ -904,13 +894,8 @@ yyerror (err)
 }
 
 void
-def_exports (name, internal_name, ordinal, noname, constant, data)
-     const char *name;
-     const char *internal_name;
-     int ordinal;
-     int noname;
-     int constant;
-     int data;
+def_exports (const char *name, const char *internal_name, int ordinal,
+            int noname, int constant, int data, int private)
 {
   struct export *p = (struct export *) xmalloc (sizeof (*p));
 
@@ -919,6 +904,7 @@ def_exports (name, internal_name, ordinal, noname, constant, data)
   p->ordinal = ordinal;
   p->constant = constant;
   p->noname = noname;
+  p->private = private;
   p->data = data;
   p->next = d_exports;
   d_exports = p;
@@ -932,9 +918,7 @@ def_exports (name, internal_name, ordinal, noname, constant, data)
 }
 
 void
-def_name (name, base)
-     const char *name;
-     int base;
+def_name (const char *name, int base)
 {
   /* xgettext:c-format */
   inform (_("NAME: %s base: %x"), name, base);
@@ -951,9 +935,7 @@ def_name (name, base)
 }
 
 void
-def_library (name, base)
-     const char *name;
-     int base;
+def_library (const char *name, int base)
 {
   /* xgettext:c-format */
   inform (_("LIBRARY: %s base: %x"), name, base);
@@ -969,8 +951,7 @@ def_library (name, base)
 }
 
 void
-def_description (desc)
-     const char *desc;
+def_description (const char *desc)
 {
   dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
   d->text = xstrdup (desc);
@@ -979,8 +960,7 @@ def_description (desc)
 }
 
 static void
-new_directive (dir)
-     char *dir;
+new_directive (char *dir)
 {
   dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
   d->text = xstrdup (dir);
@@ -989,9 +969,7 @@ new_directive (dir)
 }
 
 void
-def_heapsize (reserve, commit)
-     int reserve;
-     int commit;
+def_heapsize (int reserve, int commit)
 {
   char b[200];
   if (commit > 0)
@@ -1002,9 +980,7 @@ def_heapsize (reserve, commit)
 }
 
 void
-def_stacksize (reserve, commit)
-     int reserve;
-     int commit;
+def_stacksize (int reserve, int commit)
 {
   char b[200];
   if (commit > 0)
@@ -1018,10 +994,7 @@ def_stacksize (reserve, commit)
    import_list.  It is used by def_import.  */
 
 static void
-append_import (symbol_name, dll_name, func_ordinal)
-     const char *symbol_name;
-     const char *dll_name;
-     int func_ordinal;
+append_import (const char *symbol_name, const char *dll_name, int func_ordinal)
 {
   iheadtype **pq;
   iheadtype *q;
@@ -1085,12 +1058,8 @@ append_import (symbol_name, dll_name, func_ordinal)
              present (i.e., not NULL).  */
 
 void
-def_import (app_name, module, dllext, entry, ord_val)
-     const char *app_name;
-     const char *module;
-     const char *dllext;
-     const char *entry;
-     int ord_val;
+def_import (const char *app_name, const char *module, const char *dllext,
+           const char *entry, int ord_val)
 {
   const char *application_name;
   char *buf;
@@ -1116,17 +1085,13 @@ def_import (app_name, module, dllext, entry, ord_val)
 }
 
 void
-def_version (major, minor)
-     int major;
-     int minor;
+def_version (int major, int minor)
 {
   printf ("VERSION %d.%d\n", major, minor);
 }
 
 void
-def_section (name, attr)
-     const char *name;
-     int attr;
+def_section (const char *name, int attr)
 {
   char buf[200];
   char atts[5];
@@ -1146,16 +1111,14 @@ def_section (name, attr)
 }
 
 void
-def_code (attr)
-     int attr;
+def_code (int attr)
 {
 
   def_section ("CODE", attr);
 }
 
 void
-def_data (attr)
-     int attr;
+def_data (int attr)
 {
   def_section ("DATA", attr);
 }
@@ -1163,9 +1126,7 @@ def_data (attr)
 /**********************************************************************/
 
 static void
-run (what, args)
-     const char *what;
-     char *args;
+run (const char *what, char *args)
 {
   char *s;
   int pid, wait_status;
@@ -1236,8 +1197,7 @@ run (what, args)
    ABFD.  Pass each one to def_exports.  */
 
 static void
-scan_drectve_symbols (abfd)
-     bfd *abfd;
+scan_drectve_symbols (bfd *abfd)
 {
   asection * s;
   int        size;
@@ -1251,7 +1211,7 @@ scan_drectve_symbols (abfd)
   if (s == NULL)
     return;
 
-  size = bfd_get_section_size_before_reloc (s);
+  size = bfd_get_section_size (s);
   buf  = xmalloc (size);
 
   bfd_get_section_contents (abfd, s, buf, 0, size);
@@ -1293,7 +1253,7 @@ scan_drectve_symbols (abfd)
          /* FIXME: The 5th arg is for the `constant' field.
             What should it be?  Not that it matters since it's not
             currently useful.  */
-         def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION));
+         def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0);
 
          if (add_stdcall_alias && strchr (c, '@'))
            {
@@ -1302,7 +1262,7 @@ scan_drectve_symbols (abfd)
              char *atsym = strchr (exported_name, '@');
              *atsym = '\0';
              /* Note: stdcall alias symbols can never be data.  */
-             def_exports (exported_name, xstrdup (c), -1, 0, 0, 0);
+             def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0);
            }
        }
       else
@@ -1315,11 +1275,8 @@ scan_drectve_symbols (abfd)
    symbols to export.  */
 
 static void
-scan_filtered_symbols (abfd, minisyms, symcount, size)
-     bfd *abfd;
-     PTR minisyms;
-     long symcount;
-     unsigned int size;
+scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount,
+                      unsigned int size)
 {
   asymbol *store;
   bfd_byte *from, *fromend;
@@ -1344,7 +1301,7 @@ scan_filtered_symbols (abfd, minisyms, symcount, size)
        ++symbol_name;
 
       def_exports (xstrdup (symbol_name) , 0, -1, 0, 0,
-                  ! (sym->flags & BSF_FUNCTION));
+                  ! (sym->flags & BSF_FUNCTION), 0);
 
       if (add_stdcall_alias && strchr (symbol_name, '@'))
         {
@@ -1353,7 +1310,7 @@ scan_filtered_symbols (abfd, minisyms, symcount, size)
          char *atsym = strchr (exported_name, '@');
          *atsym = '\0';
          /* Note: stdcall alias symbols can never be data.  */
-         def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0);
+         def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0);
        }
     }
 }
@@ -1361,8 +1318,7 @@ scan_filtered_symbols (abfd, minisyms, symcount, size)
 /* Add a list of symbols to exclude.  */
 
 static void
-add_excludes (new_excludes)
-     const char *new_excludes;
+add_excludes (const char *new_excludes)
 {
   char *local_copy;
   char *exclude_string;
@@ -1395,8 +1351,7 @@ add_excludes (new_excludes)
 /* See if STRING is on the list of symbols to exclude.  */
 
 static bfd_boolean
-match_exclude (string)
-     const char *string;
+match_exclude (const char *string)
 {
   struct string_list *excl_item;
 
@@ -1417,11 +1372,7 @@ set_default_excludes (void)
 /* Choose which symbols to export.  */
 
 static long
-filter_symbols (abfd, minisyms, symcount, size)
-     bfd *abfd;
-     PTR minisyms;
-     long symcount;
-     unsigned int size;
+filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size)
 {
   bfd_byte *from, *fromend, *to;
   asymbol *store;
@@ -1439,7 +1390,7 @@ filter_symbols (abfd, minisyms, symcount, size)
       int keep = 0;
       asymbol *sym;
 
-      sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const PTR) from, store);
+      sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store);
       if (sym == NULL)
        bfd_fatal (bfd_get_filename (abfd));
 
@@ -1465,11 +1416,10 @@ filter_symbols (abfd, minisyms, symcount, size)
    export.  */
 
 static void
-scan_all_symbols (abfd)
-     bfd *abfd;
+scan_all_symbols (bfd *abfd)
 {
   long symcount;
-  PTR minisyms;
+  void *minisyms;
   unsigned int size;
 
   /* Ignore bfds with an import descriptor table.  We assume that any
@@ -1508,8 +1458,7 @@ scan_all_symbols (abfd)
 /* Look at the object file to decide which symbols to export.  */
 
 static void
-scan_open_obj_file (abfd)
-     bfd *abfd;
+scan_open_obj_file (bfd *abfd)
 {
   if (export_all_symbols)
     scan_all_symbols (abfd);
@@ -1523,8 +1472,7 @@ scan_open_obj_file (abfd)
 }
 
 static void
-scan_obj_file (filename)
-     const char *filename;
+scan_obj_file (const char *filename)
 {
   bfd * f = bfd_openr (filename, 0);
 
@@ -1567,8 +1515,7 @@ scan_obj_file (filename)
 /**********************************************************************/
 
 static void
-dump_def_info (f)
-     FILE *f;
+dump_def_info (FILE *f)
 {
   int i;
   export_type *exp;
@@ -1578,13 +1525,14 @@ dump_def_info (f)
   fprintf (f, "\n");
   for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
     {
-      fprintf (f, "%s  %d = %s %s @ %d %s%s%s\n",
+      fprintf (f, "%s  %d = %s %s @ %d %s%s%s%s\n",
               ASM_C,
               i,
               exp->name,
               exp->internal_name,
               exp->ordinal,
               exp->noname ? "NONAME " : "",
+              exp->private ? "PRIVATE " : "",
               exp->constant ? "CONSTANT" : "",
               exp->data ? "DATA" : "");
     }
@@ -1593,19 +1541,13 @@ dump_def_info (f)
 /* Generate the .exp file.  */
 
 static int
-sfunc (a, b)
-     const void *a;
-     const void *b;
+sfunc (const void *a, const void *b)
 {
   return *(const long *) a - *(const long *) b;
 }
 
 static void
-flush_page (f, need, page_addr, on_page)
-     FILE *f;
-     long *need;
-     int page_addr;
-     int on_page;
+flush_page (FILE *f, long *need, int page_addr, int on_page)
 {
   int i;
 
@@ -1635,7 +1577,7 @@ flush_page (f, need, page_addr, on_page)
 }
 
 static void
-gen_def_file ()
+gen_def_file (void)
 {
   int i;
   export_type *exp;
@@ -1653,23 +1595,28 @@ gen_def_file ()
       char *quote = strchr (exp->name, '.') ? "\"" : "";
       char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS);
 
-      if (strcmp (exp->name, exp->internal_name) == 0)
+      if (res)
        {
+         fprintf (output_def,";\t%s\n", res);
+         free (res);
+       }
 
-         fprintf (output_def, "\t%s%s%s @ %d%s%s ; %s\n",
+      if (strcmp (exp->name, exp->internal_name) == 0)
+       {
+         fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n",
                   quote,
                   exp->name,
                   quote,
                   exp->ordinal,
                   exp->noname ? " NONAME" : "",
-                  exp->data ? " DATA" : "",
-                  res ? res : "");
+                  exp->private ? "PRIVATE " : "",
+                  exp->data ? " DATA" : "");
        }
       else
        {
-         char *quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
+         char * quote1 = strchr (exp->internal_name, '.') ? "\"" : "";
          /* char *alias =  */
-         fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s ; %s\n",
+         fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n",
                   quote,
                   exp->name,
                   quote,
@@ -1678,11 +1625,9 @@ gen_def_file ()
                   quote1,
                   exp->ordinal,
                   exp->noname ? " NONAME" : "",
-                  exp->data ? " DATA" : "",
-                  res ? res : "");
+                  exp->private ? "PRIVATE " : "",
+                  exp->data ? " DATA" : "");
        }
-      if (res)
-       free (res);
     }
 
   inform (_("Added exports to output file"));
@@ -1693,8 +1638,7 @@ gen_def_file ()
    the file.  */
 
 static void
-generate_idata_ofile (filvar)
-     FILE *filvar;
+generate_idata_ofile (FILE *filvar)
 {
   iheadtype *headptr;
   ifunctype *funcptr;
@@ -1786,9 +1730,7 @@ generate_idata_ofile (filvar)
 
 /* Assemble the specified file.  */
 static void
-assemble_file (source, dest)
-     const char * source;
-     const char * dest;
+assemble_file (const char * source, const char * dest)
 {
   char * cmd;
 
@@ -1801,7 +1743,7 @@ assemble_file (source, dest)
 }
 
 static void
-gen_exp_file ()
+gen_exp_file (void)
 {
   FILE *f;
   int i;
@@ -1879,7 +1821,7 @@ gen_exp_file ()
                         exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
              else
                fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
-                        ASM_PREFIX,
+                        ASM_PREFIX (exp->internal_name),
                         exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
            }
          else
@@ -1908,14 +1850,14 @@ gen_exp_file ()
 
       fprintf(f,"%s Export Name Table\n", ASM_C);
       for (i = 0; (exp = d_exports_lexically[i]); i++)
-       if (!exp->noname || show_allnames)
-         {
+       {
+         if (!exp->noname || show_allnames)
            fprintf (f, "n%d:   %s      \"%s\"\n",
                     exp->ordinal, ASM_TEXT, xlate (exp->name));
-           if (exp->forward != 0)
-             fprintf (f, "f%d: %s      \"%s\"\n",
-                      exp->forward, ASM_TEXT, exp->internal_name);
-         }
+         if (exp->forward != 0)
+           fprintf (f, "f%d:   %s      \"%s\"\n",
+                    exp->forward, ASM_TEXT, exp->internal_name);
+       }
 
       if (a_list)
        {
@@ -2010,7 +1952,7 @@ gen_exp_file ()
          int dst = 0;
          int last = -1;
          qsort (copy, num_entries, sizeof (long), sfunc);
-         /* Delete duplcates */
+         /* Delete duplicates */
          for (src = 0; src < num_entries; src++)
            {
              if (last != copy[src])
@@ -2051,8 +1993,7 @@ gen_exp_file ()
 }
 
 static const char *
-xlate (name)
-     const char *name;
+xlate (const char *name)
 {
   int lead_at = (*name == '@');
 
@@ -2082,9 +2023,7 @@ xlate (name)
 #if 0
 
 static void
-dump_iat (f, exp)
-     FILE *f;
-     export_type *exp;
+dump_iat (FILE *f, export_type *exp)
 {
   if (exp->noname && !show_allnames )
     {
@@ -2214,23 +2153,19 @@ ID2:    .short  2
         bctr  */
 
 static char *
-make_label (prefix, name)
-     const char *prefix;
-     const char *name;
+make_label (const char *prefix, const char *name)
 {
-  int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
-  char *copy = xmalloc (len +);
+  int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
+  char *copy = xmalloc (len + 1);
 
-  strcpy (copy, ASM_PREFIX);
+  strcpy (copy, ASM_PREFIX (name));
   strcat (copy, prefix);
   strcat (copy, name);
   return copy;
 }
 
 static char *
-make_imp_label (prefix, name)
-     const char *prefix;
-     const char *name;
+make_imp_label (const char *prefix, const char *name)
 {
   int len;
   char *copy;
@@ -2244,19 +2179,17 @@ make_imp_label (prefix, name)
     }
   else
     {
-      len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
+      len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name);
       copy = xmalloc (len + 1);
       strcpy (copy, prefix);
-      strcat (copy, ASM_PREFIX);
+      strcat (copy, ASM_PREFIX (name));
       strcat (copy, name);
     }
   return copy;
 }
 
 static bfd *
-make_one_lib_file (exp, i)
-     export_type *exp;
-     int i;
+make_one_lib_file (export_type *exp, int i)
 {
 #if 0
     {
@@ -2269,12 +2202,12 @@ make_one_lib_file (exp, i)
       sprintf (name, "%ss%05d.s", prefix, i);
       f = fopen (name, FOPEN_WT);
       fprintf (f, "\t.text\n");
-      fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
+      fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX (exp->name), exp->name);
       if (create_compat_implib)
        fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
       fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name);
       if (create_compat_implib)
-       fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
+       fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX (exp->name),
                 exp->name, ASM_JUMP, exp->name);
 
       fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
@@ -2315,6 +2248,7 @@ make_one_lib_file (exp, i)
       asymbol *  exp_label;
       asymbol *  iname = 0;
       asymbol *  iname2;
+      asymbol *  iname2_pre = 0;
       asymbol *  iname_lab;
       asymbol ** iname_lab_pp;
       asymbol ** iname_pp;
@@ -2328,8 +2262,7 @@ make_one_lib_file (exp, i)
 #endif
       asymbol *  ptrs[NSECS + 4 + EXTRA + 1];
       flagword   applicable;
-
-      char *     outname = xmalloc (10);
+      char *     outname = xmalloc (strlen (TMP_STUB) + 10);
       int        oidx = 0;
 
 
@@ -2358,6 +2291,7 @@ make_one_lib_file (exp, i)
       for (i = 0; i < NSECS; i++)
        {
          sinfo *si = secdata + i;
+
          if (si->id != i)
            abort();
          si->sec = bfd_make_section_old_way (abfd, si->name);
@@ -2404,6 +2338,23 @@ make_one_lib_file (exp, i)
            bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
 #endif
          ptrs[oidx++] = exp_label;
+
+         if (ext_prefix_alias)
+           {
+             asymbol *  exp_label_pre;
+
+             exp_label_pre = bfd_make_empty_symbol (abfd);
+             exp_label_pre->name
+               = make_imp_label (ext_prefix_alias, exp->name);
+             exp_label_pre->section = exp_label->section;
+             exp_label_pre->flags = exp_label->flags;
+             exp_label_pre->value = exp_label->value;
+#ifdef DLLTOOL_ARM
+             if (machine == MTHUMB)
+               bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC);
+#endif
+             ptrs[oidx++] = exp_label_pre;
+           }
        }
 
       /* Generate imp symbols with one underscore for Microsoft
@@ -2424,10 +2375,23 @@ make_one_lib_file (exp, i)
       iname2->flags = BSF_GLOBAL;
       iname2->value = 0;
 
-      iname_lab = bfd_make_empty_symbol(abfd);
+      if (ext_prefix_alias)
+       {
+         char *pre_name;
+
+         iname2_pre = bfd_make_empty_symbol (abfd);
+         pre_name = xmalloc (strlen (ext_prefix_alias) + 7);
+         sprintf(pre_name, "__imp_%s", ext_prefix_alias);
+         iname2_pre->name = make_imp_label (pre_name, exp->name);
+         iname2_pre->section = iname2->section;
+         iname2_pre->flags = iname2->flags;
+         iname2_pre->value = iname2->value;
+       }
+
+      iname_lab = bfd_make_empty_symbol (abfd);
 
       iname_lab->name = head_label;
-      iname_lab->section = (asection *)&bfd_und_section;
+      iname_lab->section = (asection *) &bfd_und_section;
       iname_lab->flags = 0;
       iname_lab->value = 0;
 
@@ -2435,12 +2399,14 @@ make_one_lib_file (exp, i)
       if (create_compat_implib)
        ptrs[oidx++] = iname;
       ptrs[oidx++] = iname2;
+      if (ext_prefix_alias)
+       ptrs[oidx++] = iname2_pre;
 
       iname_lab_pp = ptrs + oidx;
       ptrs[oidx++] = iname_lab;
 
 #ifdef DLLTOOL_PPC
-      /* The symbol refering to the code (.text).  */
+      /* The symbol referring to the code (.text).  */
       {
        asymbol *function_name;
 
@@ -2551,16 +2517,22 @@ make_one_lib_file (exp, i)
                      why it did that, and it does not match what I see
                      in programs compiled with the MS tools.  */
                  int idx = exp->hint;
-                 si->size = strlen (xlate (exp->name)) + 3;
+                 /* If the user has specified an internal name, use it.
+                    Ignore command line name translation options.  */   
+                 char const * internal_name
+                   = exp->internal_name != exp->name
+                     ? exp->internal_name : xlate (exp->name);
+
+                 si->size = strlen (internal_name) + 3;
                  si->data = xmalloc (si->size);
                  si->data[0] = idx & 0xff;
                  si->data[1] = idx >> 8;
-                 strcpy (si->data + 2, xlate (exp->name));
+                 strcpy (si->data + 2, internal_name);
                }
              break;
            case IDATA7:
              si->size = 4;
-             si->data =xmalloc (4);
+             si->data = xmalloc (4);
              memset (si->data, 0, si->size);
              rel = xmalloc (sizeof (arelent));
              rpp = xmalloc (sizeof (arelent *) * 2);
@@ -2721,7 +2693,7 @@ make_one_lib_file (exp, i)
 }
 
 static bfd *
-make_head ()
+make_head (void)
 {
   FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
 
@@ -2780,7 +2752,7 @@ make_head ()
 }
 
 static bfd *
-make_tail ()
+make_tail (void)
 {
   FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
 
@@ -2838,7 +2810,7 @@ make_tail ()
 }
 
 static void
-gen_lib_file ()
+gen_lib_file (void)
 {
   int i;
   export_type *exp;
@@ -2870,7 +2842,11 @@ gen_lib_file ()
 
   for (i = 0; (exp = d_exports_lexically[i]); i++)
     {
-      bfd *n = make_one_lib_file (exp, i);
+      bfd *n;
+      /* Don't add PRIVATE entries to import lib.  */
+      if (exp->private)
+       continue;
+      n = make_one_lib_file (exp, i);
       n->next = head;
       head = n;
     }
@@ -2906,9 +2882,12 @@ gen_lib_file ()
     {
       char *name;
 
-      name = (char *) alloca (sizeof TMP_STUB + 10);
-      for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+      name = (char *) alloca (strlen (TMP_STUB) + 10);
+      for (i = 0; (exp = d_exports_lexically[i]); i++)
        {
+         /* Don't delete non-existent stubs for PRIVATE entries.  */
+          if (exp->private)
+           continue;
          sprintf (name, "%s%05d.o", TMP_STUB, i);
          if (unlink (name) < 0)
            /* xgettext:c-format */
@@ -2919,14 +2898,11 @@ gen_lib_file ()
   inform (_("Created lib file"));
 }
 
-/**********************************************************************/
-
 /* Run through the information gathered from the .o files and the
    .def file and work out the best stuff.  */
+
 static int
-pfunc (a, b)
-     const void *a;
-     const void *b;
+pfunc (const void *a, const void *b)
 {
   export_type *ap = *(export_type **) a;
   export_type *bp = *(export_type **) b;
@@ -2942,9 +2918,7 @@ pfunc (a, b)
 }
 
 static int
-nfunc (a, b)
-     const void *a;
-     const void *b;
+nfunc (const void *a, const void *b)
 {
   export_type *ap = *(export_type **) a;
   export_type *bp = *(export_type **) b;
@@ -2953,8 +2927,7 @@ nfunc (a, b)
 }
 
 static void
-remove_null_names (ptr)
-     export_type **ptr;
+remove_null_names (export_type **ptr)
 {
   int src;
   int dst;
@@ -2971,12 +2944,7 @@ remove_null_names (ptr)
 }
 
 static void
-dtab (ptr)
-     export_type ** ptr
-#ifndef SACDEBUG
-ATTRIBUTE_UNUSED
-#endif
-     ;
+dtab (export_type **ptr ATTRIBUTE_UNUSED)
 {
 #ifdef SACDEBUG
   int i;
@@ -2997,15 +2965,13 @@ ATTRIBUTE_UNUSED
 }
 
 static void
-process_duplicates (d_export_vec)
-     export_type **d_export_vec;
+process_duplicates (export_type **d_export_vec)
 {
   int more = 1;
   int i;
 
   while (more)
     {
-
       more = 0;
       /* Remove duplicates.  */
       qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
@@ -3016,7 +2982,6 @@ process_duplicates (d_export_vec)
          if (strcmp (d_export_vec[i]->name,
                      d_export_vec[i + 1]->name) == 0)
            {
-
              export_type *a = d_export_vec[i];
              export_type *b = d_export_vec[i + 1];
 
@@ -3046,18 +3011,14 @@ process_duplicates (d_export_vec)
        }
     }
 
-
   /* Count the names.  */
   for (i = 0; i < d_nfuncs; i++)
-    {
-      if (!d_export_vec[i]->noname)
-       d_named_nfuncs++;
-    }
+    if (!d_export_vec[i]->noname)
+      d_named_nfuncs++;
 }
 
 static void
-fill_ordinals (d_export_vec)
-     export_type **d_export_vec;
+fill_ordinals (export_type **d_export_vec)
 {
   int lowest = -1;
   int i;
@@ -3092,7 +3053,7 @@ fill_ordinals (d_export_vec)
     {
       if (d_export_vec[i]->ordinal == -1)
        {
-         register int j;
+         int j;
 
          /* First try within or after any user supplied range.  */
          for (j = lowest; j < size; j++)
@@ -3131,9 +3092,7 @@ fill_ordinals (d_export_vec)
 }
 
 static int
-alphafunc (av,bv)
-     const void *av;
-     const void *bv;
+alphafunc (const void *av, const void *bv)
 {
   const export_type **a = (const export_type **) av;
   const export_type **b = (const export_type **) bv;
@@ -3142,15 +3101,14 @@ alphafunc (av,bv)
 }
 
 static void
-mangle_defs ()
+mangle_defs (void)
 {
   /* First work out the minimum ordinal chosen.  */
   export_type *exp;
 
   int i;
   int hint = 0;
-  export_type **d_export_vec
-  = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
+  export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs);
 
   inform (_("Processing definitions"));
 
@@ -3187,12 +3145,8 @@ mangle_defs ()
   inform (_("Processed definitions"));
 }
 
-/**********************************************************************/
-
 static void
-usage (file, status)
-     FILE *file;
-     int status;
+usage (FILE *file, int status)
 {
   /* xgetext:c-format */
   fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
@@ -3215,10 +3169,12 @@ usage (file, status)
   fprintf (file, _("   -U --add-underscore       Add underscores to symbols in interface library.\n"));
   fprintf (file, _("   -k --kill-at              Kill @<n> from exported names.\n"));
   fprintf (file, _("   -A --add-stdcall-alias    Add aliases without @<n>.\n"));
+  fprintf (file, _("   -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n"));
   fprintf (file, _("   -S --as <name>            Use <name> for assembler.\n"));
   fprintf (file, _("   -f --as-flags <flags>     Pass <flags> to the assembler.\n"));
   fprintf (file, _("   -C --compat-implib        Create backward compatible import library.\n"));
   fprintf (file, _("   -n --no-delete            Keep temp files (repeat for extra preservation).\n"));
+  fprintf (file, _("   -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
   fprintf (file, _("   -v --verbose              Be verbose.\n"));
   fprintf (file, _("   -V --version              Display the program version.\n"));
   fprintf (file, _("   -h --help                 Display this information.\n"));
@@ -3248,11 +3204,12 @@ static const struct option long_options[] =
   {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS},
   {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
   {"output-lib", required_argument, NULL, 'l'},
-  {"def", required_argument, NULL, 'd'}, /* for compatiblity with older versions */
+  {"def", required_argument, NULL, 'd'}, /* for compatibility with older versions */
   {"input-def", required_argument, NULL, 'd'},
   {"add-underscore", no_argument, NULL, 'U'},
   {"kill-at", no_argument, NULL, 'k'},
   {"add-stdcall-alias", no_argument, NULL, 'A'},
+  {"ext-prefix-alias", required_argument, NULL, 'p'},
   {"verbose", no_argument, NULL, 'v'},
   {"version", no_argument, NULL, 'V'},
   {"help", no_argument, NULL, 'h'},
@@ -3263,15 +3220,14 @@ static const struct option long_options[] =
   {"as-flags", required_argument, NULL, 'f'},
   {"mcore-elf", required_argument, NULL, 'M'},
   {"compat-implib", no_argument, NULL, 'C'},
+  {"temp-prefix", required_argument, NULL, 't'},
   {NULL,0,NULL,0}
 };
 
-int main PARAMS ((int, char **));
+int main (int, char **);
 
 int
-main (ac, av)
-     int ac;
-     char **av;
+main (int ac, char **av)
 {
   int c;
   int i;
@@ -3290,9 +3246,9 @@ main (ac, av)
 
   while ((c = getopt_long (ac, av,
 #ifdef DLLTOOL_MCORE_ELF
-                          "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVHhM:L:F:",
+                          "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHhM:L:F:",
 #else
-                          "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVHh",
+                          "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHh",
 #endif
                           long_options, 0))
         != EOF)
@@ -3320,11 +3276,14 @@ main (ac, av)
        case 'S':
          as_name = optarg;
          break;
+       case 't':
+         tmp_prefix = optarg;
+         break;
        case 'f':
          as_flags = optarg;
          break;
 
-         /* ignored for compatibility */
+         /* Ignored for compatibility.  */
        case 'u':
          break;
        case 'a':
@@ -3364,6 +3323,9 @@ main (ac, av)
        case 'A':
          add_stdcall_alias = 1;
          break;
+       case 'p':
+         ext_prefix_alias = optarg;
+         break;
        case 'd':
          def_file = optarg;
          break;
@@ -3398,6 +3360,9 @@ main (ac, av)
        }
     }
 
+  if (!tmp_prefix)
+    tmp_prefix = prefix_encode ("d", getpid ());
+
   for (i = 0; mtable[i].type; i++)
     if (strcmp (mtable[i].type, mname) == 0)
       break;
@@ -3476,10 +3441,7 @@ main (ac, av)
    appropriate.  */
 
 static char *
-look_for_prog (prog_name, prefix, end_prefix)
-     const char *prog_name;
-     const char *prefix;
-     int end_prefix;
+look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
 {
   struct stat s;
   char *cmd;
@@ -3545,8 +3507,7 @@ look_for_prog (prog_name, prefix, end_prefix)
    Returns a dynamically allocated string.  */
 
 static char *
-deduce_name (prog_name)
-     const char *prog_name;
+deduce_name (const char *prog_name)
 {
   char *cmd;
   char *dash, *slash, *cp;