(linenum→info "unix/slp.c:2238")

binutils/2.18/binutils/dllwrap.c

    1: /* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs
    2:    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
    3:    Free Software Foundation, Inc.
    4:    Contributed by Mumit Khan (khan@xraylith.wisc.edu).
    5: 
    6:    This file is part of GNU Binutils.
    7: 
    8:    This program is free software; you can redistribute it and/or modify
    9:    it under the terms of the GNU General Public License as published by
   10:    the Free Software Foundation; either version 3 of the License, or
   11:    (at your option) any later version.
   12: 
   13:    This program is distributed in the hope that it will be useful,
   14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:    GNU General Public License for more details.
   17: 
   18:    You should have received a copy of the GNU General Public License
   19:    along with this program; if not, write to the Free Software
   20:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   21:    02110-1301, USA.  */
   22: 
   23: /* AIX requires this to be the first thing in the file.  */
   24: #ifndef __GNUC__
   25: # ifdef _AIX
   26:  #pragma alloca
   27: #endif
   28: #endif
   29: 
   30: #include "sysdep.h"
   31: #include "bfd.h"
   32: #include "libiberty.h"
   33: #include "getopt.h"
   34: #include "dyn-string.h"
   35: #include "bucomm.h"
   36: 
   37: #include <time.h>
   38: #include <sys/stat.h>
   39: 
   40: #ifdef HAVE_SYS_WAIT_H
   41: #include <sys/wait.h>
   42: #else /* ! HAVE_SYS_WAIT_H */
   43: #if ! defined (_WIN32) || defined (__CYGWIN32__)
   44: #ifndef WIFEXITED
   45: #define WIFEXITED(w)    (((w)&0377) == 0)
   46: #endif
   47: #ifndef WIFSIGNALED
   48: #define WIFSIGNALED(w)  (((w)&0377) != 0177 && ((w)&~0377) == 0)
   49: #endif
   50: #ifndef WTERMSIG
   51: #define WTERMSIG(w)     ((w) & 0177)
   52: #endif
   53: #ifndef WEXITSTATUS
   54: #define WEXITSTATUS(w)  (((w) >> 8) & 0377)
   55: #endif
   56: #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */
   57: #ifndef WIFEXITED
   58: #define WIFEXITED(w)    (((w) & 0xff) == 0)
   59: #endif
   60: #ifndef WIFSIGNALED
   61: #define WIFSIGNALED(w)  (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
   62: #endif
   63: #ifndef WTERMSIG
   64: #define WTERMSIG(w)     ((w) & 0x7f)
   65: #endif
   66: #ifndef WEXITSTATUS
   67: #define WEXITSTATUS(w)  (((w) & 0xff00) >> 8)
   68: #endif
   69: #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
   70: #endif /* ! HAVE_SYS_WAIT_H */
   71: 
   72: static char *driver_name = NULL;
   73: static char *cygwin_driver_flags =
   74:   "-Wl,--dll -nostartfiles";
   75: static char *mingw32_driver_flags = "-mdll";
   76: static char *generic_driver_flags = "-Wl,--dll";
   77: 
   78: static char *entry_point;
   79: 
   80: static char *dlltool_name = NULL;
   81: 
   82: static char *target = TARGET;
   83: 
   84: typedef enum {
   85:   UNKNOWN_TARGET,
   86:   CYGWIN_TARGET,
   87:   MINGW_TARGET
   88: }
   89: target_type;
   90: 
   91: static target_type which_target = UNKNOWN_TARGET;
   92: 
   93: static int dontdeltemps = 0;
   94: static int dry_run = 0;
   95: 
   96: static char *prog_name;
   97: 
   98: static int verbose = 0;
   99: 
  100: static char *dll_file_name;
  101: static char *dll_name;
  102: static char *base_file_name;
  103: static char *exp_file_name;
  104: static char *def_file_name;
  105: static int delete_base_file = 1;
  106: static int delete_exp_file = 1;
  107: static int delete_def_file = 1;
  108: 
  109: static int run (const char *, char *);
  110: static char *mybasename (const char *);
  111: static int strhash (const char *);
  112: static void usage (FILE *, int);
  113: static void display (const char *, va_list) ATTRIBUTE_PRINTF(1,0);
  114: static void inform (const char *, ...) ATTRIBUTE_PRINTF_1;
  115: static void warn (const char *, ...) ATTRIBUTE_PRINTF_1;
  116: static char *look_for_prog (const char *, const char *, int);
  117: static char *deduce_name (const char *);
  118: static void delete_temp_files (void);
  119: static void cleanup_and_exit (int);
  120: 
  121: /**********************************************************************/
  122: 
  123: /* Please keep the following 4 routines in sync with dlltool.c:
  124:      display ()
  125:      inform ()
  126:      look_for_prog ()
  127:      deduce_name ()
  128:    It's not worth the hassle to break these out since dllwrap will
  129:    (hopefully) soon be retired in favor of `ld --shared.  */
  130: 
  131: static void
  132: display (const char * message, va_list args)
  133: {
  134:   if (prog_name != NULL)
  135:     fprintf (stderr, "%s: ", prog_name);
  136: 
  137:   vfprintf (stderr, message, args);
  138:   fputc ('\n', stderr);
  139: }
  140: 
  141: 
  142: static void
  143: inform VPARAMS ((const char *message, ...))
  144: {
  145:   VA_OPEN (args, message);
  146:   VA_FIXEDARG (args, const char *, message);
  147: 
  148:   if (!verbose)
  149:     return;
  150: 
  151:   display (message, args);
  152: 
  153:   VA_CLOSE (args);
  154: }
  155: 
  156: static void
  157: warn VPARAMS ((const char *format, ...))
  158: {
  159:   VA_OPEN (args, format);
  160:   VA_FIXEDARG (args, const char *, format);
  161: 
  162:   display (format, args);
  163: 
  164:   VA_CLOSE (args);
  165: }
  166: 
  167: /* Look for the program formed by concatenating PROG_NAME and the
  168:    string running from PREFIX to END_PREFIX.  If the concatenated
  169:    string contains a '/', try appending EXECUTABLE_SUFFIX if it is
  170:    appropriate.  */
  171: 
  172: static char *
  173: look_for_prog (const char *prog_name, const char *prefix, int end_prefix)
  174: {
  175:   struct stat s;
  176:   char *cmd;
  177: 
  178:   cmd = xmalloc (strlen (prefix)
  179:                  + strlen (prog_name)
  180: #ifdef HAVE_EXECUTABLE_SUFFIX
  181:                  + strlen (EXECUTABLE_SUFFIX)
  182: #endif
  183:                  + 10);
  184:   strcpy (cmd, prefix);
  185: 
  186:   sprintf (cmd + end_prefix, "%s", prog_name);
  187: 
  188:   if (strchr (cmd, '/') != NULL)
  189:     {
  190:       int found;
  191: 
  192:       found = (stat (cmd, &s) == 0
  193: #ifdef HAVE_EXECUTABLE_SUFFIX
  194:                || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
  195: #endif
  196:                );
  197: 
  198:       if (! found)
  199:         {
  200:           /* xgettext:c-format */
  201:           inform (_("Tried file: %s"), cmd);
  202:           free (cmd);
  203:           return NULL;
  204:         }
  205:     }
  206: 
  207:   /* xgettext:c-format */
  208:   inform (_("Using file: %s"), cmd);
  209: 
  210:   return cmd;
  211: }
  212: 
  213: /* Deduce the name of the program we are want to invoke.
  214:    PROG_NAME is the basic name of the program we want to run,
  215:    eg "as" or "ld".  The catch is that we might want actually
  216:    run "i386-pe-as" or "ppc-pe-ld".
  217: 
  218:    If argv[0] contains the full path, then try to find the program
  219:    in the same place, with and then without a target-like prefix.
  220: 
  221:    Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,
  222:    deduce_name("as") uses the following search order:
  223: 
  224:      /usr/local/bin/i586-cygwin32-as
  225:      /usr/local/bin/as
  226:      as
  227: 
  228:    If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each
  229:    name, it'll try without and then with EXECUTABLE_SUFFIX.
  230: 
  231:    Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"
  232:    as the fallback, but rather return i586-cygwin32-as.
  233: 
  234:    Oh, and given, argv[0] = dlltool, it'll return "as".
  235: 
  236:    Returns a dynamically allocated string.  */
  237: 
  238: static char *
  239: deduce_name (const char * name)
  240: {
  241:   char *cmd;
  242:   const char *dash;
  243:   const char *slash;
  244:   const char *cp;
  245: 
  246:   dash = NULL;
  247:   slash = NULL;
  248:   for (cp = prog_name; *cp != '\0'; ++cp)
  249:     {
  250:       if (*cp == '-')
  251:         dash = cp;
  252: 
  253:       if (
  254: #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)
  255:           *cp == ':' || *cp == '\\' ||
  256: #endif
  257:           *cp == '/')
  258:         {
  259:           slash = cp;
  260:           dash = NULL;
  261:         }
  262:     }
  263: 
  264:   cmd = NULL;
  265: 
  266:   if (dash != NULL)
  267:     /* First, try looking for a prefixed NAME in the
  268:        PROG_NAME directory, with the same prefix as PROG_NAME.  */
  269:     cmd = look_for_prog (name, prog_name, dash - prog_name + 1);
  270: 
  271:   if (slash != NULL && cmd == NULL)
  272:     /* Next, try looking for a NAME in the same directory as
  273:        that of this program.  */
  274:     cmd = look_for_prog (name, prog_name, slash - prog_name + 1);
  275: 
  276:   if (cmd == NULL)
  277:     /* Just return NAME as is.  */
  278:     cmd = xstrdup (name);
  279: 
  280:   return cmd;
  281: }
  282: 
  283: static void
  284: delete_temp_files (void)
  285: {
  286:   if (delete_base_file && base_file_name)
  287:     {
  288:       if (verbose)
  289:         {
  290:           if (dontdeltemps)
  291:             warn (_("Keeping temporary base file %s"), base_file_name);
  292:           else
  293:             warn (_("Deleting temporary base file %s"), base_file_name);
  294:         }
  295:       if (! dontdeltemps)
  296:         {
  297:           unlink (base_file_name);
  298:           free (base_file_name);
  299:         }
  300:     }
  301: 
  302:   if (delete_exp_file && exp_file_name)
  303:     {
  304:       if (verbose)
  305:         {
  306:           if (dontdeltemps)
  307:             warn (_("Keeping temporary exp file %s"), exp_file_name);
  308:           else
  309:             warn (_("Deleting temporary exp file %s"), exp_file_name);
  310:         }
  311:       if (! dontdeltemps)
  312:         {
  313:           unlink (exp_file_name);
  314:           free (exp_file_name);
  315:         }
  316:     }
  317:   if (delete_def_file && def_file_name)
  318:     {
  319:       if (verbose)
  320:         {
  321:           if (dontdeltemps)
  322:             warn (_("Keeping temporary def file %s"), def_file_name);
  323:           else
  324:             warn (_("Deleting temporary def file %s"), def_file_name);
  325:         }
  326:       if (! dontdeltemps)
  327:         {
  328:           unlink (def_file_name);
  329:           free (def_file_name);
  330:         }
  331:     }
  332: }
  333: 
  334: static void
  335: cleanup_and_exit (int status)
  336: {
  337:   delete_temp_files ();
  338:   exit (status);
  339: }
  340: 
  341: static int
  342: run (const char *what, char *args)
  343: {
  344:   char *s;
  345:   int pid, wait_status, retcode;
  346:   int i;
  347:   const char **argv;
  348:   char *errmsg_fmt, *errmsg_arg;
  349:   char *temp_base = choose_temp_base ();
  350:   int in_quote;
  351:   char sep;
  352: 
  353:   if (verbose || dry_run)
  354:     fprintf (stderr, "%s %s\n", what, args);
  355: 
  356:   /* Count the args */
  357:   i = 0;
  358:   for (s = args; *s; s++)
  359:     if (*s == ' ')
  360:       i++;
  361:   i++;
  362:   argv = alloca (sizeof (char *) * (i + 3));
  363:   i = 0;
  364:   argv[i++] = what;
  365:   s = args;
  366:   while (1)
  367:     {
  368:       while (*s == ' ' && *s != 0)
  369:         s++;
  370:       if (*s == 0)
  371:         break;
  372:       in_quote = (*s == '\'' || *s == '"');
  373:       sep = (in_quote) ? *s++ : ' ';
  374:       argv[i++] = s;
  375:       while (*s != sep && *s != 0)
  376:         s++;
  377:       if (*s == 0)
  378:         break;
  379:       *s++ = 0;
  380:       if (in_quote)
  381:         s++;
  382:     }
  383:   argv[i++] = NULL;
  384: 
  385:   if (dry_run)
  386:     return 0;
  387: 
  388:   pid = pexecute (argv[0], (char * const *) argv, prog_name, temp_base,
  389:                   &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);
  390: 
  391:   if (pid == -1)
  392:     {
  393:       int errno_val = errno;
  394: 
  395:       fprintf (stderr, "%s: ", prog_name);
  396:       fprintf (stderr, errmsg_fmt, errmsg_arg);
  397:       fprintf (stderr, ": %s\n", strerror (errno_val));
  398:       return 1;
  399:     }
  400: 
  401:   retcode = 0;
  402:   pid = pwait (pid, &wait_status, 0);
  403:   if (pid == -1)
  404:     {
  405:       warn ("wait: %s", strerror (errno));
  406:       retcode = 1;
  407:     }
  408:   else if (WIFSIGNALED (wait_status))
  409:     {
  410:       warn (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
  411:       retcode = 1;
  412:     }
  413:   else if (WIFEXITED (wait_status))
  414:     {
  415:       if (WEXITSTATUS (wait_status) != 0)
  416:         {
  417:           warn (_("%s exited with status %d"), what, WEXITSTATUS (wait_status));
  418:           retcode = 1;
  419:         }
  420:     }
  421:   else
  422:     retcode = 1;
  423: 
  424:   return retcode;
  425: }
  426: 
  427: static char *
  428: mybasename (const char *name)
  429: {
  430:   const char *base = name;
  431: 
  432:   while (*name)
  433:     {
  434:       if (*name == '/' || *name == '\\')
  435:         {
  436:           base = name + 1;
  437:         }
  438:       ++name;
  439:     }
  440:   return (char *) base;
  441: }
  442: 
  443: static int
  444: strhash (const char *str)
  445: {
  446:   const unsigned char *s;
  447:   unsigned long hash;
  448:   unsigned int c;
  449:   unsigned int len;
  450: 
  451:   hash = 0;
  452:   len = 0;
  453:   s = (const unsigned char *) str;
  454:   while ((c = *s++) != '\0')
  455:     {
  456:       hash += c + (c << 17);
  457:       hash ^= hash >> 2;
  458:       ++len;
  459:     }
  460:   hash += len + (len << 17);
  461:   hash ^= hash >> 2;
  462: 
  463:   return hash;
  464: }
  465: 
  466: /**********************************************************************/
  467: 
  468: static void
  469: usage (FILE *file, int status)
  470: {
  471:   fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), prog_name);
  472:   fprintf (file, _("  Generic options:\n"));
  473:   fprintf (file, _("   @<file>                Read options from <file>\n"));    
  474:   fprintf (file, _("   --quiet, -q            Work quietly\n"));
  475:   fprintf (file, _("   --verbose, -v          Verbose\n"));
  476:   fprintf (file, _("   --version              Print dllwrap version\n"));
  477:   fprintf (file, _("   --implib <outname>     Synonym for --output-lib\n"));
  478:   fprintf (file, _("  Options for %s:\n"), prog_name);
  479:   fprintf (file, _("   --driver-name <driver> Defaults to \"gcc\"\n"));
  480:   fprintf (file, _("   --driver-flags <flags> Override default ld flags\n"));
  481:   fprintf (file, _("   --dlltool-name <dlltool> Defaults to \"dlltool\"\n"));
  482:   fprintf (file, _("   --entry <entry>        Specify alternate DLL entry point\n"));
  483:   fprintf (file, _("   --image-base <base>    Specify image base address\n"));
  484:   fprintf (file, _("   --target <machine>     i386-cygwin32 or i386-mingw32\n"));
  485:   fprintf (file, _("   --dry-run              Show what needs to be run\n"));
  486:   fprintf (file, _("   --mno-cygwin           Create Mingw DLL\n"));
  487:   fprintf (file, _("  Options passed to DLLTOOL:\n"));
  488:   fprintf (file, _("   --machine <machine>\n"));
  489:   fprintf (file, _("   --output-exp <outname> Generate export file.\n"));
  490:   fprintf (file, _("   --output-lib <outname> Generate input library.\n"));
  491:   fprintf (file, _("   --add-indirect         Add dll indirects to export file.\n"));
  492:   fprintf (file, _("   --dllname <name>       Name of input dll to put into output lib.\n"));
  493:   fprintf (file, _("   --def <deffile>        Name input .def file\n"));
  494:   fprintf (file, _("   --output-def <deffile> Name output .def file\n"));
  495:   fprintf (file, _("   --export-all-symbols     Export all symbols to .def\n"));
  496:   fprintf (file, _("   --no-export-all-symbols  Only export .drectve symbols\n"));
  497:   fprintf (file, _("   --exclude-symbols <list> Exclude <list> from .def\n"));
  498:   fprintf (file, _("   --no-default-excludes    Zap default exclude symbols\n"));
  499:   fprintf (file, _("   --base-file <basefile> Read linker generated base file\n"));
  500:   fprintf (file, _("   --no-idata4           Don't generate idata$4 section\n"));
  501:   fprintf (file, _("   --no-idata5           Don't generate idata$5 section\n"));
  502:   fprintf (file, _("   -U                     Add underscores to .lib\n"));
  503:   fprintf (file, _("   -k                     Kill @<n> from exported names\n"));
  504:   fprintf (file, _("   --add-stdcall-alias    Add aliases without @<n>\n"));
  505:   fprintf (file, _("   --as <name>            Use <name> for assembler\n"));
  506:   fprintf (file, _("   --nodelete             Keep temp files.\n"));
  507:   fprintf (file, _("  Rest are passed unmodified to the language driver\n"));
  508:   fprintf (file, "\n\n");
  509:   if (REPORT_BUGS_TO[0] && status == 0)
  510:     fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
  511:   exit (status);
  512: }
  513: 
  514: #define OPTION_START            149
  515: 
  516: /* GENERIC options.  */
  517: #define OPTION_QUIET            (OPTION_START + 1)
  518: #define OPTION_VERBOSE          (OPTION_QUIET + 1)
  519: #define OPTION_VERSION          (OPTION_VERBOSE + 1)
  520: 
  521: /* DLLWRAP options.  */
  522: #define OPTION_DRY_RUN          (OPTION_VERSION + 1)
  523: #define OPTION_DRIVER_NAME      (OPTION_DRY_RUN + 1)
  524: #define OPTION_DRIVER_FLAGS     (OPTION_DRIVER_NAME + 1)
  525: #define OPTION_DLLTOOL_NAME     (OPTION_DRIVER_FLAGS + 1)
  526: #define OPTION_ENTRY            (OPTION_DLLTOOL_NAME + 1)
  527: #define OPTION_IMAGE_BASE       (OPTION_ENTRY + 1)
  528: #define OPTION_TARGET           (OPTION_IMAGE_BASE + 1)
  529: #define OPTION_MNO_CYGWIN       (OPTION_TARGET + 1)
  530: 
  531: /* DLLTOOL options.  */
  532: #define OPTION_NODELETE         (OPTION_MNO_CYGWIN + 1)
  533: #define OPTION_DLLNAME          (OPTION_NODELETE + 1)
  534: #define OPTION_NO_IDATA4        (OPTION_DLLNAME + 1)
  535: #define OPTION_NO_IDATA5        (OPTION_NO_IDATA4 + 1)
  536: #define OPTION_OUTPUT_EXP       (OPTION_NO_IDATA5 + 1)
  537: #define OPTION_OUTPUT_DEF       (OPTION_OUTPUT_EXP + 1)
  538: #define OPTION_EXPORT_ALL_SYMS  (OPTION_OUTPUT_DEF + 1)
  539: #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1)
  540: #define OPTION_EXCLUDE_SYMS     (OPTION_NO_EXPORT_ALL_SYMS + 1)
  541: #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1)
  542: #define OPTION_OUTPUT_LIB       (OPTION_NO_DEFAULT_EXCLUDES + 1)
  543: #define OPTION_DEF              (OPTION_OUTPUT_LIB + 1)
  544: #define OPTION_ADD_UNDERSCORE   (OPTION_DEF + 1)
  545: #define OPTION_KILLAT           (OPTION_ADD_UNDERSCORE + 1)
  546: #define OPTION_HELP             (OPTION_KILLAT + 1)
  547: #define OPTION_MACHINE          (OPTION_HELP + 1)
  548: #define OPTION_ADD_INDIRECT     (OPTION_MACHINE + 1)