dllwrap.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,250 行 · 第 1/3 页

C
1,250
字号
/* dllwrap.c -- wrapper for DLLTOOL and GCC to generate PE style DLLs   Copyright 1998, 1999, 2000 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   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   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#include "bfd.h"#include "libiberty.h"#include "bucomm.h"#include "getopt.h"#include "dyn-string.h"#include <ctype.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>#else /* ! HAVE_SYS_WAIT_H */#if ! defined (_WIN32) || defined (__CYGWIN32__)#ifndef WIFEXITED#define WIFEXITED(w)	(((w)&0377) == 0)#endif#ifndef WIFSIGNALED#define WIFSIGNALED(w)	(((w)&0377) != 0177 && ((w)&~0377) == 0)#endif#ifndef WTERMSIG#define WTERMSIG(w)	((w) & 0177)#endif#ifndef WEXITSTATUS#define WEXITSTATUS(w)	(((w) >> 8) & 0377)#endif#else /* defined (_WIN32) && ! defined (__CYGWIN32__) */#ifndef WIFEXITED#define WIFEXITED(w)	(((w) & 0xff) == 0)#endif#ifndef WIFSIGNALED#define WIFSIGNALED(w)	(((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)#endif#ifndef WTERMSIG#define WTERMSIG(w)	((w) & 0x7f)#endif#ifndef WEXITSTATUS#define WEXITSTATUS(w)	(((w) & 0xff00) >> 8)#endif#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */#endif /* ! HAVE_SYS_WAIT_H */static char *driver_name = NULL;static char *cygwin_driver_flags =   "-Wl,--dll -nostartfiles";static char *mingw32_driver_flags = "-mdll";static char *generic_driver_flags = "-Wl,--dll";static char *entry_point;static char *dlltool_name = NULL;static char *target = TARGET;typedef enum {  UNKNOWN_TARGET,   CYGWIN_TARGET,   MINGW_TARGET} target_type;static target_type which_target = UNKNOWN_TARGET;static int dontdeltemps = 0;static int dry_run = 0;static char *program_name;static int verbose = 0;static char *dll_file_name;static char *dll_name;static char *base_file_name;static char *exp_file_name;static char *def_file_name;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 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 *format, ...));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 status));/**********************************************************************//* Please keep the following 4 routines in sync with dlltool.c:     display ()     inform ()     look_for_prog ()     deduce_name ()   It's not worth the hassle to break these out since dllwrap will   (hopefully) soon be retired in favor of `ld --shared.  */static voiddisplay (message, args)     const char * message;     va_list      args;{  if (program_name != NULL)    fprintf (stderr, "%s: ", program_name);  vfprintf (stderr, message, args);  fputc ('\n', stderr);}#ifdef __STDC__static voidinform (const char * message, ...){  va_list args;  if (!verbose)    return;  va_start (args, message);  display (message, args);  va_end (args);}static voidwarn (const char *format, ...){  va_list args;  va_start (args, format);  display (format, args);  va_end (args);}#elsestatic voidinform (message, va_alist)     const char * message;     va_dcl{  va_list args;  if (!verbose)    return;  va_start (args);  display (message, args);  va_end (args);}static voidwarn (format, va_alist)     const char *format;     va_dcl{  va_list args;  va_start (args);  display (format, args);  va_end (args);}#endif/* Look for the program formed by concatenating PROG_NAME and the   string running from PREFIX to END_PREFIX.  If the concatenated   string contains a '/', try appending EXECUTABLE_SUFFIX if it is   appropriate.  */static char *look_for_prog (prog_name, prefix, end_prefix)     const char *prog_name;     const char *prefix;     int end_prefix;{  struct stat s;  char *cmd;  cmd = xmalloc (strlen (prefix)                  + strlen (prog_name) #ifdef HAVE_EXECUTABLE_SUFFIX                 + strlen (EXECUTABLE_SUFFIX) #endif		 + 10);  strcpy (cmd, prefix);  sprintf (cmd + end_prefix, "%s", prog_name);  if (strchr (cmd, '/') != NULL)    {      int found;      found = (stat (cmd, &s) == 0#ifdef HAVE_EXECUTABLE_SUFFIX               || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0#endif	       );      if (! found)        {	  /* xgettext:c-format */	  inform (_("Tried file: %s"), cmd);	  free (cmd);	  return NULL;	}    }  /* xgettext:c-format */  inform (_("Using file: %s"), cmd);  return cmd;}/* Deduce the name of the program we are want to invoke.   PROG_NAME is the basic name of the program we want to run,   eg "as" or "ld".  The catch is that we might want actually   run "i386-pe-as" or "ppc-pe-ld".     If argv[0] contains the full path, then try to find the program   in the same place, with and then without a target-like prefix.   Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool,   deduce_name("as") uses the following search order:      /usr/local/bin/i586-cygwin32-as     /usr/local/bin/as     as      If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each   name, it'll try without and then with EXECUTABLE_SUFFIX.   Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as"   as the fallback, but rather return i586-cygwin32-as.        Oh, and given, argv[0] = dlltool, it'll return "as".   Returns a dynamically allocated string.  */static char *deduce_name (prog_name)     const char *prog_name;{  char *cmd;  char *dash, *slash, *cp;  dash = NULL;  slash = NULL;  for (cp = program_name; *cp != '\0'; ++cp)    {      if (*cp == '-')	dash = cp;      if (#if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__)	  *cp == ':' || *cp == '\\' ||#endif	  *cp == '/')	{	  slash = cp;	  dash = NULL;	}    }  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);    }  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);    }  if (cmd == NULL)    {      /* Just return PROG_NAME as is.  */      cmd = xstrdup (prog_name);    }  return cmd;}static voiddelete_temp_files (){  if (delete_base_file && base_file_name)    {      if (verbose)	{	  if (dontdeltemps)	    warn (_("Keeping temporary base file %s"), base_file_name);	  else	    warn (_("Deleting temporary base file %s"), base_file_name);	}      if (! dontdeltemps)        {          unlink (base_file_name);	  free (base_file_name);	}    }    if (delete_exp_file && exp_file_name)    {      if (verbose)	{	  if (dontdeltemps)	    warn (_("Keeping temporary exp file %s"), exp_file_name);	  else	    warn (_("Deleting temporary exp file %s"), exp_file_name);	}      if (! dontdeltemps)        {          unlink (exp_file_name);          free (exp_file_name);	}    }  if (delete_def_file && def_file_name)    {      if (verbose)	{	  if (dontdeltemps)	    warn (_("Keeping temporary def file %s"), def_file_name);	  else	    warn (_("Deleting temporary def file %s"), def_file_name);	}      if (! dontdeltemps)        {          unlink (def_file_name);          free (def_file_name);	}    }}static void cleanup_and_exit (int status){  delete_temp_files ();  exit (status);}  static intrun (what, args)     const char *what;     char *args;{  char *s;  int pid, wait_status, retcode;  int i;  const char **argv;  char *errmsg_fmt, *errmsg_arg;  char *temp_base = choose_temp_base ();  int in_quote;  char sep;  if (verbose || dry_run)    fprintf (stderr, "%s %s\n", what, args);  /* Count the args */  i = 0;  for (s = args; *s; s++)    if (*s == ' ')      i++;  i++;  argv = alloca (sizeof (char *) * (i + 3));  i = 0;  argv[i++] = what;  s = args;  while (1)    {      while (*s == ' ' && *s != 0)	s++;      if (*s == 0)	break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?