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

📄 pe.em

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 EM
📖 第 1 页 / 共 4 页
字号:
  if (pe_dll_extra_pe_debug)    {      bfd *a;      struct bfd_link_hash_entry *sym;      printf ("%s()\n", __FUNCTION__);      for (sym = link_info.hash->undefs; sym; sym=sym->next)        printf ("-%s\n", sym->root.string);      bfd_hash_traverse (&link_info.hash->table, pr_sym,NULL);      for (a = link_info.input_bfds; a; a = a->link_next)        {          printf("*%s\n",a->filename);        }    }  /* Pass the wacky PE command line options into the output bfd.     FIXME: This should be done via a function, rather than by     including an internal BFD header.  */  if (coff_data (output_bfd) == NULL || coff_data (output_bfd)->pe == 0)    einfo (_("%F%P: PE operations on non PE file.\n"));  pe_data (output_bfd)->pe_opthdr = pe;  pe_data (output_bfd)->dll = init[DLLOFF].value;#ifdef DLL_SUPPORT  if (pe_enable_stdcall_fixup) /* -1=warn or 1=disable */    pe_fixup_stdcalls ();  pe_find_data_imports ();  pe_process_import_defs(output_bfd, &link_info);  if (link_info.shared)    pe_dll_build_sections (output_bfd, &link_info);#ifndef TARGET_IS_i386pe#ifndef TARGET_IS_armpe  else    pe_exe_build_sections (output_bfd, &link_info);#endif#endif#endif#if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)  if (strstr (bfd_get_target (output_bfd), "arm") == NULL)    {      /* The arm backend needs special fields in the output hash structure.	 These will only be created if the output format is an arm format,	 hence we do not support linking and changing output formats at the	 same time.  Use a link followed by objcopy to change output formats.  */      einfo ("%F%X%P: error: cannot change output format whilst linking ARM binaries\n");      return;    }  {    /* Find a BFD that can hold the interworking stubs.  */    LANG_FOR_EACH_INPUT_STATEMENT (is)      {	if (bfd_arm_pe_get_bfd_for_interworking (is->the_bfd, & link_info))	  break;      }  }#endif  {    /* This next chunk of code tries to detect the case where you have       two import libraries for the same DLL (specifically,       symbolically linking libm.a and libc.a in cygwin to       libcygwin.a).  In those cases, it's possible for function       thunks from the second implib to be used but without the       head/tail objects, causing an improper import table.  We detect       those cases and rename the "other" import libraries to match       the one the head/tail come from, so that the linker will sort       things nicely and produce a valid import table. */    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 voidgld_${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.name != NULL && entry_from_cmdline)	    einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),		   thumb_entry_symbol, entry_symbol.name);	  entry_symbol.name = 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 */  /* I don't know where .idata gets set as code, but it shouldn't be */  {    asection *asec = bfd_get_section_by_name (output_bfd, ".idata");    if (asec)      {        asec->flags &= ~SEC_CODE;        asec->flags |= SEC_DATA;      }  }}/* Find the last output section before given output statement.   Used by place_orphan.  */

⌨️ 快捷键说明

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