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

📄 elf32-m32r.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* M32R-specific support for 32-bit ELF.   Copyright 1996, 1997, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.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 "elf-bfd.h"#include "elf/m32r.h"static bfd_reloc_status_type m32r_elf_10_pcrel_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static bfd_reloc_status_type m32r_elf_do_10_pcrel_reloc  PARAMS ((bfd *, reloc_howto_type *, asection *,	   bfd_byte *, bfd_vma, asection *, bfd_vma, bfd_vma));static bfd_reloc_status_type m32r_elf_hi16_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static void m32r_elf_relocate_hi16  PARAMS ((bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *,	   bfd_byte *, bfd_vma));bfd_reloc_status_type m32r_elf_lo16_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));bfd_reloc_status_type m32r_elf_generic_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static bfd_reloc_status_type m32r_elf_sda16_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));static void m32r_info_to_howto_rel  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));boolean _bfd_m32r_elf_section_from_bfd_section  PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *));void _bfd_m32r_elf_symbol_processing  PARAMS ((bfd *, asymbol *));static boolean m32r_elf_add_symbol_hook  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,	   const char **, flagword *, asection **, bfd_vma *));static boolean m32r_elf_relocate_section  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));#if 0 /* not yet */static boolean m32r_elf_relax_delete_bytes  PARAMS ((bfd *, asection *, bfd_vma, int));#endifstatic bfd_reloc_status_type m32r_elf_final_sda_base  PARAMS ((bfd *, struct bfd_link_info *, const char **, bfd_vma *));static boolean m32r_elf_object_p  PARAMS ((bfd *));static void m32r_elf_final_write_processing  PARAMS ((bfd *, boolean));static boolean m32r_elf_set_private_flags  PARAMS ((bfd *, flagword));static boolean m32r_elf_copy_private_bfd_data  PARAMS ((bfd *, bfd *));static boolean m32r_elf_merge_private_bfd_data  PARAMS ((bfd *, bfd *));static boolean m32r_elf_print_private_bfd_data  PARAMS ((bfd *, PTR));#define NOP_INSN		0x7000#define MAKE_PARALLEL(insn)	((insn) | 0x8000)/* Use REL instead of RELA to save space.   This only saves space in libraries and object files, but perhaps   relocs will be put in ROM?  All in all though, REL relocs are a pain   to work with.  */#define USE_RELstatic reloc_howto_type m32r_elf_howto_table[] ={  /* This reloc does nothing.  */  HOWTO (R_M32R_NONE,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_M32R_NONE",		/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),		/* pcrel_offset */  /* A 16 bit absolute relocation.  */  HOWTO (R_M32R_16,		/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 m32r_elf_generic_reloc,/* special_function */	 "R_M32R_16",		/* name */	 true,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 32 bit absolute relocation.  */  HOWTO (R_M32R_32,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 m32r_elf_generic_reloc,/* special_function */	 "R_M32R_32",		/* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 24 bit address.  */  HOWTO (R_M32R_24,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 24,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_unsigned, /* complain_on_overflow */	 m32r_elf_generic_reloc,/* special_function */	 "R_M32R_24",		/* name */	 true,			/* partial_inplace */	 0xffffff,		/* src_mask */	 0xffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* An PC Relative 10-bit relocation, shifted by 2.     This reloc is complicated because relocations are relative to pc & -4.     i.e. branches in the right insn slot use the address of the left insn     slot for pc.  */  /* ??? It's not clear whether this should have partial_inplace set or not.     Branch relaxing in the assembler can store the addend in the insn,     and if bfd_install_relocation gets called the addend may get added     again.  */  HOWTO (R_M32R_10_PCREL,	/* type */	 2,	                /* rightshift */	 1,	                /* size (0 = byte, 1 = short, 2 = long) */	 10,	                /* bitsize */	 true,	                /* pc_relative */	 0,	                /* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 m32r_elf_10_pcrel_reloc, /* special_function */	 "R_M32R_10_PCREL",	/* name */	 false,	                /* partial_inplace */	 0xff,		        /* src_mask */	 0xff,   		/* dst_mask */	 true),			/* pcrel_offset */  /* A relative 18 bit relocation, right shifted by 2.  */  HOWTO (R_M32R_18_PCREL,	/* type */	 2,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_M32R_18_PCREL",	/* name */	 false,			/* partial_inplace */	 0xffff,		/* src_mask */	 0xffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* A relative 26 bit relocation, right shifted by 2.  */  /* ??? It's not clear whether this should have partial_inplace set or not.     Branch relaxing in the assembler can store the addend in the insn,     and if bfd_install_relocation gets called the addend may get added     again.  */  HOWTO (R_M32R_26_PCREL,	/* type */	 2,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 26,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_M32R_26_PCREL",	/* name */	 false,			/* partial_inplace */	 0xffffff,		/* src_mask */	 0xffffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* High 16 bits of address when lower 16 is or'd in.  */  HOWTO (R_M32R_HI16_ULO,	/* type */	 16,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 m32r_elf_hi16_reloc,	/* special_function */	 "R_M32R_HI16_ULO",	/* name */	 true,			/* partial_inplace */	 0x0000ffff,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* High 16 bits of address when lower 16 is added in.  */  HOWTO (R_M32R_HI16_SLO,	/* type */	 16,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 m32r_elf_hi16_reloc,	/* special_function */	 "R_M32R_HI16_SLO",	/* name */	 true,			/* partial_inplace */	 0x0000ffff,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* Lower 16 bits of address.  */  HOWTO (R_M32R_LO16,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_dont, /* complain_on_overflow */	 m32r_elf_lo16_reloc,	/* special_function */	 "R_M32R_LO16",		/* name */	 true,			/* partial_inplace */	 0x0000ffff,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* Small data area 16 bits offset.  */  HOWTO (R_M32R_SDA16,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 m32r_elf_sda16_reloc,	/* special_function */	 "R_M32R_SDA16",	/* name */	 true,			/* partial_inplace */  /* FIXME: correct? */	 0x0000ffff,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* GNU extension to record C++ vtable hierarchy */  HOWTO (R_M32R_GNU_VTINHERIT, /* type */         0,                     /* rightshift */         2,                     /* size (0 = byte, 1 = short, 2 = long) */         0,                     /* bitsize */         false,                 /* pc_relative */         0,                     /* bitpos */         complain_overflow_dont, /* complain_on_overflow */         NULL,                  /* special_function */         "R_M32R_GNU_VTINHERIT", /* name */         false,                 /* partial_inplace */         0,                     /* src_mask */         0,                     /* dst_mask */         false),                /* pcrel_offset */  /* GNU extension to record C++ vtable member usage */  HOWTO (R_M32R_GNU_VTENTRY,     /* type */         0,                     /* rightshift */         2,                     /* size (0 = byte, 1 = short, 2 = long) */         0,                     /* bitsize */         false,                 /* pc_relative */         0,                     /* bitpos */         complain_overflow_dont, /* complain_on_overflow */         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */         "R_M32R_GNU_VTENTRY",   /* name */         false,                 /* partial_inplace */         0,                     /* src_mask */         0,                     /* dst_mask */         false),                /* pcrel_offset */};/* Handle the R_M32R_10_PCREL reloc.  */static bfd_reloc_status_typem32r_elf_10_pcrel_reloc (abfd, reloc_entry, symbol, data,			 input_section, output_bfd, error_message)     bfd * abfd;     arelent * reloc_entry;     asymbol * symbol;     PTR data;     asection * input_section;     bfd * output_bfd;     char ** error_message ATTRIBUTE_UNUSED;{  /* This part is from bfd_elf_generic_reloc.  */  if (output_bfd != (bfd *) NULL      && (symbol->flags & BSF_SECTION_SYM) == 0      && (! reloc_entry->howto->partial_inplace	  || reloc_entry->addend == 0))    {      reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  if (output_bfd != NULL)    {      /* FIXME: See bfd_perform_relocation.  Is this right?  */      return bfd_reloc_continue;    }  return m32r_elf_do_10_pcrel_reloc (abfd, reloc_entry->howto,				     input_section,				     data, reloc_entry->address,				     symbol->section,				     (symbol->value				      + symbol->section->output_section->vma				      + symbol->section->output_offset),				     reloc_entry->addend);}/* Utility to actually perform an R_M32R_10_PCREL reloc.  */static bfd_reloc_status_typem32r_elf_do_10_pcrel_reloc (abfd, howto, input_section, data, offset,			    symbol_section, symbol_value, addend)     bfd *abfd;     reloc_howto_type *howto;     asection *input_section;     bfd_byte *data;     bfd_vma offset;     asection *symbol_section ATTRIBUTE_UNUSED;     bfd_vma symbol_value;     bfd_vma addend;{  bfd_signed_vma relocation;  unsigned long x;  bfd_reloc_status_type status;  /* Sanity check the address (offset in section).  */  if (offset > input_section->_cooked_size)    return bfd_reloc_outofrange;  relocation = symbol_value + addend;  /* Make it pc relative.  */  relocation -=	(input_section->output_section->vma		 + input_section->output_offset);  /* These jumps mask off the lower two bits of the current address     before doing pcrel calculations.  */  relocation -= (offset & -4L);  if (relocation < -0x200 || relocation > 0x1ff)    status = bfd_reloc_overflow;  else    status = bfd_reloc_ok;  x = bfd_get_16 (abfd, data + offset);  relocation >>= howto->rightshift;  relocation <<= howto->bitpos;  x = (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask);  bfd_put_16 (abfd, x, data + offset);  return status;}/* Handle the R_M32R_HI16_[SU]LO relocs.   HI16_SLO is for the add3 and load/store with displacement instructions.   HI16_ULO is for the or3 instruction.   For R_M32R_HI16_SLO, the lower 16 bits are sign extended when added to   the high 16 bytes so if the lower 16 bits are negative (bit 15 == 1) then   we must add one to the high 16 bytes (which will get subtracted off when   the low 16 bits are added).   These relocs have to be done in combination with an R_M32R_LO16 reloc   because there is a carry from the LO16 to the HI16.  Here we just save   the information we need; we do the actual relocation when we see the LO16.   This code is copied from the elf32-mips.c.  We also support an arbitrary   number of HI16 relocs to be associated with a single LO16 reloc.  The   assembler sorts the relocs to ensure each HI16 immediately precedes its   LO16.  However if there are multiple copies, the assembler may not find   the real LO16 so it picks the first one it finds.  */struct m32r_hi16{  struct m32r_hi16 *next;  bfd_byte *addr;  bfd_vma addend;};/* FIXME: This should not be a static variable.  */static struct m32r_hi16 *m32r_hi16_list;static bfd_reloc_status_typem32r_elf_hi16_reloc (abfd, reloc_entry, symbol, data,		     input_section, output_bfd, error_message)     bfd *abfd ATTRIBUTE_UNUSED;     arelent *reloc_entry;     asymbol *symbol;     PTR data;     asection *input_section;     bfd *output_bfd;     char **error_message ATTRIBUTE_UNUSED;{  bfd_reloc_status_type ret;  bfd_vma relocation;  struct m32r_hi16 *n;  /* This part is from bfd_elf_generic_reloc.     If we're relocating, and this an external symbol, we don't want     to change anything.  */  if (output_bfd != (bfd *) NULL      && (symbol->flags & BSF_SECTION_SYM) == 0      && reloc_entry->addend == 0)    {

⌨️ 快捷键说明

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