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

📄 collect2.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  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 <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;    }  else    return 0;}/* Given the name NAME of a dynamic dependency, find its pathname and add   it to the list of libraries.  */static voidlocatelib (name)     char *name;{  static char **l;  static int cnt;  char buf[MAXPATHLEN];  char *p, *q;  char **pp;  if (l == 0)    {      char *ld_rules;      char *ldr = 0;      /* counting elements in array, need 1 extra for null */      cnt = 1;        ld_rules = (char *) (ld_2->ld_rules + code);      if (ld_rules)	{	  cnt++;	  for (; *ld_rules != 0; ld_rules++)	    if (*ld_rules == ':')	      cnt++;	  ld_rules = (char *) (ld_2->ld_rules + code);	  ldr = (char *) malloc (strlen (ld_rules) + 1);	  strcpy (ldr, ld_rules);	}      p = getenv ("LD_LIBRARY_PATH");      q = 0;      if (p)	{	  cnt++;	  for (q = p ; *q != 0; q++)	    if (*q == ':')	      cnt++;	  q = (char *) malloc (strlen (p) + 1);	  strcpy (q, p);	}      l = (char **) malloc ((cnt + 3) * sizeof (char *));      pp = l;      if (ldr)	{	  *pp++ = ldr;	  for (; *ldr != 0; ldr++) 	    if (*ldr == ':')	      {		*ldr++ = 0;		*pp++ = ldr;	      }	}      if (q)	{	  *pp++ = q;	  for (; *q != 0; q++) 	    if (*q == ':')	      {		*q++ = 0;		*pp++ = q;	      }	}      /* built in directories are /lib, /usr/lib, and /usr/local/lib */      *pp++ = "/lib";      *pp++ = "/usr/lib";      *pp++ = "/usr/local/lib";      *pp = 0;    }  libname = name;  for (pp = l; *pp != 0 ; pp++)    {      struct direct **namelist;      int entries;      if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0)	{	  sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name);	  add_to_list (&libraries, buf);	  if (debug)	    fprintf (stderr, "%s\n", buf);	  break;	}    }  if (*pp == 0)    {      if (debug)	fprintf (stderr, "not found\n");      else	fatal ("dynamic dependency %s not found", name);    }}/* Scan the _DYNAMIC structure of the output file to find shared libraries   that it depends upon and any constructors or destructors they contain.  */static void scan_libraries (prog_name)     char *prog_name;{  struct exec *header;  char *base;  struct link_object *lo;  char buff[MAXPATHLEN];  struct id *list;  mapfile (prog_name);  header = (struct exec *)object;  if (N_BADMAG (*header))    fatal ("bad magic number in file '%s'", prog_name);  if (header->a_dynamic == 0)    return;  code = (char *) (N_TXTOFF (*header) + (long) header);  data = (char *) (N_DATOFF (*header) + (long) header);  symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);  if (header->a_magic == ZMAGIC && header->a_entry == 0x20)    {      /* shared object */      ld = (struct link_dynamic *) (symtab->n_value + code);      base = code;    }  else    {      /* executable */      ld = (struct link_dynamic *) data;      base = code-PAGSIZ;    }  if (debug)    fprintf (stderr, "dynamic dependencies.\n");  ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);  for (lo = (struct link_object *) ld_2->ld_need; lo;       lo = (struct link_object *) lo->lo_next)    {      char *name;      lo = (struct link_object *) ((long) lo + code);      name = (char *) (code + lo->lo_name);      if (lo->lo_library)	{	  if (debug)	    fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);	  sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);	  locatelib (buff);	}      else	{	  if (debug)	    fprintf (stderr, "\t%s\n", name);	  add_to_list (&libraries, name);	}    }  if (debug)    fprintf (stderr, "\n");  /* now iterate through the library list adding their symbols to     the list.  */  for (list = libraries.first; list; list = list->next)    scan_prog_file (list->name, PASS_LIB);}#else  /* SUNOS4_SHARED_LIBRARIES */#ifdef LDD_SUFFIX/* Use the List Dynamic Dependencies program to find shared libraries that   the output file depends upon and their initialization/finalization   routines, if any.  */static void scan_libraries (prog_name)     char *prog_name;{  static struct head libraries;		/* list of shared libraries found */  struct id *list;  void (*int_handler) ();  void (*quit_handler) ();  char *ldd_argv[4];  int pid;  int argc = 0;  int pipe_fd[2];  char buf[1024];  FILE *inf;  /* If we don't have an `ldd', complain.  */  if (ldd_file_name == 0)    {      error ("cannot find `ldd'");      return;    }  ldd_argv[argc++] = ldd_file_name;  ldd_argv[argc++] = prog_name;  ldd_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 = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)	fprintf (stderr, " %s", str);      fprintf (stderr, "\n");    }  fflush (stdout);  fflush (stderr);  /* Spawn child ldd 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 (ldd_file_name, ldd_argv);      fatal_perror ("executing %s", ldd_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, "\nldd output with constructors/destructors.\n");  /* Read each line of ldd output.  */  while (fgets (buf, sizeof buf, inf) != (char *) 0)    {      int ch, ch2;      char *name, *end, *p = buf;      /* Extract names of libraries and add to list.  */      PARSE_LDD_OUTPUT (p);      if (p == 0)	continue;      name = p;      if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)	fatal ("dynamic dependency %s not found", buf);      /* Find the end of the symbol name.  */      for (end = p; 	   (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';	   end++)	continue;      *end = '\0';      if (access (name, R_OK) == 0)        add_to_list (&libraries, name);      else	fatal ("unable to open dynamic dependency '%s'", buf);      if (debug)	fprintf (stderr, "\t%s\n", buf);    }  if (debug)    fprintf (stderr, "\n");  if (fclose (inf) != 0)    fatal_perror ("fclose of pipe");  do_wait (ldd_file_name);  signal (SIGINT,  int_handler);#ifdef SIGQUIT  signal (SIGQUIT, quit_handler);#endif  /* now iterate through the library list adding their symbols to     the list.  */  for (list = libraries.first; list; list = list->next)    scan_prog_file (list->name, PASS_LIB);}#endif /* LDD_SUFFIX */#endif /* SUNOS4_SHARED_LIBRARIES */#endif /* OBJECT_FORMAT_NONE *//* * COFF specific stuff. */#ifdef OBJECT_FORMAT_COFF#if defined(EXTENDED_COFF)#   define GCC_SYMBOLS(X)	(SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)#   define GCC_SYMENT		SYMR#   define GCC_OK_SYMBOL(X)	((X).st == stProc && (X).sc == scText)#   define GCC_SYMINC(X)	(1)#   define GCC_SYMZERO(X)	(SYMHEADER(X).isymMax)#   define GCC_CHECK_HDR(X)	(PSYMTAB(X) != 0)#else#   define GCC_SYMBOLS(X)	(HEADER(ldptr).f_nsyms)#   define GCC_SYMENT		SYMENT#   define GCC_OK_SYMBOL(X) \     (((X).n_sclass == C_EXT) && \        (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \         ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT)))#   define GCC_SYMINC(X)	((X).n_numaux+1)#   define GCC_SYMZERO(X)	0#   define GCC_CHECK_HDR(X)	(1)#endifextern char *ldgetname ();/* COFF 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;{  LDFILE *ldptr = NULL;  int sym_index, sym_count;  if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)    return;  if ((ldptr = ldopen (prog_name, ldptr)) == NULL)    fatal ("%s: can't open as COFF file", prog_name);        if (!MY_ISCOFF (HEADER (ldptr).f_magic))    fatal ("%s: not a COFF file", prog_name);  if (GCC_CHECK_HDR (ldptr))    {      sym_count = GCC_SYMBOLS (ldptr);      sym_index = GCC_SYMZERO (ldptr);      while (sym_index < sym_count)	{	  GCC_SYMENT symbol;	  if (ldtbread (ldptr, sym_index, &symbol) <= 0)	    break;	  sym_index += GCC_SYMINC (symbol);	  if (GCC_OK_SYMBOL (symbol))	    {	      char *name;	      if ((name = ldgetname (ldptr, &symbol)) == NULL)		continue;		/* should never happen */#ifdef XCOFF_DEBUGGING_INFO	      /* All AIX function names have a duplicate entry beginning		 with a dot.  */	      if (*name == '.')		++name;#endif	      switch (is_ctor_dtor (name))		{		case 1:		  add_to_list (&constructors, name);		  if (which_pass == PASS_OBJ)		    add_to_list (&exports, name);		  break;		case 2:		  add_to_list (&destructors, name);		  if (which_pass == PASS_OBJ)		    add_to_list (&exports, name);		  break;		default:		/* not a constructor or destructor */		  continue;		}#if !defined(EXTENDED_COFF)	      if (debug)		fprintf (stderr, "

⌨️ 快捷键说明

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