pexxigen.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,044 行 · 第 1/5 页

C
2,044
字号
/* Support for the generic parts of PE/PEI; the common executable parts.   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.   Written by Cygnus Solutions.This file is part of BFD, the Binary File Descriptor library.This program 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 of the License, or(at your option) any later version.This program 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 this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* Most of this hacked by Steve Chamberlain <sac@cygnus.com>.   PE/PEI rearrangement (and code added): Donn Terry					  Softway Systems, Inc.*//* Hey look, some documentation [and in a place you expect to find it]!   The main reference for the pei format is "Microsoft Portable Executable   and Common Object File Format Specification 4.1".  Get it if you need to   do some serious hacking on this code.   Another reference:   "Peering Inside the PE: A Tour of the Win32 Portable Executable   File Format", MSJ 1994, Volume 9.   The *sole* difference between the pe format and the pei format is that the   latter has an MSDOS 2.0 .exe header on the front that prints the message   "This app must be run under Windows." (or some such).   (FIXME: Whether that statement is *really* true or not is unknown.   Are there more subtle differences between pe and pei formats?   For now assume there aren't.  If you find one, then for God sakes   document it here!)   The Microsoft docs use the word "image" instead of "executable" because   the former can also refer to a DLL (shared library).  Confusion can arise   because the `i' in `pei' also refers to "image".  The `pe' format can   also create images (i.e. executables), it's just that to run on a win32   system you need to use the pei format.   FIXME: Please add more docs here so the next poor fool that has to hack   on this code has a chance of getting something accomplished without   wasting too much time.*//* This expands into COFF_WITH_pe or COFF_WITH_pep depending on whether   we're compiling for straight PE or PE+.  */#define COFF_WITH_XX#include "bfd.h"#include "sysdep.h"#include "libbfd.h"#include "coff/internal.h"/* NOTE: it's strange to be including an architecture specific header   in what's supposed to be general (to PE/PEI) code.  However, that's   where the definitions are, and they don't vary per architecture   within PE/PEI, so we get them from there.  FIXME: The lack of   variance is an assumption which may prove to be incorrect if new   PE/PEI targets are created.  */#ifdef COFF_WITH_pep# include "coff/ia64.h"#else# include "coff/i386.h"#endif#include "coff/pe.h"#include "libcoff.h"#include "libpei.h"#ifdef COFF_WITH_pep# undef AOUTSZ# define AOUTSZ		PEPAOUTSZ# define PEAOUTHDR	PEPAOUTHDR#endif/* FIXME: This file has various tests of POWERPC_LE_PE.  Those tests   worked when the code was in peicode.h, but no longer work now that   the code is in peigen.c.  PowerPC NT is said to be dead.  If   anybody wants to revive the code, you will have to figure out how   to handle those issues.  */static void add_data_entry  PARAMS ((bfd *, struct internal_extra_pe_aouthdr *, int, char *, bfd_vma));static boolean pe_print_pdata PARAMS ((bfd *, PTR));static boolean pe_print_reloc PARAMS ((bfd *, PTR));/**********************************************************************/void_bfd_XXi_swap_sym_in (abfd, ext1, in1)     bfd *abfd;     PTR ext1;     PTR in1;{  SYMENT *ext = (SYMENT *) ext1;  struct internal_syment *in = (struct internal_syment *) in1;  if (ext->e.e_name[0] == 0)    {      in->_n._n_n._n_zeroes = 0;      in->_n._n_n._n_offset =	bfd_h_get_32 (abfd, (bfd_byte *) ext->e.e.e_offset);    }  else    {      memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);    }  in->n_value = bfd_h_get_32 (abfd, (bfd_byte *) ext->e_value);  in->n_scnum = bfd_h_get_16 (abfd, (bfd_byte *) ext->e_scnum);  if (sizeof (ext->e_type) == 2)    {      in->n_type = bfd_h_get_16 (abfd, (bfd_byte *) ext->e_type);    }  else    {      in->n_type = bfd_h_get_32 (abfd, (bfd_byte *) ext->e_type);    }  in->n_sclass = bfd_h_get_8 (abfd, ext->e_sclass);  in->n_numaux = bfd_h_get_8 (abfd, ext->e_numaux);#ifndef STRICT_PE_FORMAT  /* This is for Gnu-created DLLs.  */  /* The section symbols for the .idata$ sections have class 0x68     (C_SECTION), which MS documentation indicates is a section     symbol.  Unfortunately, the value field in the symbol is simply a     copy of the .idata section's flags rather than something useful.     When these symbols are encountered, change the value to 0 so that     they will be handled somewhat correctly in the bfd code.  */  if (in->n_sclass == C_SECTION)    {      in->n_value = 0x0;#if 0      /* FIXME: This is clearly wrong.  The problem seems to be that         undefined C_SECTION symbols appear in the first object of a         MS generated .lib file, and the symbols are not defined         anywhere.  */      in->n_scnum = 1;      /* I have tried setting the class to 3 and using the following	 to set the section number.  This will put the address of the	 pointer to the string kernel32.dll at addresses 0 and 0x10	 off start of idata section which is not correct.  */#if 0      if (strcmp (in->_n._n_name, ".idata$4") == 0)	in->n_scnum = 3;      else	in->n_scnum = 2;#endif#else      /* Create synthetic empty sections as needed.  DJ */      if (in->n_scnum == 0)	{	  asection *sec;	  for (sec = abfd->sections; sec; sec = sec->next)	    {	      if (strcmp (sec->name, in->n_name) == 0)		{		  in->n_scnum = sec->target_index;		  break;		}	    }	}      if (in->n_scnum == 0)	{	  int unused_section_number = 0;	  asection *sec;	  char *name;	  for (sec = abfd->sections; sec; sec = sec->next)	    if (unused_section_number <= sec->target_index)	      unused_section_number = sec->target_index + 1;	  name = bfd_alloc (abfd, strlen (in->n_name) + 10);	  if (name == NULL)	    return;	  strcpy (name, in->n_name);	  sec = bfd_make_section_anyway (abfd, name);	  sec->vma = 0;	  sec->lma = 0;	  sec->_cooked_size = 0;	  sec->_raw_size = 0;	  sec->filepos = 0;	  sec->rel_filepos = 0;	  sec->reloc_count = 0;	  sec->line_filepos = 0;	  sec->lineno_count = 0;	  sec->userdata = NULL;	  sec->next = (asection *) NULL;	  sec->flags = 0;	  sec->alignment_power = 2;	  sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;	  sec->target_index = unused_section_number;	  in->n_scnum = unused_section_number;	}      in->n_sclass = C_STAT;#endif    }#endif#ifdef coff_swap_sym_in_hook  /* This won't work in peigen.c, but since it's for PPC PE, it's not     worth fixing.  */  coff_swap_sym_in_hook (abfd, ext1, in1);#endif}unsigned int_bfd_XXi_swap_sym_out (abfd, inp, extp)     bfd       *abfd;     PTR	inp;     PTR	extp;{  struct internal_syment *in = (struct internal_syment *) inp;  SYMENT *ext = (SYMENT *) extp;  if (in->_n._n_name[0] == 0)    {      bfd_h_put_32 (abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);      bfd_h_put_32 (abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset);    }  else    {      memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);    }  bfd_h_put_32 (abfd, in->n_value, (bfd_byte *) ext->e_value);  bfd_h_put_16 (abfd, in->n_scnum, (bfd_byte *) ext->e_scnum);  if (sizeof (ext->e_type) == 2)    {      bfd_h_put_16 (abfd, in->n_type, (bfd_byte *) ext->e_type);    }  else    {      bfd_h_put_32 (abfd, in->n_type, (bfd_byte *) ext->e_type);    }  bfd_h_put_8 (abfd, in->n_sclass, ext->e_sclass);  bfd_h_put_8 (abfd, in->n_numaux, ext->e_numaux);  return SYMESZ;}void_bfd_XXi_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)     bfd            *abfd;     PTR	     ext1;     int             type;     int             class;     int	     indx ATTRIBUTE_UNUSED;     int	     numaux ATTRIBUTE_UNUSED;     PTR 	     in1;{  AUXENT *ext = (AUXENT *) ext1;  union internal_auxent *in = (union internal_auxent *) in1;  switch (class)    {    case C_FILE:      if (ext->x_file.x_fname[0] == 0)	{	  in->x_file.x_n.x_zeroes = 0;	  in->x_file.x_n.x_offset =	    bfd_h_get_32 (abfd, (bfd_byte *) ext->x_file.x_n.x_offset);	}      else	{	  memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);	}      return;    case C_STAT:    case C_LEAFSTAT:    case C_HIDDEN:      if (type == T_NULL)	{	  in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);	  in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);	  in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);	  in->x_scn.x_checksum =	    bfd_h_get_32 (abfd, (bfd_byte *) ext->x_scn.x_checksum);	  in->x_scn.x_associated =	    bfd_h_get_16 (abfd, (bfd_byte *) ext->x_scn.x_associated);	  in->x_scn.x_comdat =	    bfd_h_get_8 (abfd, (bfd_byte *) ext->x_scn.x_comdat);	  return;	}      break;    }  in->x_sym.x_tagndx.l = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_sym.x_tagndx);  in->x_sym.x_tvndx = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_tvndx);  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))    {      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);      in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext);    }  else    {      in->x_sym.x_fcnary.x_ary.x_dimen[0] =	bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);      in->x_sym.x_fcnary.x_ary.x_dimen[1] =	bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);      in->x_sym.x_fcnary.x_ary.x_dimen[2] =	bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);      in->x_sym.x_fcnary.x_ary.x_dimen[3] =	bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);    }  if (ISFCN (type))    {      in->x_sym.x_misc.x_fsize =	bfd_h_get_32 (abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);    }  else    {      in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);      in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);    }}unsigned int_bfd_XXi_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)     bfd  *abfd;     PTR   inp;     int   type;     int   class;     int   indx ATTRIBUTE_UNUSED;     int   numaux ATTRIBUTE_UNUSED;     PTR   extp;{  union internal_auxent *in = (union internal_auxent *) inp;  AUXENT *ext = (AUXENT *) extp;  memset ((PTR) ext, 0, AUXESZ);  switch (class)    {    case C_FILE:      if (in->x_file.x_fname[0] == 0)	{	  bfd_h_put_32 (abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);	  bfd_h_put_32 (abfd,			in->x_file.x_n.x_offset,			(bfd_byte *) ext->x_file.x_n.x_offset);	}      else	{	  memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);	}      return AUXESZ;    case C_STAT:    case C_LEAFSTAT:    case C_HIDDEN:      if (type == T_NULL)	{	  PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);	  PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);	  PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);	  bfd_h_put_32 (abfd, in->x_scn.x_checksum,			(bfd_byte *) ext->x_scn.x_checksum);	  bfd_h_put_16 (abfd, in->x_scn.x_associated,			(bfd_byte *) ext->x_scn.x_associated);	  bfd_h_put_8 (abfd, in->x_scn.x_comdat,		       (bfd_byte *) ext->x_scn.x_comdat);	  return AUXESZ;	}      break;    }  bfd_h_put_32 (abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);  bfd_h_put_16 (abfd, in->x_sym.x_tvndx, (bfd_byte *) ext->x_sym.x_tvndx);  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))    {      PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,  ext);      PUT_FCN_ENDNDX  (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);    }  else    {      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],		    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],		    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],		    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);      bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],		    (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);    }  if (ISFCN (type))    bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize,		  (bfd_byte *) ext->x_sym.x_misc.x_fsize);  else

⌨️ 快捷键说明

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