elf32-cris.c

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

C
713
字号
/* CRIS-specific support for 32-bit ELF.   Copyright 2000, 2001 Free Software Foundation, Inc.   Contributed by Axis Communications AB.   Written by Hans-Peter Nilsson, based on elf32-fr30.cThis 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/cris.h"/* Forward declarations.  */static reloc_howto_type * cris_reloc_type_lookup  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));static void cris_info_to_howto_rela  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));static boolean cris_elf_relocate_section  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));static bfd_reloc_status_type cris_final_link_relocate  PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, bfd_vma));static boolean cris_elf_gc_sweep_hook  PARAMS ((bfd *, struct bfd_link_info *, asection *,	   const Elf_Internal_Rela *));static asection * cris_elf_gc_mark_hook  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,	   struct elf_link_hash_entry *, Elf_Internal_Sym *));static boolean cris_elf_object_p PARAMS ((bfd *));static void cris_elf_final_write_processing PARAMS ((bfd *, boolean));static boolean cris_elf_print_private_bfd_data PARAMS ((bfd *, PTR));static boolean cris_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));static reloc_howto_type cris_elf_howto_table [] ={  /* This reloc does nothing.  */  HOWTO (R_CRIS_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_CRIS_NONE",		/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),		/* pcrel_offset */  /* An 8 bit absolute relocation.  */  HOWTO (R_CRIS_8,		/* type */	 0,			/* rightshift */	 0,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_CRIS_8",		/* name */	 false,			/* partial_inplace */	 0x0000,		/* src_mask */	 0x00ff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 16 bit absolute relocation.  */  HOWTO (R_CRIS_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 */	 bfd_elf_generic_reloc,	/* special_function */	 "R_CRIS_16",		/* name */	 false,			/* partial_inplace */	 0x00000000,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 32 bit absolute relocation.  */  HOWTO (R_CRIS_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 */	 bfd_elf_generic_reloc,	/* special_function */	 "R_CRIS_32",		/* name */	 false,			/* partial_inplace */	 0x00000000,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* An 8 bit absolute relocation.  */  HOWTO (R_CRIS_8_PCREL,	/* type */	 0,			/* rightshift */	 0,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_CRIS_8_PCREL",	/* name */	 false,			/* partial_inplace */	 0x0000,		/* src_mask */	 0x00ff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 16 bit absolute relocation.  */  HOWTO (R_CRIS_16_PCREL,	/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 16,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_CRIS_16",		/* name */	 false,			/* partial_inplace */	 0x00000000,		/* src_mask */	 0x0000ffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A 32 bit absolute relocation.  */  HOWTO (R_CRIS_32_PCREL,	/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_CRIS_32",		/* name */	 false,			/* partial_inplace */	 0x00000000,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* GNU extension to record C++ vtable hierarchy */  HOWTO (R_CRIS_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_CRIS_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_CRIS_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_CRIS_GNU_VTENTRY",	 /* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false)			/* pcrel_offset */};/* Map BFD reloc types to CRIS ELF reloc types.  */struct cris_reloc_map{  bfd_reloc_code_real_type bfd_reloc_val;  unsigned int cris_reloc_val;};static const struct cris_reloc_map cris_reloc_map [] ={  { BFD_RELOC_NONE,		R_CRIS_NONE },  { BFD_RELOC_8,		R_CRIS_8 },  { BFD_RELOC_16,		R_CRIS_16 },  { BFD_RELOC_32,		R_CRIS_32 },  { BFD_RELOC_8_PCREL,		R_CRIS_8_PCREL },  { BFD_RELOC_16_PCREL,		R_CRIS_16_PCREL },  { BFD_RELOC_32_PCREL,		R_CRIS_32_PCREL },  { BFD_RELOC_VTABLE_INHERIT,	R_CRIS_GNU_VTINHERIT },  { BFD_RELOC_VTABLE_ENTRY,	R_CRIS_GNU_VTENTRY }};static reloc_howto_type *cris_reloc_type_lookup (abfd, code)     bfd * abfd ATTRIBUTE_UNUSED;     bfd_reloc_code_real_type code;{  unsigned int i;  for (i = sizeof (cris_reloc_map) / sizeof (cris_reloc_map[0]);       --i;)    if (cris_reloc_map [i].bfd_reloc_val == code)      return & cris_elf_howto_table [cris_reloc_map[i].cris_reloc_val];  return NULL;}/* Set the howto pointer for an CRIS ELF reloc.  */static voidcris_info_to_howto_rela (abfd, cache_ptr, dst)     bfd * abfd ATTRIBUTE_UNUSED;     arelent * cache_ptr;     Elf32_Internal_Rela * dst;{  unsigned int r_type;  r_type = ELF32_R_TYPE (dst->r_info);  BFD_ASSERT (r_type < (unsigned int) R_CRIS_max);  cache_ptr->howto = & cris_elf_howto_table [r_type];}/* Perform a single relocation.  By default we use the standard BFD   routines, but we might have to do a few relocs ourselves in the future.  */static bfd_reloc_status_typecris_final_link_relocate (howto, input_bfd, input_section, contents, rel,			  relocation)     reloc_howto_type *  howto;     bfd *               input_bfd;     asection *          input_section;     bfd_byte *          contents;     Elf_Internal_Rela * rel;     bfd_vma             relocation;{  bfd_reloc_status_type r    = _bfd_final_link_relocate (howto, input_bfd, input_section,				contents, rel->r_offset,				relocation, rel->r_addend);  return r;}/* Relocate an CRIS ELF section.  See elf32-fr30.c, from where this was   copied, for further comments.  */static booleancris_elf_relocate_section (output_bfd, info, input_bfd, input_section,			   contents, relocs, local_syms, local_sections)     bfd *                   output_bfd ATTRIBUTE_UNUSED;     struct bfd_link_info *  info;     bfd *                   input_bfd;     asection *              input_section;     bfd_byte *              contents;     Elf_Internal_Rela *     relocs;     Elf_Internal_Sym *      local_syms;     asection **             local_sections;{  Elf_Internal_Shdr *           symtab_hdr;  struct elf_link_hash_entry ** sym_hashes;  Elf_Internal_Rela *           rel;  Elf_Internal_Rela *           relend;  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;  sym_hashes = elf_sym_hashes (input_bfd);  relend     = relocs + input_section->reloc_count;  /* It seems this can happen with erroneous or unsupported input (mixing     a.out and elf in an archive, for example.)  */  if (sym_hashes == NULL)    return false;  for (rel = relocs; rel < relend; rel ++)    {      reloc_howto_type *           howto;      unsigned long                r_symndx;      Elf_Internal_Sym *           sym;      asection *                   sec;      struct elf_link_hash_entry * h;      bfd_vma                      relocation;      bfd_reloc_status_type        r;      const char *                 name = NULL;      int                          r_type;      r_type = ELF32_R_TYPE (rel->r_info);      if (   r_type == R_CRIS_GNU_VTINHERIT	  || r_type == R_CRIS_GNU_VTENTRY)	continue;      r_symndx = ELF32_R_SYM (rel->r_info);      if (info->relocateable)	{	  /* This is a relocateable link.  We don't have to change             anything, unless the reloc is against a section symbol,             in which case we have to adjust according to where the             section symbol winds up in the output section.  */	  if (r_symndx < symtab_hdr->sh_info)	    {	      sym = local_syms + r_symndx;	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)		{		  sec = local_sections [r_symndx];		  rel->r_addend += sec->output_offset + sym->st_value;		}	    }	  continue;	}      /* This is a final link.  */      howto  = cris_elf_howto_table + ELF32_R_TYPE (rel->r_info);      h      = NULL;      sym    = NULL;      sec    = NULL;      if (r_symndx < symtab_hdr->sh_info)	{	  sym = local_syms + r_symndx;	  sec = local_sections [r_symndx];	  relocation = (sec->output_section->vma			+ sec->output_offset			+ sym->st_value);	  name = bfd_elf_string_from_elf_section	    (input_bfd, symtab_hdr->sh_link, sym->st_name);	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;#if 0	  fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",		   sec->name, name, sym->st_name,		   sec->output_section->vma, sec->output_offset,

⌨️ 快捷键说明

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