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

📄 collect2.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If we look for a program in the compiler directories, we just use     the short name, since these directories are already system-specific.     But it we look for a took in the system directories, we need to     qualify the program name with the target machine.  */  full_ld_suffix    = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_ld_suffix, target_machine);  strcat (full_ld_suffix, "-");  strcat (full_ld_suffix, ld_suffix);  full_real_ld_suffix    = xcalloc (strlen (real_ld_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_real_ld_suffix, target_machine);  strcat (full_real_ld_suffix, "-");  strcat (full_real_ld_suffix, real_ld_suffix);#if 0  full_gld_suffix    = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_gld_suffix, target_machine);  strcat (full_gld_suffix, "-");  strcat (full_gld_suffix, gld_suffix);#endif  full_nm_suffix    = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_nm_suffix, target_machine);  strcat (full_nm_suffix, "-");  strcat (full_nm_suffix, nm_suffix);  full_gnm_suffix    = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_gnm_suffix, target_machine);  strcat (full_gnm_suffix, "-");  strcat (full_gnm_suffix, gnm_suffix);#ifdef LDD_SUFFIX  full_ldd_suffix    = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_ldd_suffix, target_machine);  strcat (full_ldd_suffix, "-");  strcat (full_ldd_suffix, ldd_suffix);#endif  full_strip_suffix    = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_strip_suffix, target_machine);  strcat (full_strip_suffix, "-");  strcat (full_strip_suffix, strip_suffix);    full_gstrip_suffix    = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1);  strcpy (full_gstrip_suffix, target_machine);  strcat (full_gstrip_suffix, "-");  strcat (full_gstrip_suffix, gstrip_suffix);#endif /* CROSS_COMPILE */  /* Try to discover a valid linker/nm/strip to use.  */  /* Maybe we know the right file to use (if not cross).  */#ifdef REAL_LD_FILE_NAME  ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);  if (ld_file_name == 0)#endif  /* Search the (target-specific) compiler dirs for ld'.  */  ld_file_name = find_a_file (&cpath, real_ld_suffix);  /* Likewise for `collect-ld'.  */  if (ld_file_name == 0)    ld_file_name = find_a_file (&cpath, collect_ld_suffix);  /* Search the compiler directories for `ld'.  We have protection against     recursive calls in find_a_file.  */  if (ld_file_name == 0)    ld_file_name = find_a_file (&cpath, ld_suffix);  /* Search the ordinary system bin directories     for `ld' (if native linking) or `TARGET-ld' (if cross).  */  if (ld_file_name == 0)    ld_file_name = find_a_file (&path, full_ld_suffix);  /* If we've invoked ourselves, try again with LD_FILE_NAME.  */  if (collect_names != 0)    {      if (ld_file_name != 0)	{	  argv[0] = ld_file_name;	  execvp (argv[0], argv);	}      fatal ("cannot find `ld'");    }#ifdef REAL_NM_FILE_NAME  nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);  if (nm_file_name == 0)#endif  nm_file_name = find_a_file (&cpath, gnm_suffix);  if (nm_file_name == 0)    nm_file_name = find_a_file (&path, full_gnm_suffix);  if (nm_file_name == 0)    nm_file_name = find_a_file (&cpath, nm_suffix);  if (nm_file_name == 0)    nm_file_name = find_a_file (&path, full_nm_suffix);#ifdef LDD_SUFFIX  ldd_file_name = find_a_file (&cpath, ldd_suffix);  if (ldd_file_name == 0)    ldd_file_name = find_a_file (&path, full_ldd_suffix);#endif#ifdef REAL_STRIP_FILE_NAME  strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);  if (strip_file_name == 0)#endif  strip_file_name = find_a_file (&cpath, gstrip_suffix);  if (strip_file_name == 0)    strip_file_name = find_a_file (&path, full_gstrip_suffix);  if (strip_file_name == 0)    strip_file_name = find_a_file (&cpath, strip_suffix);  if (strip_file_name == 0)    strip_file_name = find_a_file (&path, full_strip_suffix);  /* Determine the full path name of the C compiler to use.  */  c_file_name = getenv ("COLLECT_GCC");  if (c_file_name == 0)    {#ifdef CROSS_COMPILE      c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1);      strcpy (c_file_name, target_machine);      strcat (c_file_name, "-gcc");#else      c_file_name = "gcc";#endif    }  p = find_a_file (&cpath, c_file_name);  /* Here it should be safe to use the system search path since we should have     already qualified the name of the compiler when it is needed.  */  if (p == 0)    p = find_a_file (&path, c_file_name);  if (p)    c_file_name = p;  *ld1++ = *ld2++ = ld_file_name;  /* Make temp file names.  */  temp_filename = choose_temp_base ();  temp_filename_length = strlen (temp_filename);  c_file = xcalloc (temp_filename_length + sizeof (".c"), 1);  o_file = xcalloc (temp_filename_length + sizeof (".o"), 1);  export_file = xmalloc (temp_filename_length + sizeof (".x"));  ldout = xmalloc (temp_filename_length + sizeof (".ld"));  sprintf (ldout, "%s.ld", temp_filename);  sprintf (c_file, "%s.c", temp_filename);  sprintf (o_file, "%s.o", temp_filename);  sprintf (export_file, "%s.x", 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 'l':	      if (first_file)		{		  /* place o_file BEFORE this argument! */		  first_file = 0;		  ld2--;		  *ld2++ = o_file;		  *ld2++ = arg;		}	      break;	    case 'o':	      if (arg[2] == '\0')		output_file = *ld1++ = *ld2++ = *++argv;	      else		output_file = &arg[2];	      break;	    case 'r':	      if (arg[2] == '\0')		rflag = 1;	      break;	    case 's':	      if (arg[2] == '\0' && do_collecting)		{		  /* 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 ((p = rindex (arg, '.')) != (char *) 0	       && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))	{	  if (first_file)	    {	      first_file = 0;	      if (p[1] == 'o')		*ld2++ = o_file;	      else		{		  /* place o_file BEFORE this argument! */		  ld2--;		  *ld2++ = o_file;		  *ld2++ = arg;		}	    }	  if (p[1] == 'o')	    *object++ = arg;	}    }  /* Get any options that the upper GCC wants to pass to the sub-GCC.  */  p = (char *) getenv ("COLLECT_GCC_OPTIONS");  while (p && *p)    {      char *q = extract_string (&p);      if (*q == '-' && (q[1] == 'm' || q[1] == 'f'))	*c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q));      if (strncmp (q, "-shared", sizeof ("shared") - 1) == 0)	shared_obj = 1;    }  obstack_free (&temporary_obstack, temporary_firstobj);  *c_ptr++ = "-fno-exceptions";#ifdef COLLECT_EXPORT_LIST  /* The AIX linker will discard static constructors in object files if     nothing else in the file is referenced, so look at them first.  */  while (object_lst < object)    scan_prog_file (*object_lst++, PASS_OBJ);  {    char *buf = alloca (strlen (export_file) + 5);    sprintf (buf, "-bE:%s", export_file);    *ld1++ = buf;    *ld2++ = buf;    exportf = fopen (export_file, "w");    if (exportf == (FILE *) 0)      fatal_perror ("%s", export_file);    write_export_file (exportf);    if (fclose (exportf))      fatal_perror ("closing %s", export_file);  }#endif  *c_ptr++ = c_file;  *object = *c_ptr = *ld1 = (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, "ld_file_name        = %s\n",	       (ld_file_name ? ld_file_name : "not found"));      fprintf (stderr, "c_file_name         = %s\n",	       (c_file_name ? c_file_name : "not found"));      fprintf (stderr, "nm_file_name        = %s\n",	       (nm_file_name ? nm_file_name : "not found"));#ifdef LDD_SUFFIX      fprintf (stderr, "ldd_file_name       = %s\n",	       (ldd_file_name ? ldd_file_name : "not found"));#endif      fprintf (stderr, "strip_file_name     = %s\n",	       (strip_file_name ? strip_file_name : "not found"));      fprintf (stderr, "c_file              = %s\n",	       (c_file ? c_file : "not found"));      fprintf (stderr, "o_file              = %s\n",	       (o_file ? o_file : "not found"));      ptr = getenv ("COLLECT_NAMES");      if (ptr)	fprintf (stderr, "COLLECT_NAMES       = %s\n", ptr);      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.  */  collect_execute ("ld", ld1_argv, ldout);  do_wait ("ld");  dump_file (ldout);  unlink (ldout);  /* If -r or they'll be run via some other method, don't build the     constructor or destructor list, just return now.  */  if (rflag || ! do_collecting)    return 0;  /* 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.  */  scan_prog_file (output_file, PASS_FIRST);#ifdef SCAN_LIBRARIES  scan_libraries (output_file);#endif  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      && frame_tables.number == 0#ifdef SCAN_LIBRARIES      /* If we will be running these functions ourselves, we want to emit	 stubs into the shared library so that we don't have to relink	 dependent programs when we add static objects.  */      && ! shared_obj#endif      )    {      /* 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_file_name;	  strip_argv[1] = output_file;	  strip_argv[2] = (char *) 0;	  fork_execute ("strip", strip_argv);	}#ifdef COLLECT_EXPORT_LIST      maybe_unlink (export_file);#endif      return 0;    }  maybe_unlink(output_file);  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);  /* Tell the linker that we have initializer and finalizer functions.  */#ifdef LD_INIT_SWITCH  *ld2++ = LD_INIT_SWITCH;  *ld2++ = initname;  *ld2++ = LD_FINI_SWITCH;  *ld2++ = fininame;#endif  *ld2 = (char*) 0;#ifdef COLLECT_EXPORT_LIST  if (shared_obj)    {      add_to_list (&exports, initname);      add_to_list (&exports, fininame);      add_to_list (&exports, "_GLOBAL__DI");      add_to_list (&exports, "_GLOBAL__DD");      exportf = fopen (export_file, "w");      if (exportf == (FILE *) 0)	fatal_perror ("%s", export_file);      write_export_file (exportf);      if (fclose (exportf))	fatal_perror ("closing %s", export_file);    }#endif  if (debug)    {      fprintf (stderr, "\n========== output_file = %s, c_file = %s\n",	       output_file, c_file);      write_c_file (stderr, "stderr");      fprintf (stderr, "========== end of c_file\n\n");#ifdef COLLECT_EXPORT_LIST      fprintf (stderr, "\n========== export_file = %s\n", export_file);      write_export_file (stderr);      fprintf (stderr, "========== end of export_file\n\n");#endif    }  /* Assemble the constructor and destructor tables.     Link the tables in with the rest of the program.  */  fork_execute ("gcc",  c_argv);  fork_execute ("ld", ld2_argv);  /* Let scan_prog_file do any final mods (OSF/rose needs this for     constructors/destructors in shared libraries.  */  scan_prog_file (output_file, PASS_SECOND);  maybe_unlink (c_file);  maybe_unlink (o_file);  maybe_unlink (export_file);  return 0;}/* Wait for a process to finish, and exit if a non-zero status is found.  */intcollect_wait (prog)     char *prog;{  int status;  wait (&status);  if (status)    {      if (WIFSIGNALED (status))	{	  int sig = WTERMSIG (status);#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	  collect_exit (FATAL_EXIT_CODE);	}      if (WIFEXITED (status))	return WEXITSTATUS (status);    }  return 0;}static voiddo_wait (prog)     char *prog;{  int ret = collect_wait (prog);  if (ret != 0)    {      error ("%s returned %d exit status", prog, ret);      collect_exit (ret);    }}/* Fork and execute a program, and wait for the reply.  */voidcollect_execute (prog, argv, redir)     char *prog;     char **argv;     char *redir;{  int pid;  if (vflag || debug)    {      char **p_argv;      char *str;      if (argv[0])	fprintf (stderr, "%s", argv[0]);      else

⌨️ 快捷键说明

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