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

📄 collect2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
      }  c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args);  if (argc < 2)    fatal ("no arguments");  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)    signal (SIGQUIT, handler);  if (signal (SIGINT, SIG_IGN) != SIG_IGN)    signal (SIGINT, handler);  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)    signal (SIGALRM, handler);  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)    signal (SIGHUP, handler);  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)    signal (SIGSEGV, handler);  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)    signal (SIGBUS, handler);  /* Try to discover a valid linker/assembler/nm/strip to use.  */  len = strlen (argv[0]);  prefix = (char *)0;  if (len >= sizeof ("ld")-1)    {      p = argv[0] + len - sizeof ("ld") + 1;      if (strcmp (p, "ld") == 0)	{	  prefix = argv[0];	  *p = '\0';	}    }  if (prefix == (char *)0)    {      p = rindex (argv[0], '/');      if (p != (char *)0)	{	  prefix = argv[0];	  p[1] = '\0';	}#ifdef STANDARD_EXEC_PREFIX      else if (access (STANDARD_EXEC_PREFIX, X_OK) == 0)	prefix = STANDARD_EXEC_PREFIX;#endif#ifdef MD_EXEC_PREFIX      else if (access (MD_EXEC_PREFIX, X_OK) == 0)	prefix = MD_EXEC_PREFIX;#endif      else if (access ("/usr/ccs/gcc", X_OK) == 0)	prefix = "/usr/ccs/gcc/";      else if (access ("/usr/ccs/bin", X_OK) == 0)	prefix = "/usr/ccs/bin/";      else	prefix = "/bin/";    }  clen = len = strlen (prefix);#ifdef STANDARD_BIN_PREFIX  if (clen < sizeof (STANDARD_BIN_PREFIX) - 1)    clen = sizeof (STANDARD_BIN_PREFIX) - 1;#endif#ifdef STANDARD_EXEC_PREFIX  if (clen < sizeof (STANDARD_EXEC_PREFIX) - 1)    clen = sizeof (STANDARD_EXEC_PREFIX) - 1;#endif  /* Allocate enough string space for the longest possible pathnames.  */  ld_file_name = xcalloc (len + sizeof ("real-ld"), 1);  nm_file_name = xcalloc (len + sizeof ("gnm"), 1);  strip_file_name = xcalloc (len + sizeof ("gstrip"), 1);  /* Determine the full path name of the ld program to use.  */  bcopy (prefix, ld_file_name, len);  strcpy (ld_file_name + len, "real-ld");  if (access (ld_file_name, X_OK) < 0)    {      strcpy (ld_file_name + len, "gld");      if (access (ld_file_name, X_OK) < 0)	{	  free (ld_file_name);#ifdef REAL_LD_FILE_NAME	  ld_file_name = REAL_LD_FILE_NAME;#else	  ld_file_name = (access ("/usr/bin/ld", X_OK) == 0			  ? "/usr/bin/ld" : "/bin/ld");#endif	}    }  /* Determine the full path name of the C compiler to use.  */  c_file_name = getenv ("COLLECT_GCC");  /* If this is absolute, it must be a file that exists.     If it is relative, it must be something that execvp was able to find.     Either way, we can pass it to execvp and find the same executable.  */  if (c_file_name == 0)    {      c_file_name = xcalloc (clen + sizeof ("gcc"), 1);      bcopy (prefix, c_file_name, len);      strcpy (c_file_name + len, "gcc");      if (access (c_file_name, X_OK) < 0)	{#ifdef STANDARD_BIN_PREFIX	  strcpy (c_file_name, STANDARD_BIN_PREFIX);	  strcat (c_file_name, "gcc");	  if (access (c_file_name, X_OK) < 0)#endif	    {#ifdef STANDARD_EXEC_PREFIX	      strcpy (c_file_name, STANDARD_EXEC_PREFIX);	      strcat (c_file_name, "gcc");	      if (access (c_file_name, X_OK) < 0)#endif		{		  strcpy (c_file_name, "gcc");		}	    }	}    }  /* Determine the full path name of the nm to use.  */  bcopy (prefix, nm_file_name, len);  strcpy (nm_file_name + len, "nm");  if (access (nm_file_name, X_OK) < 0)    {      strcpy (nm_file_name + len, "gnm");      if (access (nm_file_name, X_OK) < 0)	{	  free (nm_file_name);#ifdef REAL_NM_FILE_NAME	  nm_file_name = REAL_NM_FILE_NAME;#else	  nm_file_name = (access ("/usr/bin/nm", X_OK) == 0			  ? "/usr/bin/nm" : "/bin/nm");#endif	}    }  /* Determine the full pathname of the strip to use.  */  bcopy (prefix, strip_file_name, len);  strcpy (strip_file_name + len, "strip");  if (access (strip_file_name, X_OK) < 0)    {      strcpy (strip_file_name + len, "gstrip");      if (access (strip_file_name, X_OK) < 0)	{	  free (strip_file_name);#ifdef REAL_STRIP_FILE_NAME	  strip_file_name = REAL_STRIP_FILE_NAME;#else	  strip_file_name = (access ("/usr/bin/strip", X_OK) == 0			     ? "/usr/bin/strip" : "/bin/strip");#endif	}    }  *ld1++ = *ld2++ = "ld";  /* Make temp file names. */  choose_temp_base ();  c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);  o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);  sprintf (c_file, "%s.c", temp_filename);  sprintf (o_file, "%s.o", temp_filename);  *c_ptr++ = c_file_name;  *c_ptr++ = "-c";  *c_ptr++ = "-o";  *c_ptr++ = o_file;  /* !!! When GCC calls collect2,     it does not know whether it is calling collect2 or ld.     So collect2 cannot meaningfully understand any options     except those ld understands.     If you propose to make GCC pass some other option,     just imagine what will happen if ld is really ld!!!  */  /* Parse arguments.  Remember output file spec, pass the rest to ld. */  /* After the first file, put in the c++ rt0.  */  first_file = 1;  while ((arg = *++argv) != (char *)0)    {      *ld1++ = *ld2++ = arg;      if (arg[0] == '-')	  switch (arg[1])	    {	    case 'd':	      if (!strcmp (arg, "-debug"))		{		  debug = 1;		  vflag = 1;		  ld1--;		  ld2--;		}	      break;	    case 'o':	      outfile = (arg[2] == '\0') ? argv[1] : &arg[2];	      break;	    case 'r':	      if (arg[2] == '\0')		rflag = 1;	      break;	    case 's':	      if (arg[2] == '\0')		{		  /* We must strip after the nm run, otherwise C++ linking		     won't work.  Thus we strip in the second ld run, or		     else with strip if there is no second ld run.  */		  strip_flag = 1;		  ld1--;		}	      break;	    case 'v':	      if (arg[2] == '\0')		vflag = 1;	      break;	    }      else if (first_file	       && (p = rindex (arg, '.')) != (char *)0	       && strcmp (p, ".o") == 0)	{	  first_file = 0;	  *ld2++ = o_file;	}    }  /* Get any options that the upper GCC wants to pass to the sub-GCC.  */  p = (char *) getenv ("COLLECT_GCC_OPTIONS");  if (p)    while (*p)      {	char *q = p;	while (*q && *q != ' ') q++;	if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))	  *c_ptr++ = savestring (p, q - p);	if (*q) q++;	p = q;      }  *c_ptr++ = c_file;  *c_ptr = *ld1 = *ld2 = (char *)0;  if (vflag)    {      fprintf (stderr, "collect2 version %s", version_string);#ifdef TARGET_VERSION      TARGET_VERSION;#endif      fprintf (stderr, "\n");    }  if (debug)    {      char *ptr;      fprintf (stderr, "prefix              = %s\n", prefix);      fprintf (stderr, "ld_file_name        = %s\n", ld_file_name);      fprintf (stderr, "c_file_name         = %s\n", c_file_name);      fprintf (stderr, "nm_file_name        = %s\n", nm_file_name);      fprintf (stderr, "c_file              = %s\n", c_file);      fprintf (stderr, "o_file              = %s\n", o_file);      ptr = getenv ("COLLECT_GCC_OPTIONS");      if (ptr)	fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr);      ptr = getenv ("COLLECT_GCC");      if (ptr)	fprintf (stderr, "COLLECT_GCC         = %s\n", ptr);      ptr = getenv ("COMPILER_PATH");      if (ptr)	fprintf (stderr, "COMPILER_PATH       = %s\n", ptr);      ptr = getenv ("LIBRARY_PATH");      if (ptr)	fprintf (stderr, "LIBRARY_PATH        = %s\n", ptr);      fprintf (stderr, "\n");    }  /* Load the program, searching all libraries.     Examine the namelist with nm and search it for static constructors     and destructors to call.     Write the constructor and destructor tables to a .s file and reload. */  fork_execute (ld_file_name, ld1_argv);  /* If -r, don't build the constructor or destructor list, just return now.  */  if (rflag)    return 0;  scan_prog_file (outfile, PASS_FIRST);  if (debug)    {      fprintf (stderr, "%d constructor(s) found\n", constructors.number);      fprintf (stderr, "%d destructor(s)  found\n", destructors.number);    }  if (constructors.number == 0 && destructors.number == 0)    {      /* Strip now if it was requested on the command line.  */      if (strip_flag)	{	  char **strip_argv = (char **) xcalloc (sizeof (char *), 3);	  strip_argv[0] = "strip";	  strip_argv[1] = outfile;	  strip_argv[2] = (char *) 0;	  fork_execute (strip_file_name, strip_argv);	}      return 0;    }  outf = fopen (c_file, "w");  if (outf == (FILE *)0)    fatal_perror ("%s", c_file);  write_c_file (outf, c_file);  if (fclose (outf))    fatal_perror ("closing %s", c_file);  if (debug)    {      fprintf (stderr, "\n========== outfile = %s, c_file = %s\n", outfile, c_file);      write_c_file (stderr, "stderr");      fprintf (stderr, "========== end of c_file\n\n");    }  /* Assemble the constructor and destructor tables.     Link the tables in with the rest of the program. */  fork_execute (c_file_name,  c_argv);  fork_execute (ld_file_name, ld2_argv);  /* Let scan_prog_file do any final mods (OSF/rose needs this for     constructors/destructors in shared libraries.  */  scan_prog_file (outfile, PASS_SECOND);  maybe_unlink (c_file);  maybe_unlink (o_file);  return 0;}/* Wait for a process to finish, and exit if a non-zero status is found. */static voiddo_wait (prog)     char *prog;{  int status;  wait (&status);  if (status)    {      int sig = status & 0x7F;      int ret;      if (sig != -1 && sig != 0)	{#ifdef NO_SYS_SIGLIST	  error ("%s terminated with signal %d %s",		 prog,		 sig,		 (status & 0200) ? ", core dumped" : "");#else	  error ("%s terminated with signal %d [%s]%s",		 prog,		 sig,		 sys_siglist[sig],		 (status & 0200) ? ", core dumped" : "");#endif	  my_exit (127);	}      ret = ((status & 0xFF00) >> 8);      if (ret != -1 && ret != 0)	{	  error ("%s returned %d exit status", prog, ret);	  my_exit (ret);	}    }}/* Fork and execute a program, and wait for the reply.  */static voidfork_execute (prog, argv)     char *prog;     char **argv;{  int pid;  if (vflag || debug)    {      char **p_argv;      char *str;      fprintf (stderr, "%s", prog);      for (p_argv = &argv[1]; (str = *p_argv) != (char *)0; p_argv++)	fprintf (stderr, " %s", str);      fprintf (stderr, "\n");    }  fflush (stdout);  fflush (stderr);  pid = vfork ();  if (pid == -1)    fatal_perror ("vfork");  if (pid == 0)			/* child context */    {      execvp (prog, argv);      fatal_perror ("executing %s", prog);    }  do_wait (prog);}/* Unlink a file unless we are debugging.  */static voidmaybe_unlink (file)     char *file;{  if (!debug)    unlink (file);  else    fprintf (stderr, "[Leaving %s]\n", file);}/* Add a name to a linked list.  */static voidadd_to_list (head_ptr, name)     struct head *head_ptr;     char *name;{  struct id *newid = (struct id *) xcalloc (sizeof (*newid) + strlen (name), 1);  static long sequence_number = 0;  newid->sequence = ++sequence_number;  strcpy (newid->name, name);  if (head_ptr->first)    head_ptr->last->next = newid;  else    head_ptr->first = newid;  head_ptr->last = newid;  head_ptr->number++;}/* Write: `prefix', the names on list LIST, `suffix'.  */static voidwrite_list (stream, prefix, list)     FILE *stream;     char *prefix;     struct id *list;{  while (list)    {      fprintf (stream, "%sx%d,\n", prefix, list->sequence);      list = list->next;    }}static void

⌨️ 快捷键说明

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