* inf-ptrace.c (inf_ptrace_prepare_to_store)
[binutils-gdb.git] / binutils / dlltool.c
index ffbcd2861cccd61d00ed67e548d73e842bc8ff3b..8b7f9fb41072200f3924ebba86a9ffa468d65785 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>
 
    IMPORTS  (  (   <internal-name> =   <module-name> . <integer> )
              | ( [ <internal-name> = ] <module-name> . <external-name> )) *
-   Declares that <external-name> or the exported function whoes ordinal number
+   Declares that <external-name> or the exported function whose 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
 #include <varargs.h>
 #endif
 
+#include <assert.h>
+
 #ifdef DLLTOOL_ARM
 #include "coff/arm.h"
 #include "coff/internal.h"
 #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
@@ -386,6 +384,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,7 +430,11 @@ static char * mcore_elf_linker_flags = NULL;
 #define DRECTVE_SECTION_NAME ".drectve"
 #endif
 
-#define PATHMAX 250            /* What's the right name for this ?  */
+/* What's the right name for this ?  */
+#define PATHMAX 250            
+
+/* External name alias numbering starts here.  */
+#define PREFIX_ALIAS_BASE      20000
 
 char *tmp_asm_buf;
 char *tmp_head_s_buf;
@@ -447,7 +450,7 @@ char *tmp_stub_buf;
 #define TMP_TAIL_O     dlltmp (&tmp_tail_o_buf, "%st.o")
 #define TMP_STUB       dlltmp (&tmp_stub_buf, "%ss")
 
-/* This bit of assemly does jmp * ....  */
+/* This bit of assembly does jmp * ....  */
 static const unsigned char i386_jtab[] =
 {
   0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
@@ -645,9 +648,11 @@ typedef struct export
   {
     const char *name;
     const char *internal_name;
+    const char *import_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.  */
@@ -665,93 +670,53 @@ 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 void set_dll_name_from_def (const char *);
 
 static char *
-prefix_encode PARAMS ((char *start, unsigned code))
+prefix_encode (char *start, unsigned code)
 {
   static char alpha[26] = "abcdefghijklmnopqrstuvwxyz";
   static char buf[32];
@@ -766,7 +731,7 @@ prefix_encode PARAMS ((char *start, unsigned code))
 }
 
 static char *
-dlltmp PARAMS ((char **buf, const char *fmt))
+dlltmp (char **buf, const char *fmt)
 {
   if (!*buf)
     {
@@ -791,8 +756,7 @@ inform VPARAMS ((const char * message, ...))
 }
 
 static const char *
-rvaafter (machine)
-     int machine;
+rvaafter (int machine)
 {
   switch (machine)
     {
@@ -816,8 +780,7 @@ rvaafter (machine)
 }
 
 static const char *
-rvabefore (machine)
-     int machine;
+rvabefore (int machine)
 {
   switch (machine)
     {
@@ -841,8 +804,7 @@ rvabefore (machine)
 }
 
 static const char *
-asm_prefix (machine)
-     int machine;
+asm_prefix (int machine, const char *name)
 {
   switch (machine)
     {
@@ -857,7 +819,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);
@@ -866,32 +832,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);
 
@@ -913,7 +878,6 @@ process_def_file (name)
 
 /* Communications with the parser.  */
 
-static const char *d_name;     /* Arg to NAME or LIBRARY.  */
 static int d_nfuncs;           /* Number of functions exported.  */
 static int d_named_nfuncs;     /* Number of named functions exported.  */
 static int d_low_ord;          /* Lowest ordinal index.  */
@@ -928,8 +892,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);
@@ -938,21 +901,18 @@ 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));
 
   p->name = name;
   p->internal_name = internal_name ? internal_name : name;
+  p->import_name = name;
   p->ordinal = ordinal;
   p->constant = constant;
   p->noname = noname;
+  p->private = private;
   p->data = data;
   p->next = d_exports;
   d_exports = p;
@@ -965,10 +925,18 @@ def_exports (name, internal_name, ordinal, noname, constant, data)
     p->forward = 0; /* no forward */
 }
 
+static void
+set_dll_name_from_def (const char * name)
+{
+  const char* image_basename = lbasename (name);
+  if (image_basename != name)
+    non_fatal (_("%s: Path components stripped from image name, '%s'."),
+             def_file, name);
+  dll_name = xstrdup (image_basename);
+}
+
 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);
@@ -976,18 +944,15 @@ def_name (name, base)
   if (d_is_dll)
     non_fatal (_("Can't have LIBRARY and NAME"));
 
-  d_name = name;
   /* If --dllname not provided, use the one in the DEF file.
      FIXME: Is this appropriate for executables?  */
   if (! dll_name)
