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

📄 collect2.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	fprintf (stderr, "[cannot find %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);  /* If we can't find a program we need, complain error.  Do this here     since we might not end up needing something that we couldn't find.  */  if (argv[0] == 0)    fatal ("cannot find `%s'", prog);  pid = vfork ();  if (pid == -1)    {#ifdef vfork      fatal_perror ("fork");#else      fatal_perror ("vfork");#endif    }  if (pid == 0)			/* child context */    {      if (redir)	{	  unlink (redir);	  if (freopen (redir, "a", stdout) == NULL)	    fatal_perror ("redirecting stdout: %s", redir);	  if (freopen (redir, "a", stderr) == NULL)	    fatal_perror ("redirecting stderr: %s", redir);	}      execvp (argv[0], argv);      fatal_perror ("executing %s", prog);    }}static voidfork_execute (prog, argv)     char *prog;     char **argv;{  collect_execute (prog, argv, NULL);  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 (struct id) + strlen (name), 1);  struct id *p;  static long sequence_number = 0;  strcpy (newid->name, name);  if (head_ptr->first)    head_ptr->last->next = newid;  else    head_ptr->first = newid;  /* Check for duplicate symbols.  */  for (p = head_ptr->first;       strcmp (name, p->name) != 0;       p = p->next)    ;  if (p != newid)    {      head_ptr->last->next = 0;      free (newid);      return;    }  newid->sequence = ++sequence_number;  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 voidwrite_list_with_asm (stream, prefix, list)     FILE *stream;     char *prefix;     struct id *list;{  while (list)    {      fprintf (stream, "%sx%d __asm__ (\"%s\");\n",	       prefix, list->sequence, list->name);      list = list->next;    }}/* Write out the constructor and destructor tables statically (for a shared   object), along with the functions to execute them.  */static voidwrite_c_file_stat (stream, name)     FILE *stream;     char *name;{  char *prefix, *p, *q;  int frames = (frame_tables.number > 0);  /* Figure out name of output_file, stripping off .so version.  */  p = rindex (output_file, '/');  if (p == 0)    p = (char *) output_file;  else    p++;  q = p;  while (q)    {      q = index (q,'.');      if (q == 0)	{	  q = p + strlen (p);	  break;	}      else	{	  if (strncmp (q, ".so", 3) == 0)	    {	      q += 3;	      break;	    }	  else	    q++;	}    }  /* q points to null at end of the string (or . of the .so version) */  prefix = xmalloc (q - p + 1);  strncpy (prefix, p, q - p);  prefix[q - p] = 0;  for (q = prefix; *q; q++)    if (!isalnum (*q))      *q = '_';  if (debug)    fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",	     output_file, prefix);#define INIT_NAME_FORMAT "_GLOBAL__FI_%s"  initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);  sprintf (initname, INIT_NAME_FORMAT, prefix);#define FINI_NAME_FORMAT "_GLOBAL__FD_%s"  fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);  sprintf (fininame, FINI_NAME_FORMAT, prefix);  free (prefix);  /* Write the tables as C code  */  fprintf (stream, "static int count;\n");  fprintf (stream, "typedef void entry_pt();\n");  write_list_with_asm (stream, "extern entry_pt ", constructors.first);  if (frames)    {      write_list_with_asm (stream, "extern void *", frame_tables.first);      fprintf (stream, "\tstatic void *frame_table[] = {\n");      write_list (stream, "\t\t&", frame_tables.first);      fprintf (stream, "\t0\n};\n");      /* This must match what's in frame.h.  */      fprintf (stream, "struct object {\n");      fprintf (stream, "  void *pc_begin;\n");      fprintf (stream, "  void *pc_end;\n");      fprintf (stream, "  void *fde_begin;\n");      fprintf (stream, "  void *fde_array;\n");      fprintf (stream, "  __SIZE_TYPE__ count;\n");      fprintf (stream, "  struct object *next;\n");      fprintf (stream, "};\n");      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");      fprintf (stream, "extern void __deregister_frame_info (void *);\n");      fprintf (stream, "static void reg_frame () {\n");      fprintf (stream, "\tstatic struct object ob;\n");      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");      fprintf (stream, "\t}\n");      fprintf (stream, "static void dereg_frame () {\n");      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");      fprintf (stream, "\t}\n");    }  fprintf (stream, "void %s() {\n", initname);  if (constructors.number > 0 || frames)    {      fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");      write_list (stream, "\t\t", constructors.first);      if (frames)	fprintf (stream, "\treg_frame,\n");      fprintf (stream, "\t};\n");      fprintf (stream, "\tentry_pt **p;\n");      fprintf (stream, "\tif (count++ != 0) return;\n");      fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames);      fprintf (stream, "\twhile (p > ctors) (*--p)();\n");    }  else    fprintf (stream, "\t++count;\n");  fprintf (stream, "}\n");  write_list_with_asm (stream, "extern entry_pt ", destructors.first);  fprintf (stream, "void %s() {\n", fininame);  if (destructors.number > 0 || frames)    {      fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");      write_list (stream, "\t\t", destructors.first);      if (frames)	fprintf (stream, "\tdereg_frame,\n");      fprintf (stream, "\t};\n");      fprintf (stream, "\tentry_pt **p;\n");      fprintf (stream, "\tif (--count != 0) return;\n");      fprintf (stream, "\tp = dtors;\n");      fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n",	       destructors.number + frames);    }  fprintf (stream, "}\n");  if (shared_obj)    {      fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);      fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);    }}/* Write the constructor/destructor tables.  */static voidwrite_c_file_glob (stream, name)     FILE *stream;     char *name;{  /* Write the tables as C code  */  int frames = (frame_tables.number > 0);  fprintf (stream, "typedef void entry_pt();\n\n");      write_list_with_asm (stream, "extern entry_pt ", constructors.first);  if (frames)    {      write_list_with_asm (stream, "extern void *", frame_tables.first);      fprintf (stream, "\tstatic void *frame_table[] = {\n");      write_list (stream, "\t\t&", frame_tables.first);      fprintf (stream, "\t0\n};\n");      /* This must match what's in frame.h.  */      fprintf (stream, "struct object {\n");      fprintf (stream, "  void *pc_begin;\n");      fprintf (stream, "  void *pc_end;\n");      fprintf (stream, "  void *fde_begin;\n");      fprintf (stream, "  void *fde_array;\n");      fprintf (stream, "  __SIZE_TYPE__ count;\n");      fprintf (stream, "  struct object *next;\n");      fprintf (stream, "};\n");      fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n");      fprintf (stream, "extern void __deregister_frame_info (void *);\n");      fprintf (stream, "static void reg_frame () {\n");      fprintf (stream, "\tstatic struct object ob;\n");      fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n");      fprintf (stream, "\t}\n");      fprintf (stream, "static void dereg_frame () {\n");      fprintf (stream, "\t__deregister_frame_info (frame_table);\n");      fprintf (stream, "\t}\n");    }  fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");  fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames);  write_list (stream, "\t", constructors.first);  if (frames)    fprintf (stream, "\treg_frame,\n");  fprintf (stream, "\t0\n};\n\n");  write_list_with_asm (stream, "extern entry_pt ", destructors.first);  fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n");  fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames);  write_list (stream, "\t", destructors.first);  if (frames)    fprintf (stream, "\tdereg_frame,\n");  fprintf (stream, "\t0\n};\n\n");  fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN);  fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);}static voidwrite_c_file (stream, name)     FILE *stream;     char *name;{  fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");#ifndef LD_INIT_SWITCH  if (! shared_obj)    write_c_file_glob (stream, name);  else#endif    write_c_file_stat (stream, name);  fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n");}static voidwrite_export_file (stream)     FILE *stream;{  struct id *list = exports.first;  for (; list; list = list->next)    fprintf (stream, "%s\n", list->name);}#ifdef OBJECT_FORMAT_NONE/* Generic version to scan the name list of the loaded program for   the symbols g++ uses for static constructors and destructors.   The constructor table begins at __CTOR_LIST__ and contains a count   of the number of pointers (or -1 if the constructors are built in a   separate section by the linker), followed by the pointers to the   constructor functions, terminated with a null pointer.  The   destructor table has the same format, and begins at __DTOR_LIST__.  */static voidscan_prog_file (prog_name, which_pass)     char *prog_name;     enum pass which_pass;{  void (*int_handler) ();  void (*quit_handler) ();  char *nm_argv[4];  int pid;  int argc = 0;  int pipe_fd[2];  char *p, buf[1024];  FILE *inf;  if (which_pass == PASS_SECOND)    return;  /* If we don't have an `nm', complain.  */  if (nm_file_name == 0)    fatal ("cannot find `nm'");  nm_argv[argc++] = nm_file_name;  if (NM_FLAGS[0] != '\0')    nm_argv[argc++] = NM_FLAGS;  nm_argv[argc++] = prog_name;  nm_argv[argc++] = (char *) 0;  if (pipe (pipe_fd) < 0)    fatal_perror ("pipe");  inf = fdopen (pipe_fd[0], "r");  if (inf == (FILE *) 0)    fatal_perror ("fdopen");  /* Trace if needed.  */  if (vflag)    {      char **p_argv;      char *str;      for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)	fprintf (stderr, " %s", str);      fprintf (stderr, "\n");    }  fflush (stdout);  fflush (stderr);  /* Spawn child nm on pipe */  pid = vfork ();  if (pid == -1)    {#ifdef vfork      fatal_perror ("fork");#else      fatal_perror ("vfork");#endif    }  if (pid == 0)			/* child context */    {      /* setup stdout */      if (dup2 (pipe_fd[1], 1) < 0)	fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);      if (close (pipe_fd[0]) < 0)	fatal_perror ("close (%d)", pipe_fd[0]);      if (close (pipe_fd[1]) < 0)	fatal_perror ("close (%d)", pipe_fd[1]);      execv (nm_file_name, nm_argv);      fatal_perror ("executing %s", nm_file_name);    }  /* Parent context from here on.  */  int_handler  = (void (*) ())signal (SIGINT,  SIG_IGN);#ifdef SIGQUIT  quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);#endif  if (close (pipe_fd[1]) < 0)    fatal_perror ("close (%d)", pipe_fd[1]);  if (debug)    fprintf (stderr, "\nnm output with constructors/destructors.\n");  /* Read each line of nm output.  */  while (fgets (buf, sizeof buf, inf) != (char *) 0)    {      int ch, ch2;      char *name, *end;      /* If it contains a constructor or destructor name, add the name	 to the appropriate list.  */      for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)	if (ch == ' ' && p[1] == 'U' && p[2] == ' ')	  break;      if (ch != '_')	continue;        name = p;      /* Find the end of the symbol name.	 Don't include `|', because Encore nm can tack that on the end.  */      for (end = p; (ch2 = *end) != '\0' && !isspace (ch2) && ch2 != '|';	   end++)	continue;      *end = '\0';      switch (is_ctor_dtor (name))	{	case 1:	  if (which_pass != PASS_LIB)	    add_to_list (&constructors, name);	  break;	case 2:	  if (which_pass != PASS_LIB)	    add_to_list (&destructors, name);	  break;	case 3:	  if (which_pass != PASS_LIB)	    fatal ("init function found in object %s", prog_name);#ifndef LD_INIT_SWITCH	  add_to_list (&constructors, name);#endif	  break;	case 4:	  if (which_pass != PASS_LIB)	    fatal ("fini function found in object %s", prog_name);#ifndef LD_FINI_SWITCH	  add_to_list (&destructors, name);#endif	  break;	case 5:	  if (which_pass != PASS_LIB)	    add_to_list (&frame_tables, name);	default:		/* not a constructor or destructor */	  continue;	}      if (debug)	fprintf (stderr, "\t%s\n", buf);    }  if (debug)    fprintf (stderr, "\n");  if (fclose (inf) != 0)    fatal_perror ("fclose of pipe");  do_wait (nm_file_name);

⌨️ 快捷键说明

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