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

📄 collect2.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
  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, "\tsec=%d class=%d type=%s%o %s\n",			 symbol.n_scnum, symbol.n_sclass,			 (symbol.n_type ? "0" : ""), symbol.n_type,			 name);#else	      if (debug)		fprintf (stderr, "\tiss = %5d, value = %5d, index = %5d, name = %s\n",			 symbol.iss, symbol.value, symbol.index, name);#endif	    }	}    }  (void) ldclose(ldptr);}#ifdef XCOFF_SCAN_LIBS/* Scan imported AIX libraries for GCC static ctors and dtors.   FIXME: it is possible to link an executable without the actual import	  library by using an "import file" - a text file listing symbols	  exported by a library.  To support this, we would have to scan	  import files as well as actual shared binaries to find GCC ctors.   TODO: use memory mapping instead of 'ld' routines, files are already	 memory mapped, but we could eliminate the extra in-memory copies.	 Is it worth the effort?  */static voidscan_libraries (prog_name)     char *prog_name;{  LDFILE *ldptr;  SCNHDR ldsh;  static struct path_prefix libpath; /* we should only do this once */  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);  /* find and read loader section */  if (ldnshread (ldptr, _LOADER, &ldsh))    {      LDHDR ldh;      char *impbuf;      int entry;      FSEEK (ldptr, ldsh.s_scnptr, BEGINNING);      FREAD (&ldh, sizeof (ldh), 1, ldptr);      /* read import library list */      impbuf = alloca (ldh.l_istlen);      FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING);      FREAD (impbuf, ldh.l_istlen, 1, ldptr);      if (debug)	fprintf (stderr, "LIBPATH=%s\n", impbuf);      prefix_from_string (impbuf, &libpath);      /* skip LIBPATH and empty base and member fields */      impbuf += strlen (impbuf) + 3;      for (entry = 1; entry < ldh.l_nimpid; ++entry)	{	  char *impath = impbuf;	  char *implib = impath + strlen (impath) + 1;	  char *impmem = implib + strlen (implib) + 1;	  char *soname = NULL;	  char *trial;	  int pathlen;	  LDFILE *libptr = NULL;	  struct prefix_list *pl;	  ARCHDR ah;	  impbuf = impmem + strlen (impmem) + 1;	  if (debug)	    fprintf (stderr, "PATH+BASE=%s%s\n", impath, implib);	  /* Skip AIX kernel exports */	  if (*impath == '/' && *(impath+1) == '\0'	      && strcmp (implib, "unix") == 0)	    continue;	  pathlen = strlen (impath);          trial = alloca (MAX (pathlen + 1, libpath.max_len)			  + strlen (implib) + 1);	  if (*impath)	    {	      strcpy (trial, impath);	      if (impath[pathlen - 1] != '/')		trial[pathlen++] = '/';	      strcpy (trial + pathlen, implib);	      if (access (trial, R_OK) == 0)		soname = trial;	    }	  else	    for (pl = libpath.plist; pl; pl = pl->next)	      {		strcpy (trial, pl->prefix);		strcat (trial, implib);		if (access (trial, R_OK) == 0)		  {		    soname = trial;		    break;		  }	      }	  if (! soname)	    fatal ("%s: library not found", implib);	  if (debug)	    if (*impmem)	      fprintf (stderr, "%s (%s)\n", soname, impmem);	    else	      fprintf (stderr, "%s\n", soname);	  do	    {	      /* scan imported shared objects for GCC GLOBAL ctors */	      short type;	      if ((libptr = ldopen (soname, libptr)) == NULL)		fatal ("%s: can't open import library", soname)

⌨️ 快捷键说明

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