-    dll_name = xstrdup (name);
+    set_dll_name_from_def (name);
   d_is_exe = 1;
 }
 
 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);
@@ -995,16 +960,14 @@ def_library (name, base)
   if (d_is_exe)
     non_fatal (_("Can't have LIBRARY and NAME"));
 
-  d_name = name;
   /* If --dllname not provided, use the one in the DEF file.  */
   if (! dll_name)
-    dll_name = xstrdup (name);
+    set_dll_name_from_def (name);
   d_is_dll = 1;
 }
 
 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);
@@ -1013,8 +976,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);
@@ -1023,9 +985,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)
@@ -1036,9 +996,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)
@@ -1052,10 +1010,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;
@@ -1119,12 +1074,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;
@@ -1150,17 +1101,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];
@@ -1180,16 +1127,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);
 }
@@ -1197,9 +1142,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;
@@ -1270,8 +1213,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;
@@ -1285,7 +1227,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);
@@ -1327,7 +1269,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, '@'))
            {
@@ -1336,7 +1278,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
@@ -1349,11 +1291,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;
@@ -1378,7 +1317,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, '@'))
         {
@@ -1387,7 +1326,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);
        }
     }
 }
@@ -1395,8 +1334,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;
@@ -1429,8 +1367,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;
 
@@ -1451,11 +1388,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;
@@ -1473,7 +1406,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));
 
@@ -1499,11 +1432,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
@@ -1542,8 +1474,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);
@@ -1557,8 +1488,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);
 
@@ -1601,8 +1531,7 @@ scan_obj_file (filename)
 /**********************************************************************/
 
 static void
-dump_def_info (f)
-     FILE *f;
+dump_def_info (FILE *f)
 {
   int i;
   export_type *exp;
@@ -1612,13 +1541,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" : "");
     }
@@ -1627,19 +1557,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;
 
@@ -1669,7 +1593,7 @@ flush_page (f, need, page_addr, on_page)
 }
 
 static void
-gen_def_file ()
+gen_def_file (void)
 {
   int i;
   export_type *exp;
@@ -1689,26 +1613,26 @@ gen_def_file ()
 
       if (res)
        {
-         fprintf (output_def,";\t%s\n", res);
+         fprintf (output_def,";\t%s\n", res);
          free (res);
        }
 
       if (strcmp (exp->name, exp->internal_name) == 0)
        {
-
-         fprintf (output_def, "\t%s%s%s @ %d%s%s\n",
+         fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n",
                   quote,
                   exp->name,
                   quote,
                   exp->ordinal,
                   exp->noname ? " NONAME" : "",
+                  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\n",
+         fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n",
                   quote,
                   exp->name,
                   quote,
@@ -1717,6 +1641,7 @@ gen_def_file ()
                   quote1,
                   exp->ordinal,
                   exp->noname ? " NONAME" : "",
+                  exp->private ? "PRIVATE " : "",
                   exp->data ? " DATA" : "");
        }
     }
@@ -1729,8 +1654,7 @@ gen_def_file ()
    the file.  */
 
 static void
-generate_idata_ofile (filvar)
-     FILE *filvar;
+generate_idata_ofile (FILE *filvar)
 {
   iheadtype *headptr;
   ifunctype *funcptr;
@@ -1822,9 +1746,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;
 
@@ -1837,7 +1759,7 @@ assemble_file (source, dest)
 }
 
 static void
-gen_exp_file ()
+gen_exp_file (void)
 {
   FILE *f;
   int i;
@@ -1915,7 +1837,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
@@ -1944,14 +1866,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)
        {
@@ -2046,7 +1968,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])
@@ -2087,8 +2009,7 @@ gen_exp_file ()
 }
 
 static const char *
-xlate (name)
-     const char *name;
+xlate (const char *name)
 {
   int lead_at = (*name == '@');
 
@@ -2118,9 +2039,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 )
     {
@@ -2250,23 +2169,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;
@@ -2280,19 +2195,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
     {
@@ -2305,12 +2218,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);
@@ -2364,7 +2277,6 @@ make_one_lib_file (exp, i)
 #endif
       asymbol *  ptrs[NSECS + 4 + EXTRA + 1];
       flagword   applicable;
-
       char *     outname = xmalloc (strlen (TMP_STUB) + 10);
       int        oidx = 0;
 
@@ -2394,6 +2306,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);
@@ -2460,10 +2373,10 @@ make_one_lib_file (exp, i)
       iname2->flags = BSF_GLOBAL;
       iname2->value = 0;
 
-      iname_lab = bfd_make_empty_symbol(abfd);
+      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;
 
