⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 collect2.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (c == '\0')	break;      ++p;      if (backquote)	obstack_1grow (&temporary_obstack, c);      else if (! inside && c == ' ')	break;      else if (! inside && c == '\\')	backquote = 1;      else if (c == '\'')	inside = !inside;      else	obstack_1grow (&temporary_obstack, c);    }  obstack_1grow (&temporary_obstack, '\0');  *pp = p;  return obstack_finish (&temporary_obstack);}voiddump_file (name)     char *name;{  FILE *stream = fopen (name, "r");  int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");  if (stream == 0)    return;  while (1)    {      int c;      while (c = getc (stream),	     c != EOF && (isalnum (c) || c == '_' || c == '$' || c == '.'))	obstack_1grow (&temporary_obstack, c);      if (obstack_object_size (&temporary_obstack) > 0)	{	  char *word, *p, *result;	  obstack_1grow (&temporary_obstack, '\0');	  word = obstack_finish (&temporary_obstack);	  if (*word == '.')	    ++word, putc ('.', stderr);	  p = word;	  if (*p == '_' && prepends_underscore)	    ++p;	  if (no_demangle)	    result = 0;	  else	    result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI);	  if (result)	    {	      int diff;	      fputs (result, stderr);	      diff = strlen (word) - strlen (result);	      while (diff > 0)		--diff, putc (' ', stderr);	      while (diff < 0 && c == ' ')		++diff, c = getc (stream);	      free (result);	    }	  else	    fputs (word, stderr);	  fflush (stderr);	  obstack_free (&temporary_obstack, temporary_firstobj);	}      if (c == EOF)	break;      putc (c, stderr);    }  fclose (stream);}/* Decide whether the given symbol is:   a constructor (1), a destructor (2), or neither (0).  */static intis_ctor_dtor (s)     char *s;{  struct names { char *name; int len; int ret; int two_underscores; };  register struct names *p;  register int ch;  register char *orig_s = s;  static struct names special[] = {#ifdef NO_DOLLAR_IN_LABEL#ifdef NO_DOT_IN_LABEL    { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },    { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },    { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },#else    { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },    { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },    { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 },#endif#else    { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },    { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },    { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 },#endif    { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },    { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },#ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.			 cfront has its own linker procedure to collect them;			 if collect2 gets them too, they get collected twice			 when the cfront procedure is run and the compiler used			 for linking happens to be GCC.  */    { "sti__", sizeof ("sti__")-1, 1, 1 },    { "std__", sizeof ("std__")-1, 2, 1 },#endif /* CFRONT_LOSSAGE */    { NULL, 0, 0, 0 }  };  while ((ch = *s) == '_')    ++s;  if (s == orig_s)    return 0;  for (p = &special[0]; p->len > 0; p++)    {      if (ch == p->name[0]	  && (!p->two_underscores || ((s - orig_s) >= 2))	  && strncmp(s, p->name, p->len) == 0)	{	  return p->ret;	}    }  return 0;}/* Routine to add variables to the environment.  */#ifndef HAVE_PUTENVintputenv (str)     char *str;{#ifndef VMS			/* nor about VMS */  extern char **environ;  char **old_environ = environ;  char **envp;  int num_envs = 0;  int name_len = 1;  char *p = str;  int ch;  while ((ch = *p++) != '\0' && ch != '=')    name_len++;  if (!ch)    abort ();  /* Search for replacing an existing environment variable, and     count the number of total environment variables.  */  for (envp = old_environ; *envp; envp++)    {      num_envs++;      if (!strncmp (str, *envp, name_len))	{	  *envp = str;	  return 0;	}    }  /* Add a new environment variable */  environ = (char **) xmalloc (sizeof (char *) * (num_envs+2));  *environ = str;  bcopy ((char *) old_environ, (char *) (environ + 1),	 sizeof (char *) * (num_envs+1));  return 0;#endif	/* VMS */}#endif	/* HAVE_PUTENV *//* By default, colon separates directories in a path.  */#ifndef PATH_SEPARATOR#define PATH_SEPARATOR ':'#endif/* We maintain two prefix lists: one from COMPILER_PATH environment variable   and one from the PATH variable.  */static struct path_prefix cpath, path;#ifdef CROSS_COMPILE/* This is the name of the target machine.  We use it to form the name   of the files to execute.  */static char *target_machine = TARGET_MACHINE;#endif/* Names under which we were executed.  Never return one of those files in our   searches.  */static struct path_prefix our_file_names;/* Determine if STRING is in PPREFIX.   This utility is currently only used to look up file names.  Prefix lists   record directory names.  This matters to us because the latter has a    trailing slash, so I've added a flag to handle both.  */static intis_in_prefix_list (pprefix, string, filep)     struct path_prefix *pprefix;     char *string;     int filep;{  struct prefix_list *pl;  if (filep)    {      int len = strlen (string);      for (pl = pprefix->plist; pl; pl = pl->next)	{	  if (strncmp (pl->prefix, string, len) == 0	      && strcmp (pl->prefix + len, "/") == 0)	    return 1;	}    }  else    {      for (pl = pprefix->plist; pl; pl = pl->next)	{	  if (strcmp (pl->prefix, string) == 0)	    return 1;	}    }  return 0;}/* Search for NAME using prefix list PPREFIX.  We only look for executable   files.    Return 0 if not found, otherwise return its name, allocated with malloc.  */static char *find_a_file (pprefix, name)     struct path_prefix *pprefix;     char *name;{  char *temp;  struct prefix_list *pl;  int len = pprefix->max_len + strlen (name) + 1;#ifdef EXECUTABLE_SUFFIX  len += strlen (EXECUTABLE_SUFFIX);#endif  temp = xmalloc (len);  /* Determine the filename to execute (special case for absolute paths).  */  if (*name == '/')    {      if (access (name, X_OK) == 0)	{	  strcpy (temp, name);	  return temp;	}    }  else    for (pl = pprefix->plist; pl; pl = pl->next)      {	strcpy (temp, pl->prefix);	strcat (temp, name);	if (! is_in_prefix_list (&our_file_names, temp, 1)	    /* This is a kludge, but there seems no way around it.  */	    && strcmp (temp, "./ld") != 0	    && access (temp, X_OK) == 0)	  return temp;#ifdef EXECUTABLE_SUFFIX	/* Some systems have a suffix for executable files.	   So try appending that.  */	strcat (temp, EXECUTABLE_SUFFIX);	if (! is_in_prefix_list (&our_file_names, temp, 1)	    && access (temp, X_OK) == 0)	  return temp;#endif      }  free (temp);  return 0;}/* Add an entry for PREFIX to prefix list PPREFIX.  */static voidadd_prefix (pprefix, prefix)     struct path_prefix *pprefix;     char *prefix;{  struct prefix_list *pl, **prev;  int len;  if (pprefix->plist)    {      for (pl = pprefix->plist; pl->next; pl = pl->next)	;      prev = &pl->next;    }  else    prev = &pprefix->plist;  /* Keep track of the longest prefix */  len = strlen (prefix);  if (len > pprefix->max_len)    pprefix->max_len = len;  pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));  pl->prefix = savestring (prefix, len);  if (*prev)    pl->next = *prev;  else    pl->next = (struct prefix_list *) 0;  *prev = pl;}/* Take the value of the environment variable ENV, break it into a path, and   add of the entries to PPREFIX.  */static voidprefix_from_env (env, pprefix)     char *env;     struct path_prefix *pprefix;{  char *p = getenv (env);  if (p)    prefix_from_string (p, pprefix);}static voidprefix_from_string (p, pprefix)     char *p;     struct path_prefix *pprefix;{  char *startp, *endp;  char *nstore = (char *) xmalloc (strlen (p) + 3);  startp = endp = p;  while (1)    {      if (*endp == PATH_SEPARATOR || *endp == 0)	{	  strncpy (nstore, startp, endp-startp);	  if (endp == startp)	    {	      strcpy (nstore, "./");	    }	  else if (endp[-1] != '/')	    {	      nstore[endp-startp] = '/';	      nstore[endp-startp+1] = 0;	    }	  else	    nstore[endp-startp] = 0;	  add_prefix (pprefix, nstore);	  if (*endp == 0)	    break;	  endp = startp = endp + 1;	}      else	endp++;    }}/* Main program.  */intmain (argc, argv)     int argc;     char *argv[];{  char *ld_suffix	= "ld";  char *full_ld_suffix	= ld_suffix;  char *real_ld_suffix	= "real-ld";  char *full_real_ld_suffix = real_ld_suffix;  char *collect_ld_suffix = "collect-ld";  char *nm_suffix	= "nm";  char *full_nm_suffix	= nm_suffix;  char *gnm_suffix	= "gnm";  char *full_gnm_suffix	= gnm_suffix;#ifdef LDD_SUFFIX  char *ldd_suffix	= LDD_SUFFIX;  char *full_ldd_suffix	= ldd_suffix;#endif  char *strip_suffix	= "strip";  char *full_strip_suffix = strip_suffix;  char *gstrip_suffix	= "gstrip";  char *full_gstrip_suffix = gstrip_suffix;  char *arg;  FILE *outf, *exportf;  char *ld_file_name;  char *collect_name;  char *collect_names;  char *p;  char **c_argv;  char **c_ptr;  char **ld1_argv	= (char **) xcalloc (sizeof (char *), argc+3);  char **ld1		= ld1_argv;  char **ld2_argv	= (char **) xcalloc (sizeof (char *), argc+6);  char **ld2		= ld2_argv;  char **object_lst	= (char **) xcalloc (sizeof (char *), argc);  char **object		= object_lst;  int first_file;  int num_c_args	= argc+7;#ifdef DEBUG  debug = 1;  vflag = 1;#endif#ifndef DEFAULT_A_OUT_NAME  output_file = "a.out";#else  output_file = DEFAULT_A_OUT_NAME;#endif  obstack_begin (&temporary_obstack, 0);  obstack_begin (&permanent_obstack, 0);  temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);  current_demangling_style = gnu_demangling;  /* We must check that we do not call ourselves in an infinite     recursion loop. We append the name used for us to the COLLECT_NAMES     environment variable.     In practice, collect will rarely invoke itself.  This can happen now     that we are no longer called gld.  A perfect example is when running     gcc in a build directory that has been installed.  When looking for      ld's, we'll find our installed version and believe that's the real ld.  */  /* We must also append COLLECT_NAME to COLLECT_NAMES to watch for the     previous version of collect (the one that used COLLECT_NAME and only     handled two levels of recursion).  If we don't we may mutually recurse     forever.  This can happen (I think) when bootstrapping the old version     and a new one is installed (rare, but we should handle it).     ??? Hopefully references to COLLECT_NAME can be removed at some point.  */  collect_name = (char *) getenv ("COLLECT_NAME");  collect_names = (char *) getenv ("COLLECT_NAMES");  p = (char *) xmalloc (strlen ("COLLECT_NAMES=")			+ (collect_name ? strlen (collect_name) + 1 : 0)			+ (collect_names ? strlen (collect_names) + 1 : 0)			+ strlen (argv[0]) + 1);  strcpy (p, "COLLECT_NAMES=");  if (collect_name != 0)    sprintf (p + strlen (p), "%s%c", collect_name, PATH_SEPARATOR);  if (collect_names != 0)    sprintf (p + strlen (p), "%s%c", collect_names, PATH_SEPARATOR);  strcat (p, argv[0]);  putenv (p);  prefix_from_env ("COLLECT_NAMES", &our_file_names);  /* Set environment variable COLLECT_NAME to our name so the previous version     of collect won't find us.  If it does we'll mutually recurse forever.     This can happen when bootstrapping the new version and an old version is     installed.     ??? Hopefully this bit of code can be removed at some point.  */  p = xmalloc (strlen ("COLLECT_NAME=") + strlen (argv[0]) + 1);  sprintf (p, "COLLECT_NAME=%s", argv[0]);  putenv (p);  p = (char *) getenv ("COLLECT_GCC_OPTIONS");  while (p && *p)    {      char *q = extract_string (&p);      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))	num_c_args++;    }  obstack_free (&temporary_obstack, temporary_firstobj);  ++num_c_args;  c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);  if (argc < 2)    fatal ("no arguments");#ifdef SIGQUIT  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)    signal (SIGQUIT, handler);#endif  if (signal (SIGINT, SIG_IGN) != SIG_IGN)    signal (SIGINT, handler);#ifdef SIGALRM  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)    signal (SIGALRM, handler);#endif#ifdef SIGHUP  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)    signal (SIGHUP, handler);#endif  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)    signal (SIGSEGV, handler);#ifdef SIGBUS  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)    signal (SIGBUS, handler);#endif  /* Extract COMPILER_PATH and PATH into our prefix list.  */  prefix_from_env ("COMPILER_PATH", &cpath);  prefix_from_env ("PATH", &path);#ifdef CROSS_COMPILE

⌨️ 快捷键说明

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