pe.em

来自「基于4个mips核的noc设计」· EM 代码 · 共 1,678 行 · 第 1/4 页

EM
1,678
字号
    LANG_FOR_EACH_INPUT_STATEMENT (is)      {	if (is->the_bfd->my_archive)	  {	    int idata2 = 0, reloc_count=0, is_imp = 0;	    asection *sec;	    	    /* See if this is an import library thunk.  */	    for (sec = is->the_bfd->sections; sec; sec = sec->next)	      {		if (strcmp (sec->name, ".idata\$2") == 0)		  idata2 = 1;		if (strncmp (sec->name, ".idata\$", 7) == 0)		  is_imp = 1;		reloc_count += sec->reloc_count;	      }	    	    if (is_imp && !idata2 && reloc_count)	      {		/* It is, look for the reference to head and see if it's		   from our own library.  */		for (sec = is->the_bfd->sections; sec; sec = sec->next)		  {		    int i;		    long symsize;		    long relsize;		    asymbol **symbols;		    arelent **relocs;		    int nrelocs;		    		    symsize = bfd_get_symtab_upper_bound (is->the_bfd);		    if (symsize < 1)		      break;		    relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec);		    if (relsize < 1)		      break;		    		    symbols = (asymbol **) xmalloc (symsize); 		    symsize = bfd_canonicalize_symtab (is->the_bfd, symbols);		    if (symsize < 0)		      {			einfo ("%X%P: unable to process symbols: %E");			return;		      }		    		    relocs = (arelent **) xmalloc ((size_t) relsize);		    nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec,							  relocs, symbols);		    if (nrelocs < 0)		      {			free (relocs);			einfo ("%X%P: unable to process relocs: %E");			return;		      }		    		    for (i = 0; i < nrelocs; i++)		      {			struct symbol_cache_entry *s;			struct bfd_link_hash_entry * blhe;			bfd *other_bfd;			char *n;						s = (relocs[i]->sym_ptr_ptr)[0];						if (s->flags & BSF_LOCAL)			  continue;						/* Thunk section with reloc to another bfd.  */			blhe = bfd_link_hash_lookup (link_info.hash,						     s->name,						     false, false, true);			    			if (blhe == NULL			    || blhe->type != bfd_link_hash_defined)			  continue;						other_bfd = blhe->u.def.section->owner;			    			if (strcmp (is->the_bfd->my_archive->filename,				    other_bfd->my_archive->filename) == 0)			  continue;						/* Rename this implib to match the other.  */			n = (char *) xmalloc (strlen (other_bfd->my_archive->filename) + 1);			    			strcpy (n, other_bfd->my_archive->filename);			    			is->the_bfd->my_archive->filename = n;		      }		    free (relocs);		    /* Note - we do not free the symbols,		       they are now cached in the BFD.  */		  }	      }	  }      }  }  {    int is_ms_arch = 0;    bfd *cur_arch = 0;    lang_input_statement_type *is2;    /* Careful - this is a shell script.  Watch those dollar signs! */    /* Microsoft import libraries have every member named the same,       and not in the right order for us to link them correctly.  We       must detect these and rename the members so that they'll link       correctly.  There are three types of objects: the head, the       thunks, and the sentinel(s).  The head is easy; it's the one       with idata2.  We assume that the sentinels won't have relocs,       and the thunks will.  It's easier than checking the symbol       table for external references.  */    LANG_FOR_EACH_INPUT_STATEMENT (is)      {	if (is->the_bfd->my_archive)	  {	    bfd *arch = is->the_bfd->my_archive;	    if (cur_arch != arch)	      {		cur_arch = arch;		is_ms_arch = 1;		for (is2 = is;		     is2 && is2->the_bfd->my_archive == arch;		     is2 = (lang_input_statement_type *)is2->next)		  {		    if (strcmp (is->the_bfd->filename, is2->the_bfd->filename))		      is_ms_arch = 0;		  }	      }	    if (is_ms_arch)	      {		int idata2 = 0, reloc_count=0;		asection *sec;		char *new_name, seq;		for (sec = is->the_bfd->sections; sec; sec = sec->next)		  {		    if (strcmp (sec->name, ".idata\$2") == 0)		      idata2 = 1;		    reloc_count += sec->reloc_count;		  }		if (idata2) /* .idata2 is the TOC */		  seq = 'a';		else if (reloc_count > 0) /* thunks */		  seq = 'b';		else /* sentinel */		  seq = 'c';		new_name = xmalloc (strlen (is->the_bfd->filename) + 3);		sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);		is->the_bfd->filename = new_name;		new_name = xmalloc (strlen (is->filename) + 3);		sprintf (new_name, "%s.%c", is->filename, seq);		is->filename = new_name;	      }	  }      }  }}static void  gld_${EMULATION_NAME}_before_allocation(){#ifdef TARGET_IS_ppcpe  /* Here we rummage through the found bfds to collect toc information */  {    LANG_FOR_EACH_INPUT_STATEMENT (is)      {	if (!ppc_process_before_allocation (is->the_bfd, &link_info))	  {	    /* xgettext:c-format */	    einfo (_("Errors encountered processing file %s\n"), is->filename);	  }      }  }  /* We have seen it all. Allocate it, and carry on */  ppc_allocate_toc_section (&link_info);#endif /* TARGET_IS_ppcpe */#if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)  /* FIXME: we should be able to set the size of the interworking stub     section.     Here we rummage through the found bfds to collect glue     information.  FIXME: should this be based on a command line     option?  krk@cygnus.com */  {    LANG_FOR_EACH_INPUT_STATEMENT (is)      {	if (! bfd_arm_pe_process_before_allocation	    (is->the_bfd, & link_info, support_old_code))	  {	    /* xgettext:c-format */	    einfo (_("Errors encountered processing file %s for interworking"),		   is->filename);	  }      }  }  /* We have seen it all. Allocate it, and carry on */  bfd_arm_pe_allocate_interworking_sections (& link_info);#endif /* TARGET_IS_armpe */}#ifdef DLL_SUPPORT/* This is called when an input file isn't recognized as a BFD.  We   check here for .DEF files and pull them in automatically. */static intsaw_option(char *option){  int i;  for (i=0; init[i].ptr; i++)    if (strcmp (init[i].symbol, option) == 0)      return init[i].inited;  return 0;}#endif /* DLL_SUPPORT */static booleangld_${EMULATION_NAME}_unrecognized_file(entry)     lang_input_statement_type *entry ATTRIBUTE_UNUSED;{#ifdef DLL_SUPPORT  const char *ext = entry->filename + strlen (entry->filename) - 4;  if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0)  {    if (pe_def_file == 0)      pe_def_file = def_file_empty ();    def_file_parse (entry->filename, pe_def_file);    if (pe_def_file)    {      int i, buflen=0, len;      char *buf;      for (i=0; i<pe_def_file->num_exports; i++)	{	  len = strlen(pe_def_file->exports[i].internal_name);	  if (buflen < len+2)	    buflen = len+2;	}      buf = (char *) xmalloc (buflen);      for (i=0; i<pe_def_file->num_exports; i++)	{	  struct bfd_link_hash_entry *h;	  sprintf(buf, "_%s", pe_def_file->exports[i].internal_name);	  h = bfd_link_hash_lookup (link_info.hash, buf, true, true, true);	  if (h == (struct bfd_link_hash_entry *) NULL)	    einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));	  if (h->type == bfd_link_hash_new)	    {	      h->type = bfd_link_hash_undefined;	      h->u.undef.abfd = NULL;	      bfd_link_add_undef (link_info.hash, h);	    }	}      free (buf);      /* def_file_print (stdout, pe_def_file); */      if (pe_def_file->is_dll == 1)	link_info.shared = 1;      if (pe_def_file->base_address != (bfd_vma)(-1))      {	pe.ImageBase =	pe_data (output_bfd)->pe_opthdr.ImageBase =	init[IMAGEBASEOFF].value = pe_def_file->base_address;	init[IMAGEBASEOFF].inited = 1;	if (image_base_statement)	  image_base_statement->exp =	    exp_assop ('=', "__image_base__", exp_intop (pe.ImageBase));      }#if 0      /* Not sure if these *should* be set */      if (pe_def_file->version_major != -1)      {	pe.MajorImageVersion = pe_def_file->version_major;	pe.MinorImageVersion = pe_def_file->version_minor;      }#endif      if (pe_def_file->stack_reserve != -1	  && ! saw_option ("__size_of_stack_reserve__"))      {	pe.SizeOfStackReserve = pe_def_file->stack_reserve;	if (pe_def_file->stack_commit != -1)	  pe.SizeOfStackCommit = pe_def_file->stack_commit;      }      if (pe_def_file->heap_reserve != -1	  && ! saw_option ("__size_of_heap_reserve__"))      {	pe.SizeOfHeapReserve = pe_def_file->heap_reserve;	if (pe_def_file->heap_commit != -1)	  pe.SizeOfHeapCommit = pe_def_file->heap_commit;      }      return true;    }  }#endif  return false;  }static booleangld_${EMULATION_NAME}_recognized_file(entry)  lang_input_statement_type *entry ATTRIBUTE_UNUSED;{#ifdef DLL_SUPPORT#ifdef TARGET_IS_i386pe  pe_dll_id_target ("pei-i386");#endif#ifdef TARGET_IS_shpe  pe_dll_id_target ("pei-shl");#endif#ifdef TARGET_IS_mipspe  pe_dll_id_target ("pei-mips");#endif#ifdef TARGET_IS_armpe  pe_dll_id_target ("pei-arm-little");#endif  if (bfd_get_format (entry->the_bfd) == bfd_object)    {      const char *ext = entry->filename + strlen (entry->filename) - 4;      if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0)	return pe_implied_import_dll (entry->filename);    }#endif  return false;}static voidgld_${EMULATION_NAME}_finish (){#if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)  struct bfd_link_hash_entry * h;  if (thumb_entry_symbol != NULL)    {      h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, false, false, true);            if (h != (struct bfd_link_hash_entry *) NULL	  && (h->type == bfd_link_hash_defined	      || h->type == bfd_link_hash_defweak)	  && h->u.def.section->output_section != NULL)	{	  static char buffer[32];	  bfd_vma val;	  	  /* Special procesing is required for a Thumb entry symbol.  The	     bottom bit of its address must be set.  */	  val = (h->u.def.value		 + bfd_get_section_vma (output_bfd,					h->u.def.section->output_section)		 + h->u.def.section->output_offset);	  	  val |= 1;	  	  /* Now convert this value into a string and store it in entry_symbol	     where the lang_finish() function will pick it up.  */	  buffer[0] = '0';	  buffer[1] = 'x';	  	  sprintf_vma (buffer + 2, val);	  	  if (entry_symbol != NULL && entry_from_cmdline)	    einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),		   thumb_entry_symbol, entry_symbol);	  entry_symbol = buffer;	}      else	einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);    }#endif /* defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe) */#ifdef DLL_SUPPORT  if (link_info.shared)    {      pe_dll_fill_sections (output_bfd, &link_info);      if (pe_implib_filename)	pe_dll_generate_implib (pe_def_file, pe_implib_filename);    }#if defined(TARGET_IS_shpe) || defined(TARGET_IS_mipspe)  /* ARM doesn't need relocs.  */  else    {      pe_exe_fill_sections (output_bfd, &link_info);    }#endif    if (pe_out_def_filename)    pe_dll_generate_def_file (pe_out_def_filename);#endif /* DLL_SUPPORT */}/* Place an orphan section.   We use this to put sections in a reasonable place in the file, and   to ensure that they are aligned as required.   We handle grouped sections here as well.  A section named .foo$nn   goes into the output section .foo.  All grouped sections are sorted   by name.   Grouped sections for the default sections are handled by the   default linker script using wildcards, and are sorted by   sort_sections.  */struct orphan_save{  lang_output_section_statement_type *os;  asection **section;  lang_statement_union_type **stmt;};

⌨️ 快捷键说明

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