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

📄 collect2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
		case SYMC_STABS:	   kind = "stabs";   break;		}	      fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",		       symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);	    }	  if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)	    continue;	  str_sect = load_array[load_hdr->sym.symc_strings_section].section;	  if (str_sect == (char *)0)	    fatal ("string section missing");	  if (load_cmd->section == (char *)0)	    fatal ("section pointer missing");	  num_syms = load_hdr->sym.symc_nentries;	  for (i = 0; i < num_syms; i++)	    {	      symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;	      char *name = sym->si_name.symbol_name + str_sect;	      if (name[0] != '_')		continue;	      if (rw)		{		  char *n = name;		  while (*n == '_')		    ++n;		  if (*n != 'm' || (n - name) < 2 || strcmp (n, "main"))		    continue;		  main_sym = sym;		}	      else		{		  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, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",			 sym->si_type, sym->si_sc_type, sym->si_flags, name);	    }	}    }  if (symbol_load_cmds == 0)    fatal ("no symbol table found");  /* Update the program file now, rewrite header and load commands.  At present,     we assume that there is enough space after the last load command to insert     one more.  Since the first section written out is page aligned, and the     number of load commands is small, this is ok for the present.  */  if (rw)    {      load_union_t *load_map;      size_t size;      if (cmd_strings == -1)	fatal ("no cmd_strings found");      /* Add __main to initializer list.	 If we are building a program instead of a shared library, don't	 do anything, since in the current version, you cannot do mallocs	 and such in the constructors.  */      if (main_sym != (symbol_info_t *)0	  && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))	add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);      if (debug)	fprintf (stderr, "\nUpdating header and load commands.\n\n");      hdr.moh_n_load_cmds++;      size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));      /* Create new load command map.  */      if (debug)	fprintf (stderr, "load command map, %d cmds, new size %ld.\n",		 (int)hdr.moh_n_load_cmds, (long)size);      load_map = (load_union_t *) xcalloc (1, size);      load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;      load_map->map.ldc_header.ldci_cmd_size = size;      load_map->map.lcm_ld_cmd_strings = cmd_strings;      load_map->map.lcm_nentries = hdr.moh_n_load_cmds;      load_array[hdr.moh_n_load_cmds-1].load = load_map;      offset = hdr.moh_first_cmd_off;      for (i = 0; i < hdr.moh_n_load_cmds; i++)	{	  load_map->map.lcm_map[i] = offset;	  if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)	    hdr.moh_load_map_cmd_off = offset;	  offset += load_array[i].load->hdr.ldci_cmd_size;	}      hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;      if (debug)	print_header (&hdr);      /* Write header */      status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);      if (status != MO_HDR_CONV_SUCCESS)	bad_header (status);      if (debug)	fprintf (stderr, "writing load commands.\n\n");      /* Write load commands */      offset = hdr.moh_first_cmd_off;      for (i = 0; i < hdr.moh_n_load_cmds; i++)	{	  load_union_t *load_hdr = load_array[i].load;	  size_t size = load_hdr->hdr.ldci_cmd_size;	  if (debug)	    print_load_command (load_hdr, offset, i);	  bcopy ((generic *)load_hdr, (generic *)(obj + offset), size);	  offset += size;	}    }  end_file (obj_file);  if (close (prog_fd))    fatal_perror ("closing %s", prog_name);  if (debug)    fprintf (stderr, "\n");}/* Add a function table to the load commands to call a function   on initiation or termination of the process.  */static voidadd_func_table (hdr_p, load_array, sym, type)     mo_header_t *hdr_p;		/* pointer to global header */     load_all_t *load_array;		/* array of ptrs to load cmds */     symbol_info_t *sym;		/* pointer to symbol entry */     int type;				/* fntc_type value */{  /* Add a new load command.  */  int num_cmds = ++hdr_p->moh_n_load_cmds;  int load_index = num_cmds - 1;  size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);  load_union_t *ptr = xcalloc (1, size);  load_all_t *load_cmd;  int i;  /* Set the unresolved address bit in the header to force the loader to be     used, since kernel exec does not call the initialization functions.  */  hdr_p->moh_flags |= MOH_UNRESOLVED_F;  load_cmd = &load_array[load_index];  load_cmd->load = ptr;  load_cmd->section = (char *)0;  /* Fill in func table load command.  */  ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;  ptr->func.ldc_header.ldci_cmd_size = size;  ptr->func.ldc_header.ldci_section_off = 0;  ptr->func.ldc_header.ldci_section_len = 0;  ptr->func.fntc_type = type;  ptr->func.fntc_nentries = 1;  /* copy address, turn it from abs. address to (region,offset) if necessary.  */  /* Is the symbol already expressed as (region, offset)?  */  if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)    {      ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;      ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;    }  /* If not, figure out which region it's in.  */  else    {      mo_vm_addr_t addr = sym->si_value.abs_val;      int found = 0;      for (i = 0; i < load_index; i++)	{	  if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)	    {	      region_command_t *region_ptr = &load_array[i].load->region;	      if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0		  && addr >= region_ptr->regc_addr.vm_addr		  && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)		{		  ptr->func.fntc_entry_loc[0].adr_lcid = i;		  ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;		  found++;		  break;		}	    }	}      if (!found)	fatal ("could not convert 0x%l.8x into a region", addr);    }  if (debug)    fprintf (stderr,	     "%s function, region %d, offset = %ld (0x%.8lx)\n",	     (type == FNTC_INITIALIZATION) ? "init" : "term",	     (int)ptr->func.fntc_entry_loc[i].adr_lcid,	     (long)ptr->func.fntc_entry_loc[i].adr_sctoff,	     (long)ptr->func.fntc_entry_loc[i].adr_sctoff);}/* Print the global header for an OSF/rose object.  */static voidprint_header (hdr_ptr)     mo_header_t *hdr_ptr;{  fprintf (stderr, "\nglobal header:\n");  fprintf (stderr, "\tmoh_magic            = 0x%.8lx\n", hdr_ptr->moh_magic);  fprintf (stderr, "\tmoh_major_version    = %d\n", (int)hdr_ptr->moh_major_version);  fprintf (stderr, "\tmoh_minor_version    = %d\n", (int)hdr_ptr->moh_minor_version);  fprintf (stderr, "\tmoh_header_version   = %d\n", (int)hdr_ptr->moh_header_version);  fprintf (stderr, "\tmoh_max_page_size    = %d\n", (int)hdr_ptr->moh_max_page_size);  fprintf (stderr, "\tmoh_byte_order       = %d\n", (int)hdr_ptr->moh_byte_order);  fprintf (stderr, "\tmoh_data_rep_id      = %d\n", (int)hdr_ptr->moh_data_rep_id);  fprintf (stderr, "\tmoh_cpu_type         = %d\n", (int)hdr_ptr->moh_cpu_type);  fprintf (stderr, "\tmoh_cpu_subtype      = %d\n", (int)hdr_ptr->moh_cpu_subtype);  fprintf (stderr, "\tmoh_vendor_type      = %d\n", (int)hdr_ptr->moh_vendor_type);  fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);  fprintf (stderr, "\tmoh_first_cmd_off    = %d\n", (int)hdr_ptr->moh_first_cmd_off);  fprintf (stderr, "\tmoh_sizeofcmds       = %d\n", (int)hdr_ptr->moh_sizeofcmds);  fprintf (stderr, "\tmon_n_load_cmds      = %d\n", (int)hdr_ptr->moh_n_load_cmds);  fprintf (stderr, "\tmoh_flags            = 0x%.8lx", (long)hdr_ptr->moh_flags);  if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)    fprintf (stderr, ", relocatable");  if (hdr_ptr->moh_flags & MOH_LINKABLE_F)    fprintf (stderr, ", linkable");  if (hdr_ptr->moh_flags & MOH_EXECABLE_F)    fprintf (stderr, ", execable");  if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)    fprintf (stderr, ", executable");  if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)    fprintf (stderr, ", unresolved");  fprintf (stderr, "\n\n");  return;}/* Print a short summary of a load command.  */static voidprint_load_command (load_hdr, offset, number)     load_union_t *load_hdr;     size_t offset;     int number;{  mo_long_t type = load_hdr->hdr.ldci_cmd_type;  char *type_str = (char *)0;  switch (type)    {    case LDC_UNDEFINED:   type_str = "UNDEFINED";	break;    case LDC_CMD_MAP:	  type_str = "CMD_MAP";		break;    case LDC_INTERPRETER: type_str = "INTERPRETER";	break;    case LDC_STRINGS:	  type_str = "STRINGS";		break;    case LDC_REGION:	  type_str = "REGION";		break;    case LDC_RELOC:	  type_str = "RELOC";		break;    case LDC_PACKAGE:	  type_str = "PACKAGE";		break;    case LDC_SYMBOLS:	  type_str = "SYMBOLS";		break;    case LDC_ENTRY:	  type_str = "ENTRY";		break;    case LDC_FUNC_TABLE:  type_str = "FUNC_TABLE";	break;    case LDC_GEN_INFO:	  type_str = "GEN_INFO";	break;    }  fprintf (stderr,	   "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",	   number,	   (long) load_hdr->hdr.ldci_cmd_size,	   (long) offset,	   (long) load_hdr->hdr.ldci_section_off,	   (long) load_hdr->hdr.ldci_section_len);  if (type_str == (char *)0)    fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);  else if (type != LDC_REGION)    fprintf (stderr, ", ty: %s\n", type_str);  else    {      char *region = "";      switch (load_hdr->region.regc_usage_type)	{	case REG_TEXT_T:	region = ", .text";	break;	case REG_DATA_T:	region = ", .data";	break;	case REG_BSS_T:		region = ", .bss";	break;	case REG_GLUE_T:	region = ", .glue";	break;#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/	case REG_RDATA_T:	region = ", .rdata";	break;	case REG_SDATA_T:	region = ", .sdata";	break;	case REG_SBSS_T:	region = ", .sbss";	break;#endif	}      fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",	       type_str,	       (long) load_hdr->region.regc_vm_addr,	       (long) load_hdr->region.regc_vm_size,	       region);    }  return;}/* Fatal error when {en,de}code_mach_o_header fails.  */static voidbad_header (status)     int status;{  char *msg = (char *)0;  switch (status)    {    case MO_ERROR_BAD_MAGIC:		msg = "bad magic number";		break;    case MO_ERROR_BAD_HDR_VERS:		msg = "bad header version";		break;    case MO_ERROR_BAD_RAW_HDR_VERS:	msg = "bad raw header version";		break;    case MO_ERROR_BUF2SML:		msg = "raw header buffer too small";	break;    case MO_ERROR_OLD_RAW_HDR_FILE:	msg = "old raw header file";		break;    case MO_ERROR_UNSUPPORTED_VERS:	msg = "unsupported version";		break;    }  if (msg == (char *)0)    fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);  else    fatal ("%s", msg);}/* Read a file into a memory buffer.  */static struct file_info *read_file (name, fd, rw)     char *name;		/* filename */     int fd;			/* file descriptor */     int rw;			/* read/write */{  struct stat stat_pkt;  struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);#ifdef USE_MMAP  static int page_size;#endif  if (fstat (fd, &stat_pkt) < 0)    fatal_perror ("fstat %s", name);  p->name	  = name;  p->size	  = stat_pkt.st_size;  p->rounded_size = stat_pkt.st_size;  p->fd		  = fd;  p->rw		  = rw;#ifdef USE_MMAP  if (debug)    fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");  if (page_size == 0)    page_size = sysconf (_SC_PAGE_SIZE);  p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;  p->start = mmap ((caddr_t)0,		   (rw) ? p->rounded_size : p->size,		   (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,		   MAP_FILE | MAP_VARIABLE | MAP_SHARED,		   fd,		   0L);  if (p->start != (char *)0 && p->start != (char *)-1)    p->use_mmap = 1;  else#endif /* USE_MMAP */    {      long len;      if (debug)	fprintf (stderr, "read %s\n", name);      p->use_mmap = 0;      p->start = xmalloc (p->size);      if (lseek (fd, 0L, SEEK_SET) < 0)	fatal_perror ("lseek to 0 on %s", name);      len = read (fd, p->start, p->size);      if (len < 0)	fatal_perror ("read %s", name);      if (len != p->size)	fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);    }  return p;}/* Do anything necessary to write a file back from memory.  */static voidend_file (ptr)     struct file_info *ptr;	/* file information block */{#ifdef USE_MMAP  if (ptr->use_mmap)    {      if (ptr->rw)	{	  if (debug)	    fprintf (stderr, "msync %s\n", ptr->name);	  if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))	    fatal_perror ("msync %s", ptr->name);	}      if (debug)	fprintf (stderr, "munmap %s\n", ptr->name);      if (munmap (ptr->start, ptr->size))	fatal_perror ("munmap %s", ptr->name);    }  else#endif /* USE_MMAP */    {      if (ptr->rw)	{	  long len;	  if (debug)	    fprintf (stderr, "write %s\n", ptr->name);	  if (lseek (ptr->fd, 0L, SEEK_SET) < 0)	    fatal_perror ("lseek to 0 on %s", ptr->name);	  len = write (ptr->fd, ptr->start, ptr->size);	  if (len < 0)	    fatal_perror ("read %s", ptr->name);	  if (len != ptr->size)	    fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);	}      free ((generic *)ptr->start);    }  free ((generic *)ptr);}#endif /* OBJECT_FORMAT_ROSE */

⌨️ 快捷键说明

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