X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fdllwrap.c;h=3a58e5fe079ab09856f0bf93c61c2aa02eab2fc6;hb=831bd6aa3b2d5e36c94b89756f58bb99f35026ca;hp=e4db7bae53878ab22cdefd5640fe86afbc790bdf;hpb=2da42df615c0489291f8d3e1ce873642755a49c6;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/dllwrap.c b/binutils/dllwrap.c index e4db7bae53..3a58e5fe07 100644 --- a/binutils/dllwrap.c +++ b/binutils/dllwrap.c @@ -1,12 +1,12 @@ /* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs - Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1998-2019 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, @@ -16,34 +16,17 @@ 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 -#include - -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif #ifdef HAVE_SYS_WAIT_H #include @@ -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; @@ -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 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); @@ -139,8 +134,8 @@ static void cleanup_and_exit (int); static void 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); @@ -148,28 +143,30 @@ display (const char * message, va_list 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 @@ -178,20 +175,20 @@ warn VPARAMS ((const char *format, ...)) 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) - + 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) { @@ -244,17 +241,20 @@ look_for_prog (const char *prog_name, const char *prefix, int end_prefix) Returns a dynamically allocated string. */ static char * -deduce_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 == '\\' || @@ -269,24 +269,18 @@ deduce_name (const char *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; } @@ -370,7 +364,7 @@ run (const char *what, char *args) if (*s == ' ') i++; i++; - argv = alloca (sizeof (char *) * (i + 3)); + argv = xmalloc (sizeof (char *) * (i + 3)); i = 0; argv[i++] = what; s = args; @@ -396,14 +390,15 @@ run (const char *what, char *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; @@ -413,7 +408,7 @@ run (const char *what, char *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)) @@ -479,13 +474,14 @@ strhash (const char *str) static void usage (FILE *file, int status) { - fprintf (file, _("Usage %s \n"), program_name); + fprintf (file, _("Usage %s \n"), prog_name); fprintf (file, _(" Generic options:\n")); + fprintf (file, _(" @ Read options from \n")); fprintf (file, _(" --quiet, -q Work quietly\n")); fprintf (file, _(" --verbose, -v Verbose\n")); fprintf (file, _(" --version Print dllwrap version\n")); fprintf (file, _(" --implib 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 Defaults to \"gcc\"\n")); fprintf (file, _(" --driver-flags Override default ld flags\n")); fprintf (file, _(" --dlltool-name Defaults to \"dlltool\"\n")); @@ -514,8 +510,12 @@ usage (FILE *file, int status) fprintf (file, _(" --add-stdcall-alias Add aliases without @\n")); fprintf (file, _(" --as Use 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); } @@ -535,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_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_IDATA5 (OPTION_NO_IDATA4 + 1) @@ -573,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'}, @@ -624,7 +628,7 @@ main (int argc, char **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, ""); @@ -635,6 +639,8 @@ main (int argc, char **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)); @@ -688,7 +694,7 @@ main (int argc, char **argv) verbose = 1; break; case OPTION_VERSION: - print_version (program_name); + print_version (prog_name); break; case 'e': entry_point = optarg; @@ -734,6 +740,12 @@ main (int argc, char **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; @@ -781,7 +793,7 @@ main (int argc, char **argv) } } - /* sanity checks. */ + /* Sanity checks. */ if (! dll_name && ! dll_file_name) { warn (_("Must provide at least one of -o or --dllname options")); @@ -806,6 +818,7 @@ main (int argc, char **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); @@ -816,7 +829,7 @@ main (int argc, char **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")) @@ -824,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); @@ -869,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); @@ -922,14 +965,11 @@ Creating one, but that may not be what you want")); } } - /* - * Step pre-1. If no --def is specified, then create it - * and then pass it on. - */ + /* Step pre-1. If no --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); @@ -980,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) { @@ -1027,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'; @@ -1053,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)