gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / binutils / dllwrap.c
index 4ca59366a0291332f29ab60bff66aa8024b005b5..c8cdf843019e88cf8e48f11d7a94d830ea1f9361 100644 (file)
@@ -1,12 +1,12 @@
 /* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs
-   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1998-2020 Free Software Foundation, Inc.
    Contributed by Mumit Khan (khan@xraylith.wisc.edu).
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
-
-/* AIX requires this to be the first thing in the file.  */
-#ifndef __GNUC__
-# ifdef _AIX
- #pragma alloca
-#endif
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
+#include "sysdep.h"
 #include "bfd.h"
 #include "libiberty.h"
-#include "bucomm.h"
 #include "getopt.h"
 #include "dyn-string.h"
+#include "bucomm.h"
 
 #include <time.h>
-#include <sys/stat.h>
-
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
 
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
@@ -89,6 +72,9 @@ static char *dlltool_name = NULL;
 
 static char *target = TARGET;
 
+/* -1: use default, 0: no underscoring, 1: underscore.  */
+static int is_leading_underscore = -1;
+
 typedef enum {
   UNKNOWN_TARGET,
   CYGWIN_TARGET,
@@ -96,12 +82,21 @@ typedef enum {
 }
 target_type;
 
+typedef enum {
+  UNKNOWN_CPU,
+  X86_CPU,
+  X64_CPU,
+  ARM_CPU
+}
+target_cpu;
+
 static target_type which_target = UNKNOWN_TARGET;
+static target_cpu which_cpu = UNKNOWN_CPU;
 
 static int dontdeltemps = 0;
 static int dry_run = 0;
 
-static char *program_name;
+static char *prog_name;
 
 static int verbose = 0;
 
@@ -114,17 +109,17 @@ static int delete_base_file = 1;
 static int delete_exp_file = 1;
 static int delete_def_file = 1;
 
-static int run PARAMS ((const char *, char *));
-static char *mybasename PARAMS ((const char *));
-static int strhash PARAMS ((const char *));
-static void usage PARAMS ((FILE *, int));
-static void display PARAMS ((const char *, va_list));
-static void inform PARAMS ((const char *, ...));
-static void warn PARAMS ((const char *, ...));
-static char *look_for_prog PARAMS ((const char *, const char *, int));
-static char *deduce_name PARAMS ((const char *));
-static void delete_temp_files PARAMS ((void));
-static void cleanup_and_exit PARAMS ((int));
+static int run (const char *, char *);
+static char *mybasename (const char *);
+static int strhash (const char *);
+static void usage (FILE *, int);
+static void display (const char *, va_list) ATTRIBUTE_PRINTF(1,0);
+static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
+static void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
+static char *look_for_prog (const char *, const char *, int);
+static char *deduce_name (const char *);
+static void delete_temp_files (void);
+static void cleanup_and_exit (int);
 
 /**********************************************************************/
 
@@ -137,12 +132,10 @@ static void cleanup_and_exit PARAMS ((int));
    (hopefully) soon be retired in favor of `ld --shared.  */
 
 static void
-display (message, args)
-     const char * message;
-     va_list      args;
+display (const char * message, va_list args)
 {
-  if (program_name != NULL)
-    fprintf (stderr, "%s: ", program_name);
+  if (prog_name != NULL)
+    fprintf (stderr, "%s: ", prog_name);
 
   vfprintf (stderr, message, args);
   fputc ('\n', stderr);
@@ -150,28 +143,30 @@ display (message, args)
 
 
 static void
-inform VPARAMS ((const char *message, ...))
+inform (const char *message, ...)
 {
-  VA_OPEN (args, message);
-  VA_FIXEDARG (args, const char *, message);
+  va_list args;
+
+  va_start (args, message);
 
   if (!verbose)
     return;
 
   display (message, args);
 
-  VA_CLOSE (args);
+  va_end (args);
 }
 
 static void
-warn VPARAMS ((const char *format, ...))
+warn (const char *format, ...)
 {
-  VA_OPEN (args, format);
-  VA_FIXEDARG (args, const char *, format);
+  va_list args;
+
+  va_start (args, format);
 
   display (format, args);
 
-  VA_CLOSE (args);
+  va_end (args);
 }
 
 /* Look for the program formed by concatenating PROG_NAME and the
@@ -180,23 +175,20 @@ warn VPARAMS ((const char *format, ...))
    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 *progname, const char *prefix, int end_prefix)
 {
   struct stat s;
   char *cmd;
 
   cmd = xmalloc (strlen (prefix)
-                + strlen (prog_name)
+                + strlen (progname)
 #ifdef HAVE_EXECUTABLE_SUFFIX
                 + strlen (EXECUTABLE_SUFFIX)
 #endif
                 + 10);
   strcpy (cmd, prefix);
 
-  sprintf (cmd + end_prefix, "%s", prog_name);
+  sprintf (cmd + end_prefix, "%s", progname);
 
   if (strchr (cmd, '/') != NULL)
     {
@@ -249,18 +241,20 @@ 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 * name)
 {
   char *cmd;
-  char *dash, *slash, *cp;
+  const char *dash;
+  const char *slash;
+  const char *cp;
 
   dash = NULL;
   slash = NULL;
-  for (cp = program_name; *cp != '\0'; ++cp)
+  for (cp = prog_name; *cp != '\0'; ++cp)
     {
       if (*cp == '-')
        dash = cp;
+
       if (
 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
          *cp == ':' || *cp == '\\' ||
@@ -275,30 +269,24 @@ deduce_name (prog_name)
   cmd = NULL;
 
   if (dash != NULL)
-    {
-      /* First, try looking for a prefixed PROG_NAME in the
-         PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME.  */
-      cmd = look_for_prog (prog_name, program_name, dash - program_name + 1);
-    }
+    /* First, try looking for a prefixed NAME in the
+       PROG_NAME directory, with the same prefix as PROG_NAME.  */
+    cmd = look_for_prog (name, prog_name, dash - prog_name + 1);
 
   if (slash != NULL && cmd == NULL)
-    {
-      /* Next, try looking for a PROG_NAME in the same directory as
-         that of this program.  */
-      cmd = look_for_prog (prog_name, program_name, slash - program_name + 1);
-    }
+    /* Next, try looking for a NAME in the same directory as
+       that of this program.  */
+    cmd = look_for_prog (name, prog_name, slash - prog_name + 1);
 
   if (cmd == NULL)
-    {
-      /* Just return PROG_NAME as is.  */
-      cmd = xstrdup (prog_name);
-    }
+    /* Just return NAME as is.  */
+    cmd = xstrdup (name);
 
   return cmd;
 }
 
 static void
-delete_temp_files ()
+delete_temp_files (void)
 {
   if (delete_base_file && base_file_name)
     {
@@ -349,17 +337,14 @@ delete_temp_files ()
 }
 
 static void
-cleanup_and_exit (status)
-     int status;
+cleanup_and_exit (int status)
 {
   delete_temp_files ();
   exit (status);
 }
 
 static int
-run (what, args)
-     const char *what;
-     char *args;
+run (const char *what, char *args)
 {
   char *s;
   int pid, wait_status, retcode;
@@ -379,7 +364,7 @@ run (what, args)
     if (*s == ' ')
       i++;
   i++;
-  argv = alloca (sizeof (char *) * (i + 3));
+  argv = xmalloc (sizeof (char *) * (i + 3));
   i = 0;
   argv[i++] = what;
   s = args;
@@ -405,14 +390,15 @@ run (what, args)
   if (dry_run)
     return 0;
 
-  pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
+  pid = pexecute (argv[0], (char * const *) argv, prog_name, temp_base,
                  &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
+  free (argv);
 
   if (pid == -1)
     {
       int errno_val = errno;
 
-      fprintf (stderr, "%s: ", program_name);
+      fprintf (stderr, "%s: ", prog_name);
       fprintf (stderr, errmsg_fmt, errmsg_arg);
       fprintf (stderr, ": %s\n", strerror (errno_val));
       return 1;
@@ -422,7 +408,7 @@ run (what, args)
   pid = pwait (pid, &wait_status, 0);
   if (pid == -1)
     {
-      warn ("wait: %s", strerror (errno));
+      warn (_("pwait returns: %s"), strerror (errno));
       retcode = 1;
     }
   else if (WIFSIGNALED (wait_status))
@@ -445,8 +431,7 @@ run (what, args)
 }
 
 static char *
-mybasename (name)
-     const char *name;
+mybasename (const char *name)
 {
   const char *base = name;
 
@@ -462,8 +447,7 @@ mybasename (name)
 }
 
 static int
-strhash (str)
-     const char *str;
+strhash (const char *str)
 {
   const unsigned char *s;
   unsigned long hash;
@@ -488,17 +472,16 @@ strhash (str)
 /**********************************************************************/
 
 static void
-usage (file, status)
-     FILE *file;
-     int status;
+usage (FILE *file, int status)
 {
-  fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name);
+  fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), prog_name);
   fprintf (file, _("  Generic options:\n"));
+  fprintf (file, _("   @<file>                Read options from <file>\n"));
   fprintf (file, _("   --quiet, -q            Work quietly\n"));
   fprintf (file, _("   --verbose, -v          Verbose\n"));
   fprintf (file, _("   --version              Print dllwrap version\n"));
   fprintf (file, _("   --implib <outname>     Synonym for --output-lib\n"));
-  fprintf (file, _("  Options for %s:\n"), program_name);
+  fprintf (file, _("  Options for %s:\n"), prog_name);
   fprintf (file, _("   --driver-name <driver> Defaults to \"gcc\"\n"));
   fprintf (file, _("   --driver-flags <flags> Override default ld flags\n"));
   fprintf (file, _("   --dlltool-name <dlltool> Defaults to \"dlltool\"\n"));
@@ -527,8 +510,12 @@ usage (file, status)
   fprintf (file, _("   --add-stdcall-alias    Add aliases without @<n>\n"));
   fprintf (file, _("   --as <name>            Use <name> for assembler\n"));
   fprintf (file, _("   --nodelete             Keep temp files.\n"));
+  fprintf (file, _("   --no-leading-underscore  Entrypoint without underscore\n"));
+  fprintf (file, _("   --leading-underscore     Entrypoint with underscore.\n"));
   fprintf (file, _("  Rest are passed unmodified to the language driver\n"));
   fprintf (file, "\n\n");
+  if (REPORT_BUGS_TO[0] && status == 0)
+    fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
   exit (status);
 }
 
@@ -548,11 +535,13 @@ usage (file, status)
 #define OPTION_IMAGE_BASE      (OPTION_ENTRY + 1)
 #define OPTION_TARGET          (OPTION_IMAGE_BASE + 1)
 #define OPTION_MNO_CYGWIN      (OPTION_TARGET + 1)
+#define OPTION_NO_LEADING_UNDERSCORE (OPTION_MNO_CYGWIN + 1)
+#define OPTION_LEADING_UNDERSCORE (OPTION_NO_LEADING_UNDERSCORE + 1)
 
 /* DLLTOOL options.  */
-#define OPTION_NODELETE                (OPTION_MNO_CYGWIN + 1)
+#define OPTION_NODELETE                (OPTION_LEADING_UNDERSCORE + 1)
 #define OPTION_DLLNAME         (OPTION_NODELETE + 1)
-#define OPTION_NO_IDATA4       (OPTION_DLLNAME + 1)
+#define OPTION_NO_IDATA4       (OPTION_DLLNAME + 1)
 #define OPTION_NO_IDATA5       (OPTION_NO_IDATA4 + 1)
 #define OPTION_OUTPUT_EXP      (OPTION_NO_IDATA5 + 1)
 #define OPTION_OUTPUT_DEF      (OPTION_OUTPUT_EXP + 1)
@@ -586,6 +575,8 @@ static const struct option long_options[] =
   {"entry", required_argument, NULL, 'e'},
   {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
   {"target", required_argument, NULL, OPTION_TARGET},
+  {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
+  {"leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
 
   /* dlltool options.  */
   {"no-delete", no_argument, NULL, 'n'},
@@ -611,12 +602,10 @@ static const struct option long_options[] =
   {0, 0, 0, 0}
 };
 
-int main PARAMS ((int, char **));
+int main (int, char **);
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   int c;
   int i;
@@ -639,7 +628,7 @@ main (argc, argv)
 
   char *image_base_str = 0;
 
-  program_name = argv[0];
+  prog_name = argv[0];
 
 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   setlocale (LC_MESSAGES, "");
@@ -650,6 +639,8 @@ main (argc, argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
+  expandargv (&argc, &argv);
+
   saved_argv = (char **) xmalloc (argc * sizeof (char*));
   dlltool_arg_indices = (int *) xmalloc (argc * sizeof (int));
   driver_arg_indices = (int *) xmalloc (argc * sizeof (int));
@@ -703,7 +694,7 @@ main (argc, argv)
          verbose = 1;
          break;
        case OPTION_VERSION:
-         print_version (program_name);
+         print_version (prog_name);
          break;
        case 'e':
          entry_point = optarg;
@@ -749,6 +740,12 @@ main (argc, argv)
        case OPTION_MNO_CYGWIN:
          target = "i386-mingw32";
          break;
+       case OPTION_NO_LEADING_UNDERSCORE:
+         is_leading_underscore = 0;
+         break;
+       case OPTION_LEADING_UNDERSCORE:
+         is_leading_underscore = 1;
+         break;
        case OPTION_BASE_FILE:
          base_file_name = optarg;
          delete_base_file = 0;
@@ -796,7 +793,7 @@ main (argc, argv)
        }
     }
 
-  /* sanity checks.  */
+  /* Sanity checks.  */
   if (! dll_name && ! dll_file_name)
     {
       warn (_("Must provide at least one of -o or --dllname options"));
@@ -821,6 +818,7 @@ main (argc, argv)
   if (! def_file_seen)
     {
       char *fileprefix = choose_temp_base ();
+
       def_file_name = (char *) xmalloc (strlen (fileprefix) + 5);
       sprintf (def_file_name, "%s.def",
               (dontdeltemps) ? mybasename (fileprefix) : fileprefix);
@@ -831,7 +829,7 @@ main (argc, argv)
 Creating one, but that may not be what you want"));
     }
 
-  /* set the target platform.  */
+  /* Set the target platform.  */
   if (strstr (target, "cygwin"))
     which_target = CYGWIN_TARGET;
   else if (strstr (target, "mingw"))
@@ -839,12 +837,26 @@ Creating one, but that may not be what you want"));
   else
     which_target = UNKNOWN_TARGET;
 
-  /* re-create the command lines as a string, taking care to quote stuff.  */
+  if (! strncmp (target, "arm", 3))
+    which_cpu = ARM_CPU;
+  else if (!strncmp (target, "x86_64", 6)
+          || !strncmp (target, "athlon64", 8)
+          || !strncmp (target, "amd64", 5))
+    which_cpu = X64_CPU;
+  else if (target[0] == 'i' && (target[1] >= '3' && target[1] <= '6')
+          && target[2] == '8' && target[3] == '6')
+    which_cpu = X86_CPU;
+  else
+    which_cpu = UNKNOWN_CPU;
+
+  if (is_leading_underscore == -1)
+    is_leading_underscore = (which_cpu != X64_CPU && which_cpu != ARM_CPU);
+
+  /* Re-create the command lines as a string, taking care to quote stuff.  */
   dlltool_cmdline = dyn_string_new (cmdline_len);
   if (verbose)
-    {
-      dyn_string_append_cstr (dlltool_cmdline, " -v");
-    }
+    dyn_string_append_cstr (dlltool_cmdline, " -v");
+
   dyn_string_append_cstr (dlltool_cmdline, " --dllname ");
   dyn_string_append_cstr (dlltool_cmdline, dll_name);
 
@@ -884,22 +896,38 @@ Creating one, but that may not be what you want"));
   dyn_string_append_cstr (driver_cmdline, " -o ");
   dyn_string_append_cstr (driver_cmdline, dll_file_name);
 
+  if (is_leading_underscore == 0)
+    dyn_string_append_cstr (driver_cmdline, " --no-leading-underscore");
+  else if (is_leading_underscore == 1)
+    dyn_string_append_cstr (driver_cmdline, " --leading-underscore");
+
   if (! entry_point || strlen (entry_point) == 0)
     {
+      const char *prefix = (is_leading_underscore != 0 ? "_" : "");
+      const char *postfix = "";
+      const char *name_entry;
+
+      if (which_cpu == X86_CPU || which_cpu == UNKNOWN_CPU)
+       postfix = "@12";
+
       switch (which_target)
        {
        case CYGWIN_TARGET:
-         entry_point = "__cygwin_dll_entry@12";
+         name_entry = "_cygwin_dll_entry";
          break;
 
        case MINGW_TARGET:
-         entry_point = "_DllMainCRTStartup@12";
+         name_entry = "DllMainCRTStartup";
          break;
 
        default:
-         entry_point = "_DllMain@12";
+         name_entry = "DllMain";
          break;
        }
+      entry_point =
+       (char *) malloc (strlen (name_entry) + strlen (prefix)
+                        + strlen (postfix) + 1);
+      sprintf (entry_point, "%s%s%s", prefix, name_entry, postfix);
     }
   dyn_string_append_cstr (driver_cmdline, " -Wl,-e,");
   dyn_string_append_cstr (driver_cmdline, entry_point);
@@ -937,14 +965,11 @@ Creating one, but that may not be what you want"));
        }
     }
 
-  /*
-   * Step pre-1. If no --def <EXPORT_DEF> is specified, then create it
-   * and then pass it on.
-   */
+  /* Step pre-1. If no --def <EXPORT_DEF> is specified,
+     then create it and then pass it on.  */
 
   if (! def_file_seen)
     {
-      int i;
       dyn_string_t step_pre1;
 
       step_pre1 = dyn_string_new (1024);
@@ -995,16 +1020,13 @@ Creating one, but that may not be what you want"));
       fprintf (stderr, _("DRIVER options  : %s\n"), driver_cmdline->s);
     }
 
-  /*
-   * Step 1. Call GCC/LD to create base relocation file. If using GCC, the
-   * driver command line will look like the following:
-   *
-   *    % gcc -Wl,--dll --Wl,--base-file,foo.base [rest of command line]
-   *
-   * If the user does not specify a base name, create temporary one that
-   * is deleted at exit.
-   *
-   */
+  /* Step 1. Call GCC/LD to create base relocation file. If using GCC, the
+     driver command line will look like the following:
+
+        % gcc -Wl,--dll --Wl,--base-file,foo.base [rest of command line]
+
+     If the user does not specify a base name, create temporary one that
+     is deleted at exit.  */
 
   if (! base_file_name)
     {
@@ -1042,23 +1064,19 @@ Creating one, but that may not be what you want"));
     dyn_string_delete (step1);
   }
 
+  /* Step 2. generate the exp file by running dlltool.
+     dlltool command line will look like the following:
 
+        % dlltool -Wl,--dll --Wl,--base-file,foo.base [rest of command line]
 
-  /*
-   * Step 2. generate the exp file by running dlltool.
-   * dlltool command line will look like the following:
-   *
-   *    % dlltool -Wl,--dll --Wl,--base-file,foo.base [rest of command line]
-   *
-   * If the user does not specify a base name, create temporary one that
-   * is deleted at exit.
-   *
-   */
+     If the user does not specify a base name, create temporary one that
+     is deleted at exit.  */
 
   if (! exp_file_name)
     {
       char *p = strrchr (dll_name, '.');
-      size_t prefix_len = (p) ? p - dll_name : strlen (dll_name);
+      size_t prefix_len = (p) ? (size_t) (p - dll_name) : strlen (dll_name);
+
       exp_file_name = (char *) xmalloc (prefix_len + 4 + 1);
       strncpy (exp_file_name, dll_name, prefix_len);
       exp_file_name[prefix_len] = '\0';
@@ -1068,6 +1086,7 @@ Creating one, but that may not be what you want"));
 
   {
     int quote;
+
     dyn_string_t step2 = dyn_string_new (dlltool_cmdline->length
                                         + strlen (base_file_name)
                                         + strlen (exp_file_name)
This page took 0.032043 seconds and 4 git commands to generate.