@@ -2476,7 +2389,7 @@ make_one_lib_file (exp, i)
       ptrs[oidx++] = iname_lab;
 
 #ifdef DLLTOOL_PPC
-      /* The symbol refering to the code (.text).  */
+      /* The symbol referring to the code (.text).  */
       {
        asymbol *function_name;
 
@@ -2587,16 +2500,16 @@ 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;
+                 si->size = strlen (xlate (exp->import_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, xlate (exp->import_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);
@@ -2757,7 +2670,7 @@ make_one_lib_file (exp, i)
 }
 
 static bfd *
-make_head ()
+make_head (void)
 {
   FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
 
@@ -2816,7 +2729,7 @@ make_head ()
 }
 
 static bfd *
-make_tail ()
+make_tail (void)
 {
   FILE *f = fopen (TMP_TAIL_S, FOPEN_WT);
 
@@ -2874,7 +2787,7 @@ make_tail ()
 }
 
 static void
-gen_lib_file ()
+gen_lib_file (void)
 {
   int i;
   export_type *exp;
@@ -2906,9 +2819,33 @@ 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;
+      if (ext_prefix_alias)
+       {
+         export_type alias_exp;
+
+         assert (i < PREFIX_ALIAS_BASE);
+         alias_exp.name = make_imp_label (ext_prefix_alias, exp->name);
+         alias_exp.internal_name = exp->internal_name;
+         alias_exp.import_name = exp->name;
+         alias_exp.ordinal = exp->ordinal;
+         alias_exp.constant = exp->constant;
+         alias_exp.noname = exp->noname;
+         alias_exp.private = exp->private;
+         alias_exp.data = exp->data;
+         alias_exp.hint = exp->hint;
+         alias_exp.forward = exp->forward;
+         alias_exp.next = exp->next;
+         n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE);
+         n->next = head;
+         head = n;
+       }
     }
 
   /* Now stick them all into the archive.  */
@@ -2943,26 +2880,33 @@ gen_lib_file ()
       char *name;
 
       name = (char *) alloca (strlen (TMP_STUB) + 10);
-      for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
+      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 */
            non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
+         if (ext_prefix_alias)
+           {
+             sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE);
+             if (unlink (name) < 0)
+               /* xgettext:c-format */
+               non_fatal (_("cannot delete %s: %s"), name, strerror (errno));
+           }
        }
     }
 
   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;
@@ -2978,9 +2922,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;
@@ -2989,8 +2931,7 @@ nfunc (a, b)
 }
 
 static void
-remove_null_names (ptr)
-     export_type **ptr;
+remove_null_names (export_type **ptr)
 {
   int src;
   int dst;
@@ -3007,12 +2948,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;
@@ -3033,15 +2969,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);
@@ -3052,7 +2986,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];
 
@@ -3082,18 +3015,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;
@@ -3128,7 +3057,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++)
@@ -3167,9 +3096,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;
@@ -3178,15 +3105,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"));
 
@@ -3223,12 +3149,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);
@@ -3251,10 +3173,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"));
@@ -3284,11 +3208,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'},
@@ -3303,12 +3228,10 @@ static const struct option long_options[] =
   {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;
@@ -3327,9 +3250,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)
@@ -3364,7 +3287,7 @@ main (ac, av)
          as_flags = optarg;
          break;
 
-         /* ignored for compatibility */
+         /* Ignored for compatibility.  */
        case 'u':
          break;
        case 'a':
@@ -3374,7 +3297,10 @@ main (ac, av)
          output_def = fopen (optarg, FOPEN_WT);
          break;
        case 'D':
-         dll_name = optarg;
+         dll_name = (char*) lbasename (optarg);
+         if (dll_name != optarg)
+           non_fatal (_("Path components stripped from dllname, '%s'."),
+                        optarg);
          break;
        case 'l':
          imp_name = optarg;
@@ -3404,6 +3330,9 @@ main (ac, av)
        case 'A':
          add_stdcall_alias = 1;
          break;
+       case 'p':
+         ext_prefix_alias = optarg;
+         break;
        case 'd':
          def_file = optarg;
          break;
@@ -3453,9 +3382,13 @@ main (ac, av)
 
   if (!dll_name && exp_name)
     {
-      int len = strlen (exp_name) + 5;
+      /* If we are inferring dll_name from exp_name,
+         strip off any path components, without emitting
+         a warning.  */  
+      const char* exp_basename = lbasename (exp_name); 
+      const int len = strlen (exp_basename) + 5;
       dll_name = xmalloc (len);
-      strcpy (dll_name, exp_name);
+      strcpy (dll_name, exp_basename);
       strcat (dll_name, ".dll");
     }
 
@@ -3519,10 +3452,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;
@@ -3588,8 +3518,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;