coff-i386.c

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

C
624
字号
/* BFD back-end for Intel 386 COFF files.   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,   2000, 2001   Free Software Foundation, Inc.   Written by Cygnus Support.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.  */#include "bfd.h"#include "sysdep.h"#include "libbfd.h"#include "coff/i386.h"#include "coff/internal.h"#ifdef COFF_WITH_PE#include "coff/pe.h"#endif#ifdef COFF_GO32_EXE#include "coff/go32exe.h"#endif#include "libcoff.h"static bfd_reloc_status_type coff_i386_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static reloc_howto_type *coff_i386_rtype_to_howto  PARAMS ((bfd *, asection *, struct internal_reloc *,	   struct coff_link_hash_entry *, struct internal_syment *,	   bfd_vma *));static reloc_howto_type *coff_i386_reloc_type_lookup  PARAMS ((bfd *, bfd_reloc_code_real_type));#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)/* The page size is a guess based on ELF.  */#define COFF_PAGE_SIZE 0x1000/* For some reason when using i386 COFF the value stored in the .text   section for a reference to a common symbol is the value itself plus   any desired offset.  Ian Taylor, Cygnus Support.  *//* If we are producing relocateable output, we need to do some   adjustments to the object file that are not done by the   bfd_perform_relocation function.  This function is called by every   reloc type to make any required adjustments.  */static bfd_reloc_status_typecoff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,		 error_message)     bfd *abfd;     arelent *reloc_entry;     asymbol *symbol;     PTR data;     asection *input_section ATTRIBUTE_UNUSED;     bfd *output_bfd;     char **error_message ATTRIBUTE_UNUSED;{  symvalue diff;#ifndef COFF_WITH_PE  if (output_bfd == (bfd *) NULL)    return bfd_reloc_continue;#endif  if (bfd_is_com_section (symbol->section))    {#ifndef COFF_WITH_PE      /* We are relocating a common symbol.  The current value in the	 object file is ORIG + OFFSET, where ORIG is the value of the	 common symbol as seen by the object file when it was compiled	 (this may be zero if the symbol was undefined) and OFFSET is	 the offset into the common symbol (normally zero, but may be	 non-zero when referring to a field in a common structure).	 ORIG is the negative of reloc_entry->addend, which is set by	 the CALC_ADDEND macro below.  We want to replace the value in	 the object file with NEW + OFFSET, where NEW is the value of	 the common symbol which we are going to put in the final	 object file.  NEW is symbol->value.  */      diff = symbol->value + reloc_entry->addend;#else      /* In PE mode, we do not offset the common symbol.  */      diff = reloc_entry->addend;#endif    }  else    {      /* For some reason bfd_perform_relocation always effectively	 ignores the addend for a COFF target when producing	 relocateable output.  This seems to be always wrong for 386	 COFF, so we handle the addend here instead.  */#ifdef COFF_WITH_PE      if (output_bfd == (bfd *) NULL)	{	  reloc_howto_type *howto = reloc_entry->howto;	  /* Although PC relative relocations are very similar between	     PE and non-PE formats, but they are off by 1 << howto->size	     bytes. For the external relocation, PE is very different	     from others. See md_apply_fix3 () in gas/config/tc-i386.c.	     When we link PE and non-PE object files together to	     generate a non-PE executable, we have to compensate it	     here.  */	  if (howto->pc_relative == true && howto->pcrel_offset == true)	    diff = -(1 << howto->size);	  else	    diff = -reloc_entry->addend;	}      else#endif	diff = reloc_entry->addend;    }#ifdef COFF_WITH_PE  /* FIXME: How should this case be handled?  */  if (reloc_entry->howto->type == R_IMAGEBASE      && output_bfd != NULL      && bfd_get_flavour(output_bfd) == bfd_target_coff_flavour)    diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;#endif#define DOIT(x) \  x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))    if (diff != 0)      {	reloc_howto_type *howto = reloc_entry->howto;	unsigned char *addr = (unsigned char *) data + reloc_entry->address;	switch (howto->size)	  {	  case 0:	    {	      char x = bfd_get_8 (abfd, addr);	      DOIT (x);	      bfd_put_8 (abfd, x, addr);	    }	    break;	  case 1:	    {	      short x = bfd_get_16 (abfd, addr);	      DOIT (x);	      bfd_put_16 (abfd, x, addr);	    }	    break;	  case 2:	    {	      long x = bfd_get_32 (abfd, addr);	      DOIT (x);	      bfd_put_32 (abfd, x, addr);	    }	    break;	  default:	    abort ();	  }      }  /* Now let bfd_perform_relocation finish everything up.  */  return bfd_reloc_continue;}#ifdef COFF_WITH_PE/* Return true if this relocation should appear in the output .reloc   section.  */static boolean in_reloc_p PARAMS ((bfd *, reloc_howto_type *));static boolean in_reloc_p (abfd, howto)     bfd * abfd ATTRIBUTE_UNUSED;     reloc_howto_type *howto;{  return ! howto->pc_relative && howto->type != R_IMAGEBASE;}#endif /* COFF_WITH_PE */#ifndef PCRELOFFSET#define PCRELOFFSET false#endifstatic reloc_howto_type howto_table[] ={  EMPTY_HOWTO (0),  EMPTY_HOWTO (1),  EMPTY_HOWTO (2),  EMPTY_HOWTO (3),  EMPTY_HOWTO (4),  EMPTY_HOWTO (5),  HOWTO (R_DIR32,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 coff_i386_reloc,	/* special_function */	 "dir32",		/* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* PE IMAGE_REL_I386_DIR32NB relocation (7).	*/  HOWTO (R_IMAGEBASE,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 coff_i386_reloc,	/* special_function */	 "rva32",		/* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  EMPTY_HOWTO (010),  EMPTY_HOWTO (011),  EMPTY_HOWTO (012),  EMPTY_HOWTO (013),  EMPTY_HOWTO (014),  EMPTY_HOWTO (015),  EMPTY_HOWTO (016),  /* Byte relocation (017).  */  HOWTO (R_RELBYTE,		/* type */	 0,			/* rightshift */	 0,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 coff_i386_reloc,	/* special_function */	 "8",			/* name */	 true,			/* partial_inplace */	 0x000000ff,		/* src_mask */	 0x000000ff,		/* dst_mask */	 PCRELOFFSET),		/* pcrel_offset */  /* 16-bit word relocation (020).  */  HOWTO (R_RELWORD,		/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 coff_i386_reloc,	/* special_function */	 "16",			/* name */	 true,			/* partial_inplace */	 0x0000ffff,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 PCRELOFFSET),		/* pcrel_offset */  /* 32-bit longword relocation (021).	*/  HOWTO (R_RELLONG,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 coff_i386_reloc,	/* special_function */	 "32",			/* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 PCRELOFFSET),		/* pcrel_offset */  /* Byte PC relative relocation (022).	 */  HOWTO (R_PCRBYTE,		/* type */	 0,			/* rightshift */	 0,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 coff_i386_reloc,	/* special_function */	 "DISP8",		/* name */	 true,			/* partial_inplace */	 0x000000ff,		/* src_mask */	 0x000000ff,		/* dst_mask */	 PCRELOFFSET),		/* pcrel_offset */  /* 16-bit word PC relative relocation (023).	*/  HOWTO (R_PCRWORD,		/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 coff_i386_reloc,	/* special_function */	 "DISP16",		/* name */	 true,			/* partial_inplace */	 0x0000ffff,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 PCRELOFFSET),		/* pcrel_offset */  /* 32-bit longword PC relative relocation (024).  */  HOWTO (R_PCRLONG,		/* type */

⌨️ 快捷键说明

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