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

📄 collect2.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
      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");	  if (freopen (redir, "a", stderr) == NULL)	    fatal_perror ("redirecting stderr");	}      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;  /* 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);  fprintf (stream, "void %s() {\n", initname);  if (constructors.number > 0)    {      fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");      write_list (stream, "\t\t", constructors.first);      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);      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)    {      fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");      write_list (stream, "\t\t", destructors.first);      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);    }  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  */  fprintf (stream, "typedef void entry_pt();\n\n");      write_list_with_asm (stream, "extern entry_pt ", constructors.first);      fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n");  fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number);  write_list (stream, "\t", constructors.first);  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);  write_list (stream, "\t", destructors.first);  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;{#ifndef LD_INIT_SWITCH  if (! shared_obj)    write_c_file_glob (stream, name);  else#endif    write_c_file_stat (stream, name);}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;	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);  signal (SIGINT,  int_handler);#ifdef SIGQUIT  signal (SIGQUIT, quit_handler);#endif}#if SUNOS4_SHARED_LIBRARIES/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries   that the output file depends upon and their initialization/finalization   routines, if any.  */#include <a.out.h>#include <fcntl.h>#include <link.h>#include <sys/mman.h>#include <sys/param.h>#include <sys/unistd.h>#include <sys/dir.h>/* pointers to the object file */unsigned object;    	/* address of memory mapped file */unsigned objsize;    	/* size of memory mapped to file */char * code;		/* pointer to code segment */char * data;		/* pointer to data segment */struct nlist *symtab;	/* pointer to symbol table */struct link_dynamic *ld;struct link_dynamic_2 *ld_2;struct head libraries;/* Map the file indicated by NAME into memory and store its address.  */static voidmapfile (name)     char *name;{  int fp;  struct stat s;  if ((fp = open (name, O_RDONLY)) == -1)    fatal ("unable to open file '%s'", name);  if (fstat (fp, &s) == -1)    fatal ("unable to stat file '%s'", name);  objsize = s.st_size;  object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,			    fp, 0);  if (object == -1)    fatal ("unable to mmap file '%s'", name);  close (fp);}/* Helpers for locatelib.  */static char *libname;static intlibselect (d)     struct direct *d;{  return (strncmp (libname, d->d_name, strlen (libname)) == 0);}/* If one file has an additional numeric extension past LIBNAME, then put   that one first in the sort.  If both files have additional numeric   extensions, then put the one with the higher number first in the sort.   We must verify that the extension is numeric, because Sun saves the   original versions of patched libraries with a .FCS extension.  Files with   invalid extensions must go last in the sort, so that they won't be used.  */static intlibcompare (d1, d2)     struct direct **d1, **d2;{  int i1, i2 = strlen (libname);  char *e1 = (*d1)->d_name + i2;  char *e2 = (*d2)->d_name + i2;  while (*e1 && *e2 && *e1 == '.' && *e2 == '.'	 && e1[1] && isdigit (e1[1]) && e2[1] && isdigit (e2[1]))    {      ++e1;      ++e2;      i1 = strtol (e1, &e1, 10);      i2 = strtol (e2, &e2, 10);      if (i1 != i2)	return i1 - i2;    }  if (*e1)    {      /* It has a valid numeric extension, prefer this one.  */      if (*e1 == '.' && e1[1] && isdigit (e1[1]))	return 1;      /* It has a invalid numeric extension, must prefer the other one.  */      else	return -1;    }  else if (*e2)    {      /* It has a valid numeric extension, prefer this one.  */      if (*e2 == '.' && e2[1] && isdigit (e2[1]))	return -1;      /* It has a invalid numeric extension, must prefer the other one.  */      else	return 1;    }

⌨️ 快捷键说明

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