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

📄 collect2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Collect static initialization info into data structures   that can be traversed by C++ initialization and finalization   routines.   Copyright (C) 1992 Free Software Foundation, Inc.   Contributed by Chris Smith (csmith@convex.com).   Heavily modified by Michael Meissner (meissner@osf.org),   Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  *//* Build tables of static constructors and destructors and run ld. */#include <sys/types.h>#include <stdio.h>#include <ctype.h>#include <errno.h>#include <signal.h>#include <sys/file.h>#include <sys/stat.h>#ifdef NO_WAIT_H#include <sys/wait.h>#endif#ifndef errnoextern int errno;#endif#define COLLECT#include "config.h"#ifndef __STDC__#define generic char#define const#else#define generic void#endif#ifdef USG#define vfork fork#endif#ifndef R_OK#define R_OK 4#define W_OK 2#define X_OK 1#endif/* On MSDOS, write temp files in current dir   because there's no place else we can expect to use.  */#if __MSDOS__#ifndef P_tmpdir#define P_tmpdir "./"#endif#endif/* On certain systems, we have code that works by scanning the object file   directly.  But this code uses system-specific header files and library   functions, so turn it off in a cross-compiler.  */#ifdef CROSS_COMPILE#undef OBJECT_FORMAT_COFF#undef OBJECT_FORMAT_ROSE#endif/* If we can't use a special method, use the ordinary one:   run nm to find what symbols are present.   In a cross-compiler, this means you need a cross nm,   but that isn't quite as unpleasant as special headers.  */#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)#define OBJECT_FORMAT_NONE#endif#ifdef OBJECT_FORMAT_COFF#include <a.out.h>#include <ar.h>#ifdef UMAX#include <sgs.h>#endif#ifdef _AIX#define ISCOFF(magic) \  ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC || (magic) == U802TOCMAGIC)#endif/* Many versions of ldfcn.h define these.  */#ifdef FREAD#undef FREAD#undef FWRITE#endif#include <ldfcn.h>/* Mips-news overrides this macro.  */#ifndef MY_ISCOFF#define MY_ISCOFF(X) ISCOFF (X)#endif#endif /* OBJECT_FORMAT_COFF */#ifdef OBJECT_FORMAT_ROSE#ifdef _OSF_SOURCE#define USE_MMAP#endif#ifdef USE_MMAP#include <sys/mman.h>#endif#include <unistd.h>#include <mach_o_format.h>#include <mach_o_header.h>#include <mach_o_vals.h>#include <mach_o_types.h>#endif /* OBJECT_FORMAT_ROSE */#ifdef OBJECT_FORMAT_NONE/* Default flags to pass to nm.  */#ifndef NM_FLAGS#define NM_FLAGS "-p"#endif#endif /* OBJECT_FORMAT_NONE *//* Linked lists of constructor and destructor names. */struct id {  struct id *next;  int sequence;  char name[1];};struct head{  struct id *first;  struct id *last;  int number;};/* Enumeration giving which pass this is for scanning the program file.  */enum pass {  PASS_FIRST,				/* without constructors */  PASS_SECOND				/* with constructors linked in */};#ifndef NO_SYS_SIGLISTextern char *sys_siglist[];#endifextern char *version_string;static int vflag;			/* true if -v */static int rflag;			/* true if -r */static int strip_flag;			/* true if -s */static int debug;			/* true if -debug */static int   temp_filename_length;	/* Length of temp_filename */static char *temp_filename;		/* Base of temp filenames */static char *c_file;			/* <xxx>.c for constructor/destructor list. */static char *o_file;			/* <xxx>.o for constructor/destructor list. */static char *nm_file_name;		/* pathname of nm */static char *strip_file_name;		/* pathname of strip */static struct head constructors;	/* list of constructors found */static struct head destructors;		/* list of destructors found */extern char *getenv ();extern char *mktemp ();static void  add_to_list ();static void  scan_prog_file ();static void  fork_execute ();static void  do_wait ();static void  write_c_file ();static void  my_exit ();static void  handler ();static void  maybe_unlink ();static void  choose_temp_base ();generic *xcalloc ();generic *xmalloc ();extern char *index ();extern char *rindex ();#ifdef NO_DUP2dup2 (oldfd, newfd)     int oldfd;     int newfd;{  int fdtmp[256];  int fdx = 0;  int fd;   if (oldfd == newfd)    return 0;  close (newfd);  while ((fd = dup (oldfd)) != newfd) /* good enough for low fd's */    fdtmp[fdx++] = fd;  while (fdx > 0)    close (fdtmp[--fdx]);}#endifchar *my_strerror (e)     int e;{  extern char *sys_errlist[];  extern int sys_nerr;  static char buffer[30];  if (!e)    return "";  if (e > 0 && e < sys_nerr)    return sys_errlist[e];  sprintf (buffer, "Unknown error %d", e);  return buffer;}/* Delete tempfiles and exit function.  */static voidmy_exit (status)     int status;{  if (c_file != 0 && c_file[0])    maybe_unlink (c_file);  if (o_file != 0 && o_file[0])    maybe_unlink (o_file);  exit (status);}/* Die when sys call fails. */static voidfatal_perror (string, arg1, arg2, arg3)     char *string;{  int e = errno;  fprintf (stderr, "collect: ");  fprintf (stderr, string, arg1, arg2, arg3);  fprintf (stderr, ": %s\n", my_strerror (e));  my_exit (1);}/* Just die. */static voidfatal (string, arg1, arg2, arg3)     char *string;{  fprintf (stderr, "collect: ");  fprintf (stderr, string, arg1, arg2, arg3);  fprintf (stderr, "\n");  my_exit (1);}/* Write error message.  */static voiderror (string, arg1, arg2, arg3, arg4)     char *string;{  fprintf (stderr, "collect: ");  fprintf (stderr, string, arg1, arg2, arg3, arg4);  fprintf (stderr, "\n");}/* In case obstack is linked in, and abort is defined to fancy_abort,   provide a default entry.  */voidfancy_abort (){  fatal ("internal error");}static voidhandler (signo)     int signo;{  if (c_file[0])    maybe_unlink (c_file);  if (o_file[0])    maybe_unlink (o_file);  signal (signo, SIG_DFL);  kill (getpid (), signo);}generic *xcalloc (size1, size2)     int size1, size2;{  generic *ptr = (generic *) calloc (size1, size2);  if (ptr)    return ptr;  fatal ("out of memory");  return (generic *)0;}generic *xmalloc (size)     int size;{  generic *ptr = (generic *) malloc (size);  if (ptr)    return ptr;  fatal ("out of memory");  return (generic *)0;}/* Make a copy of a string INPUT with size SIZE.  */char *savestring (input, size)     char *input;     int size;{  char *output = (char *) xmalloc (size + 1);  bcopy (input, output, size);  output[size] = 0;  return output;}/* Decide whether the given symbol is:   a constructor (1), a destructor (2), or neither (0).  */static intis_ctor_dtor (s)     char *s;{  struct names { char *name; int len; int ret; int two_underscores; };  register struct names *p;  register int ch;  register char *orig_s = s;  static struct names special[] = {#ifdef NO_DOLLAR_IN_LABEL    { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 },    { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 },#else    { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },    { "GLOBAL_$D$", sizeof ("GLOBAL_$I$")-1, 2, 0 },#endif#ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.			 cfront has its own linker procedure to collect them;			 if collect2 gets them too, they get collected twice			 when the cfront procedure is run and the compiler used			 for linking happens to be GCC.  */    { "sti__", sizeof ("sti__")-1, 1, 1 },    { "std__", sizeof ("std__")-1, 2, 1 },#endif /* CFRONT_LOSSAGE */    { NULL, 0, 0, 0 }  };  while ((ch = *s) == '_')    ++s;  if (s == orig_s)    return 0;  for (p = &special[0]; p->len > 0; p++)    {      if (ch == p->name[0]	  && (!p->two_underscores || ((s - orig_s) >= 2))	  && strncmp(s, p->name, p->len) == 0)	{	  return p->ret;	}    }  return 0;}/* Compute a string to use as the base of all temporary file names.   It is substituted for %g.  */static voidchoose_temp_base (){  char *base = getenv ("TMPDIR");  int len;  if (base == (char *)0)    {#ifdef P_tmpdir      if (access (P_tmpdir, R_OK | W_OK) == 0)	base = P_tmpdir;#endif      if (base == (char *)0)	{	  if (access ("/usr/tmp", R_OK | W_OK) == 0)	    base = "/usr/tmp/";	  else	    base = "/tmp/";	}    }  len = strlen (base);  temp_filename = xmalloc (len + sizeof("/ccXXXXXX"));  strcpy (temp_filename, base);  if (len > 0 && temp_filename[len-1] != '/')    temp_filename[len++] = '/';  strcpy (temp_filename + len, "ccXXXXXX");  mktemp (temp_filename);  temp_filename_length = strlen (temp_filename);}/* Main program. */intmain (argc, argv)     int argc;     char *argv[];{  char *outfile		= "a.out";  char *arg;  FILE *outf;  char *ld_file_name;  char *c_file_name;  char *p;  char *prefix;  char **c_argv;  char **c_ptr;  char **ld1_argv	= (char **) xcalloc (sizeof (char *), argc+2);  char **ld1		= ld1_argv;  char **ld2_argv	= (char **) xcalloc (sizeof (char *), argc+5);  char **ld2		= ld2_argv;  int first_file;  int num_c_args	= argc+7;  int len;  int clen;#ifdef DEBUG  debug = 1;  vflag = 1;#endif  p = (char *) getenv ("COLLECT_GCC_OPTIONS");  if (p)    while (*p)      {	char *q = p;	while (*q && *q != ' ') q++;	if (*p == '-' && p[1] == 'm')	  num_c_args++;	if (*q) q++;	p = q;

⌨️ 快捷键说明

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