gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / binutils / dllwrap.c
index 0c01f5f9390a79abb5cae7dee8f942633b814453..c8cdf843019e88cf8e48f11d7a94d830ea1f9361 100644 (file)
@@ -1,12 +1,12 @@
 /* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs
 /* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 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
    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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, USA.  */
 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, 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
-
+#include "sysdep.h"
 #include "bfd.h"
 #include "libiberty.h"
 #include "bfd.h"
 #include "libiberty.h"
-#include "bucomm.h"
 #include "getopt.h"
 #include "dyn-string.h"
 #include "getopt.h"
 #include "dyn-string.h"
+#include "bucomm.h"
 
 #include <time.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>
 
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
@@ -89,6 +72,9 @@ static char *dlltool_name = NULL;
 
 static char *target = TARGET;
 
 
 static char *target = TARGET;
 
+/* -1: use default, 0: no underscoring, 1: underscore.  */
+static int is_leading_underscore = -1;
+
 typedef enum {
   UNKNOWN_TARGET,
   CYGWIN_TARGET,
 typedef enum {
   UNKNOWN_TARGET,
   CYGWIN_TARGET,
@@ -96,7 +82,16 @@ typedef enum {
 }
 target_type;
 
 }
 target_type;
 
+typedef enum {
+  UNKNOWN_CPU,
+  X86_CPU,
+  X64_CPU,
+  ARM_CPU
+}
+target_cpu;
+
 static target_type which_target = UNKNOWN_TARGET;
 static target_type which_target = UNKNOWN_TARGET;
+static target_cpu which_cpu = UNKNOWN_CPU;
 
 static int dontdeltemps = 0;
 static int dry_run = 0;
 
 static int dontdeltemps = 0;
 static int dry_run = 0;
@@ -118,9 +113,9 @@ static int run (const char *, char *);
 static char *mybasename (const char *);
 static int strhash (const char *);
 static void usage (FILE *, int);
 static char *mybasename (const char *);
 static int strhash (const char *);
 static void usage (FILE *, int);
-static void display (const char *, va_list);
-static void inform (const char *, ...);
-static void warn (const char *, ...);
+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 char *look_for_prog (const char *, const char *, int);
 static char *deduce_name (const char *);
 static void delete_temp_files (void);
@@ -148,28 +143,30 @@ display (const char * message, va_list args)
 
 
 static void
 
 
 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);
 
 
   if (!verbose)
     return;
 
   display (message, args);
 
-  VA_CLOSE (args);
+  va_end (args);
 }
 
 static void
 }
 
 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);
 
 
   display (format, args);
 
-  VA_CLOSE (args);
+  va_end (args);
 }
 
 /* Look for the program formed by concatenating PROG_NAME and the
 }
 
 /* Look for the program formed by concatenating PROG_NAME and the
@@ -178,20 +175,20 @@ warn VPARAMS ((const char *format, ...))
    appropriate.  */
 
 static char *
    appropriate.  */
 
 static char *
