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

📄 collect2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
write_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 the constructor/destructor tables. */static voidwrite_c_file (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 __main;\n");  fprintf (stream, "entry_pt *__main_reference = __main;\n\n");}#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_FIRST)    return;  nm_argv[argc++] = "nm";  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;      fprintf (stderr, "%s", nm_file_name);      for (p_argv = &nm_argv[1]; (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)    fatal_perror ("vfork");  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);  quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN);  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 == '\0' || ch == '\n')	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:	  add_to_list (&constructors, name);	  break;	case 2:	  add_to_list (&destructors, name);	  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);  signal (SIGQUIT, quit_handler);}#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)    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 _AIX	      /* All AIX function names begin with a dot. */	      if (*name++ != '.')		continue;#endif	      switch (is_ctor_dtor (name))		{		case 1:		  add_to_list (&constructors, name);		  break;		case 2:		  add_to_list (&destructors, 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);}#endif /* OBJECT_FORMAT_COFF *//* * OSF/rose specific stuff. */#ifdef OBJECT_FORMAT_ROSE/* Union of the various load commands */typedef union load_union{  ldc_header_t			hdr;	/* common header */  load_cmd_map_command_t	map;	/* map indexing other load cmds */  interpreter_command_t		iprtr;	/* interpreter pathname */  strings_command_t		str;	/* load commands strings section */  region_command_t		region;	/* region load command */  reloc_command_t		reloc;	/* relocation section */  package_command_t		pkg;	/* package load command */  symbols_command_t		sym;	/* symbol sections */  entry_command_t		ent;	/* program start section */  gen_info_command_t		info;	/* object information */  func_table_command_t		func;	/* function constructors/destructors */} load_union_t;/* Structure to point to load command and data section in memory.  */typedef struct load_all{  load_union_t *load;			/* load command */  char *section;			/* pointer to section */} load_all_t;/* Structure to contain information about a file mapped into memory.  */struct file_info{  char *start;				/* start of map */  char *name;				/* filename */  long	size;				/* size of the file */  long  rounded_size;			/* size rounded to page boundary */  int	fd;				/* file descriptor */  int	rw;				/* != 0 if opened read/write */  int	use_mmap;			/* != 0 if mmap'ed */};extern int decode_mach_o_hdr ();extern int encode_mach_o_hdr ();static void bad_header ();static void print_header ();static void print_load_command ();static void add_func_table ();static struct file_info	*read_file ();static void end_file ();/* OSF/rose specific 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;{  char *obj;  mo_header_t hdr;  load_all_t *load_array;  load_all_t *load_end;  load_all_t *load_cmd;  int symbol_load_cmds;  off_t offset;  int i;  int num_syms;  int status;  char *str_sect;  struct file_info *obj_file;  int prog_fd;  mo_lcid_t cmd_strings	  = -1;  symbol_info_t *main_sym = 0;  int rw		  = (which_pass != PASS_FIRST);  prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);  if (prog_fd < 0)    fatal_perror ("can't read %s", prog_name);  obj_file = read_file (prog_name, prog_fd, rw);  obj = obj_file->start;  status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);  if (status != MO_HDR_CONV_SUCCESS)    bad_header (status);  /* Do some basic sanity checks.  Note we explicitly use the big endian magic number,     since the hardware will automatically swap bytes for us on loading little endian     integers.  */#ifndef CROSS_COMPILE  if (hdr.moh_magic != MOH_MAGIC_MSB      || hdr.moh_header_version != MOH_HEADER_VERSION      || hdr.moh_byte_order != OUR_BYTE_ORDER      || hdr.moh_data_rep_id != OUR_DATA_REP_ID      || hdr.moh_cpu_type != OUR_CPU_TYPE      || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE      || hdr.moh_vendor_type != OUR_VENDOR_TYPE)    {      fatal ("incompatibilities between object file & expected values");    }#endif  if (debug)    print_header (&hdr);  offset = hdr.moh_first_cmd_off;  load_end = load_array    = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);  /* Build array of load commands, calculating the offsets */  for (i = 0; i < hdr.moh_n_load_cmds; i++)    {      load_union_t *load_hdr;		/* load command header */      load_cmd = load_end++;      load_hdr = (load_union_t *) (obj + offset);      /* If modifying the program file, copy the header.  */      if (rw)	{	  load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);	  bcopy ((generic *)load_hdr, (generic *)ptr, load_hdr->hdr.ldci_cmd_size);	  load_hdr = ptr;	  /* null out old command map, because we will rewrite at the end.  */	  if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)	    {	      cmd_strings = ptr->map.lcm_ld_cmd_strings;	      ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;	    }	}      load_cmd->load = load_hdr;      if (load_hdr->hdr.ldci_section_off > 0)	load_cmd->section = obj + load_hdr->hdr.ldci_section_off;      if (debug)	print_load_command (load_hdr, offset, i);      offset += load_hdr->hdr.ldci_cmd_size;    }  /* If the last command is the load command map and is not undefined,     decrement the count of load commands.  */  if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)    {      load_end--;      hdr.moh_n_load_cmds--;    }  /* Go through and process each symbol table section.  */  symbol_load_cmds = 0;  for (load_cmd = load_array; load_cmd < load_end; load_cmd++)    {      load_union_t *load_hdr = load_cmd->load;      if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)	{	  symbol_load_cmds++;	  if (debug)	    {	      char *kind = "unknown";	      switch (load_hdr->sym.symc_kind)		{		case SYMC_IMPORTS:	   kind = "imports"; break;		case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;

⌨️ 快捷键说明

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