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

📄 coff-mips.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* BFD back-end for MIPS Extended-Coff files.   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,   2000, 2001   Free Software Foundation, Inc.   Original version by Per Bothner.   Full support added by Ian Lance Taylor, ian@cygnus.com.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 "bfdlink.h"#include "libbfd.h"#include "coff/internal.h"#include "coff/sym.h"#include "coff/symconst.h"#include "coff/ecoff.h"#include "coff/mips.h"#include "libcoff.h"#include "libecoff.h"/* Prototypes for static functions.  */static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr));static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR,					      struct internal_reloc *));static void mips_ecoff_swap_reloc_out PARAMS ((bfd *,					       const struct internal_reloc *,					       PTR));static void mips_adjust_reloc_in PARAMS ((bfd *,					  const struct internal_reloc *,					  arelent *));static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *,					   struct internal_reloc *));static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd,							 arelent *reloc,							 asymbol *symbol,							 PTR data,							 asection *section,							 bfd *output_bfd,							 char **error));static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd,						       arelent *reloc,						       asymbol *symbol,						       PTR data,						       asection *section,						       bfd *output_bfd,						       char **error));static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd,						       arelent *reloc,						       asymbol *symbol,						       PTR data,						       asection *section,						       bfd *output_bfd,						       char **error));static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd,						       arelent *reloc,						       asymbol *symbol,						       PTR data,						       asection *section,						       bfd *output_bfd,						       char **error));static bfd_reloc_status_type mips_relhi_reloc PARAMS ((bfd *abfd,						       arelent *reloc,						       asymbol *symbol,						       PTR data,						       asection *section,						       bfd *output_bfd,						       char **error));static bfd_reloc_status_type mips_rello_reloc PARAMS ((bfd *abfd,						       arelent *reloc,						       asymbol *symbol,						       PTR data,						       asection *section,						       bfd *output_bfd,						       char **error));static bfd_reloc_status_type mips_switch_reloc PARAMS ((bfd *abfd,							arelent *reloc,							asymbol *symbol,							PTR data,							asection *section,							bfd *output_bfd,							char **error));static void mips_relocate_hi PARAMS ((struct internal_reloc *refhi,				      struct internal_reloc *reflo,				      bfd *input_bfd,				      asection *input_section,				      bfd_byte *contents,				      size_t adjust,				      bfd_vma relocation,				      boolean pcrel));static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *,					      bfd *, asection *,					      bfd_byte *, PTR));static boolean mips_read_relocs PARAMS ((bfd *, asection *));static boolean mips_relax_section PARAMS ((bfd *, asection *,					   struct bfd_link_info *,					   boolean *));static boolean mips_relax_pcrel16 PARAMS ((struct bfd_link_info *, bfd *,					   asection *,					   struct ecoff_link_hash_entry *,					   bfd_byte *, bfd_vma));static reloc_howto_type *mips_bfd_reloc_type_lookup  PARAMS ((bfd *, bfd_reloc_code_real_type));/* ECOFF has COFF sections, but the debugging information is stored in   a completely different format.  ECOFF targets use some of the   swapping routines from coffswap.h, and some of the generic COFF   routines in coffgen.c, but, unlike the real COFF targets, do not   use coffcode.h itself.   Get the generic COFF swapping routines, except for the reloc,   symbol, and lineno ones.  Give them ECOFF names.  */#define MIPSECOFF#define NO_COFF_RELOCS#define NO_COFF_SYMBOLS#define NO_COFF_LINENOS#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in#define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in#define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out#include "coffswap.h"/* Get the ECOFF swapping routines.  */#define ECOFF_32#include "ecoffswap.h"/* How to process the various relocs types.  */static reloc_howto_type mips_howto_table[] ={  /* Reloc type 0 is ignored.  The reloc reading code ensures that     this is a reference to the .abs section, which will cause     bfd_perform_relocation to do nothing.  */  HOWTO (MIPS_R_IGNORE,	/* type */	 0,			/* rightshift */	 0,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 0,			/* special_function */	 "IGNORE",		/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),		/* pcrel_offset */  /* A 16 bit reference to a symbol, normally from a data section.  */  HOWTO (MIPS_R_REFHALF,	/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 mips_generic_reloc,	/* special_function */	 "REFHALF",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 32 bit reference to a symbol, normally from a data section.  */  HOWTO (MIPS_R_REFWORD,	/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 mips_generic_reloc,	/* special_function */	 "REFWORD",		/* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 26 bit absolute jump address.  */  HOWTO (MIPS_R_JMPADDR,	/* type */	 2,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 26,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 			/* This needs complex overflow				   detection, because the upper four				   bits must match the PC.  */	 mips_generic_reloc,	/* special_function */	 "JMPADDR",		/* name */	 true,			/* partial_inplace */	 0x3ffffff,		/* src_mask */	 0x3ffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* The high 16 bits of a symbol value.  Handled by the function     mips_refhi_reloc.  */  HOWTO (MIPS_R_REFHI,		/* type */	 16,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 mips_refhi_reloc,	/* special_function */	 "REFHI",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* The low 16 bits of a symbol value.  */  HOWTO (MIPS_R_REFLO,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 mips_reflo_reloc,	/* special_function */	 "REFLO",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A reference to an offset from the gp register.  Handled by the     function mips_gprel_reloc.  */  HOWTO (MIPS_R_GPREL,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 mips_gprel_reloc,	/* special_function */	 "GPREL",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A reference to a literal using an offset from the gp register.     Handled by the function mips_gprel_reloc.  */  HOWTO (MIPS_R_LITERAL,	/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 mips_gprel_reloc,	/* special_function */	 "LITERAL",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  EMPTY_HOWTO (8),  EMPTY_HOWTO (9),  EMPTY_HOWTO (10),  EMPTY_HOWTO (11),  /* This reloc is a Cygnus extension used when generating position     independent code for embedded systems.  It represents a 16 bit PC     relative reloc rightshifted twice as used in the MIPS branch     instructions.  */  HOWTO (MIPS_R_PCREL16,	/* type */	 2,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 mips_generic_reloc,	/* special_function */	 "PCREL16",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* This reloc is a Cygnus extension used when generating position     independent code for embedded systems.  It represents the high 16     bits of a PC relative reloc.  The next reloc must be     MIPS_R_RELLO, and the addend is formed from the addends of the     two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO.  The     final value is actually PC relative to the location of the     MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc.  */  HOWTO (MIPS_R_RELHI,		/* type */	 16,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 mips_relhi_reloc,	/* special_function */	 "RELHI",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* This reloc is a Cygnus extension used when generating position     independent code for embedded systems.  It represents the low 16     bits of a PC relative reloc.  */  HOWTO (MIPS_R_RELLO,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 mips_rello_reloc,	/* special_function */	 "RELLO",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 true),			/* pcrel_offset */  EMPTY_HOWTO (15),  EMPTY_HOWTO (16),  EMPTY_HOWTO (17),  EMPTY_HOWTO (18),  EMPTY_HOWTO (19),  EMPTY_HOWTO (20),  EMPTY_HOWTO (21),  /* This reloc is a Cygnus extension used when generating position     independent code for embedded systems.  It represents an entry in     a switch table, which is the difference between two symbols in     the .text section.  The symndx is actually the offset from the     reloc address to the subtrahend.  See include/coff/mips.h for     more details.  */  HOWTO (MIPS_R_SWITCH,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 mips_switch_reloc,	/* special_function */	 "SWITCH",		/* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 true)			/* pcrel_offset */};#define MIPS_HOWTO_COUNT \  (sizeof mips_howto_table / sizeof mips_howto_table[0])/* When the linker is doing relaxing, it may change a external PCREL16   reloc.  This typically represents an instruction like       bal foo   We change it to       .set  noreorder       bal   $L1       lui   $at,%hi(foo - $L1)     $L1:       addiu $at,%lo(foo - $L1)       addu  $at,$at,$31       jalr  $at   PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the   instruction by.  */#define PCREL16_EXPANSION_ADJUSTMENT (4 * 4)/* See whether the magic number matches.  */static booleanmips_ecoff_bad_format_hook (abfd, filehdr)     bfd *abfd;     PTR filehdr;{  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;  switch (internal_f->f_magic)    {    case MIPS_MAGIC_1:      /* I don't know what endianness this implies.  */      return true;    case MIPS_MAGIC_BIG:    case MIPS_MAGIC_BIG2:    case MIPS_MAGIC_BIG3:      return bfd_big_endian (abfd);    case MIPS_MAGIC_LITTLE:    case MIPS_MAGIC_LITTLE2:    case MIPS_MAGIC_LITTLE3:      return bfd_little_endian (abfd);    default:      return false;    }}/* Reloc handling.  MIPS ECOFF relocs are packed into 8 bytes in   external form.  They use a bit which indicates whether the symbol   is external.  *//* Swap a reloc in.  */static voidmips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)     bfd *abfd;

⌨️ 快捷键说明

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