-look_for_prog (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)
 {
   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);
 
 #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)
     {
 
   if (strchr (cmd, '/') != NULL)
     {
@@ -367,7 +364,7 @@ run (const char *what, char *args)
     if (*s == ' ')
       i++;
   i++;
     if (*s == ' ')
       i++;
   i++;
-  argv = alloca (sizeof (char *) * (i + 3));
+  argv = xmalloc (sizeof (char *) * (i + 3));
   i = 0;
   argv[i++] = what;
   s = args;
   i = 0;
   argv[i++] = what;
   s = args;
@@ -395,6 +392,7 @@ run (const char *what, char *args)
 
   pid = pexecute (argv[0], (char * const *) argv, prog_name, temp_base,
                  &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
 
   pid = pexecute (argv[0], (char * const *) argv, prog_name, temp_base,
                  &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
+  free (argv);
 
   if (pid == -1)
     {
 
   if (pid == -1)
     {
@@ -410,7 +408,7 @@ run (const char *what, char *args)
   pid = pwait (pid, &wait_status, 0);
   if (pid == -1)
     {
   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))
       retcode = 1;
     }
   else if (WIFSIGNALED (wait_status))
@@ -478,6 +476,7 @@ usage (FILE *file, int status)
 {
   fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), prog_name);
   fprintf (file, _("  Generic options:\n"));
 {
   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, _("   --quiet, -q            Work quietly\n"));
   fprintf (file, _("   --verbose, -v          Verbose\n"));
   fprintf (file, _("   --version              Print dllwrap version\n"));
@@ -511,8 +510,12 @@ usage (FILE *file, int 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, _("   --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");
   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);
 }
 
   exit (status);
 }
 
@@ -532,9 +535,11 @@ usage (FILE *file, int status)
 #define OPTION_IMAGE_BASE      (OPTION_ENTRY + 1)
 #define OPTION_TARGET          (OPTION_IMAGE_BASE + 1)
 #define OPTION_MNO_CYGWIN      (OPTION_TARGET + 1)
 #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.  */
 
 /* 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_IDATA5       (OPTION_NO_IDATA4 + 1)
 #define OPTION_DLLNAME         (OPTION_NODELETE + 1)
 #define OPTION_NO_IDATA4       (OPTION_DLLNAME + 1)
 #define OPTION_NO_IDATA5       (OPTION_NO_IDATA4 + 1)
@@ -570,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},
   {"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'},
 
   /* dlltool options.  */
   {"no-delete", no_argument, NULL, 'n'},
@@ -632,6 +639,8 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
   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));
   saved_argv = (char **) xmalloc (argc * sizeof (char*));
   dlltool_arg_indices = (int *) xmalloc (argc * sizeof (int));
   driver_arg_indices = (int *) xmalloc (argc * sizeof (int));
@@ -731,6 +740,12 @@ main (int argc, char **argv)
        case OPTION_MNO_CYGWIN:
          target = "i386-mingw32";
          break;
        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;
        case OPTION_BASE_FILE:
          base_file_name = optarg;
          delete_base_file = 0;
@@ -822,6 +837,21 @@ Creating one, but that may not be what you want"));
   else
     which_target = UNKNOWN_TARGET;
 
   else
     which_target = UNKNOWN_TARGET;
 
+  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)
   /* Re-create the command lines as a string, taking care to quote stuff.  */
   dlltool_cmdline = dyn_string_new (cmdline_len);
   if (verbose)
@@ -866,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);
 
   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)
     {
   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:
       switch (which_target)
        {
        case CYGWIN_TARGET:
-         entry_point = "__cygwin_dll_entry@12";
+         name_entry = "_cygwin_dll_entry";
          break;
 
        case MINGW_TARGET:
          break;
 
        case MINGW_TARGET:
-         entry_point = "_DllMainCRTStartup@12";
+         name_entry = "DllMainCRTStartup";
          break;
 
        default:
          break;
 
        default:
-         entry_point = "_DllMain@12";
+         name_entry = "DllMain";
          break;
        }
          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);
     }
   dyn_string_append_cstr (driver_cmdline, " -Wl,-e,");
   dyn_string_append_cstr (driver_cmdline, entry_point);
@@ -924,7 +970,6 @@ Creating one, but that may not be what you want"));
 
   if (! def_file_seen)
     {
 
   if (! def_file_seen)
     {
-      int i;
       dyn_string_t step_pre1;
 
       step_pre1 = dyn_string_new (1024);
       dyn_string_t step_pre1;
 
       step_pre1 = dyn_string_new (1024);
@@ -977,9 +1022,9 @@ Creating one, but that may not be what you want"));
 
   /* Step 1. Call GCC/LD to create base relocation file. If using GCC, the
      driver command line will look like the following:
 
   /* 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]
         % 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 the user does not specify a base name, create temporary one that
      is deleted at exit.  */
 
@@ -1021,9 +1066,9 @@ Creating one, but that may not be what you want"));
 
   /* Step 2. generate the exp file by running dlltool.
      dlltool command line will look like the following:
 
   /* 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]
         % 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.  */
 
This page took 0.035273 seconds and 4 git commands to generate.