elf32-mcore.c

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

C
750
字号
/* Motorola MCore specific support for 32-bit ELF   Copyright 1994, 1995, 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.  *//* This file is based on a preliminary RCE ELF ABI.  The   information may not match the final RCE ELF ABI.   */#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#include "elf-bfd.h"#include "elf/mcore.h"#include <assert.h>#define	USE_RELA	/* Only USE_REL is actually significant, but this is			   here are a reminder...  */static void mcore_elf_howto_init  PARAMS ((void));static reloc_howto_type * mcore_elf_reloc_type_lookup  PARAMS ((bfd *, bfd_reloc_code_real_type));static void mcore_elf_info_to_howto  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));static boolean mcore_elf_set_private_flags  PARAMS ((bfd *, flagword));static boolean mcore_elf_copy_private_bfd_data  PARAMS ((bfd *, bfd *));static boolean mcore_elf_merge_private_bfd_data  PARAMS ((bfd *, bfd *));static bfd_reloc_status_type mcore_elf_unsupported_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static boolean mcore_elf_relocate_section  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];static reloc_howto_type mcore_elf_howto_raw[] ={  /* This reloc does nothing.  */  HOWTO (R_MCORE_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 */	 NULL,                  /* special_function */	 "R_MCORE_NONE",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),		/* pcrel_offset */  /* A standard 32 bit relocation.  */  HOWTO (R_MCORE_ADDR32,	/* 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 */	 "ADDR32",		/* name *//* For compatability with coff/pe port.  */	 false,			/* partial_inplace */	 0x0,			/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* 8 bits + 2 zero bits; jmpi/jsri/lrw instructions.     Should not appear in object files.  */  HOWTO (R_MCORE_PCRELIMM8BY4,	/* type */	 2,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 8,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 mcore_elf_unsupported_reloc,	/* special_function */	 "R_MCORE_PCRELIMM8BY4",/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 true),			/* pcrel_offset */  /* bsr/bt/bf/br instructions; 11 bits + 1 zero bit     Span 2k instructions == 4k bytes.     Only useful pieces at the relocated address are the opcode (5 bits) */  HOWTO (R_MCORE_PCRELIMM11BY2,/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 11,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_MCORE_PCRELIMM11BY2",/* name */	 false,			/* partial_inplace */	 0x0,			/* src_mask */	 0x7ff,			/* dst_mask */	 true),			/* pcrel_offset */  /* 4 bits + 1 zero bit; 'loopt' instruction only; unsupported.  */  HOWTO (R_MCORE_PCRELIMM4BY2,	/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 4,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 mcore_elf_unsupported_reloc,/* special_function */	 "R_MCORE_PCRELIMM4BY2",/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 true),			/* pcrel_offset */  /* 32-bit pc-relative. Eventually this will help support PIC code.  */  HOWTO (R_MCORE_PCREL32,	/* 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_MCORE_PCREL32",	/* name */	 false,			/* partial_inplace */	 0x0,			/* src_mask */	 0xffffffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* Like PCRELIMM11BY2, this relocation indicates that there is a     'jsri' at the specified address. There is a separate relocation     entry for the literal pool entry that it references, but we     might be able to change the jsri to a bsr if the target turns out     to be close enough [even though we won't reclaim the literal pool     entry, we'll get some runtime efficiency back]. Note that this     is a relocation that we are allowed to safely ignore.  */  HOWTO (R_MCORE_PCRELJSR_IMM11BY2,/* type */	 1,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 11,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_MCORE_PCRELJSR_IMM11BY2", /* name */	 false,			/* partial_inplace */	 0x0,			/* src_mask */	 0x7ff,			/* dst_mask */	 true),			/* pcrel_offset */  /* GNU extension to record C++ vtable hierarchy */  HOWTO (R_MCORE_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_MCORE_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_MCORE_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_MCORE_GNU_VTENTRY", /* name */         false,                 /* partial_inplace */         0,                     /* src_mask */         0,                     /* dst_mask */         false),                /* pcrel_offset */  HOWTO (R_MCORE_RELATIVE,      /* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 32,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_signed, /* complain_on_overflow */	 NULL,                  /* special_function */	 "R_MCORE_RELATIVE",    /* name */	 true,			/* partial_inplace */	 0xffffffff,		/* src_mask */	 0xffffffff,		/* dst_mask */	 false)			/* pcrel_offset */};#ifndef NUM_ELEM#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])#endif/* Initialize the mcore_elf_howto_table, so that linear accesses can be done.  */static voidmcore_elf_howto_init (){  unsigned int i;  for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)    {      unsigned int type;      type = mcore_elf_howto_raw[i].type;      BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));      mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];    }}static reloc_howto_type *mcore_elf_reloc_type_lookup (abfd, code)     bfd * abfd ATTRIBUTE_UNUSED;     bfd_reloc_code_real_type code;{  enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;  switch (code)    {    case BFD_RELOC_NONE:		     mcore_reloc = R_MCORE_NONE; break;    case BFD_RELOC_32:			     mcore_reloc = R_MCORE_ADDR32; break;    case BFD_RELOC_MCORE_PCREL_IMM8BY4:	     mcore_reloc = R_MCORE_PCRELIMM8BY4; break;    case BFD_RELOC_MCORE_PCREL_IMM11BY2:     mcore_reloc = R_MCORE_PCRELIMM11BY2; break;    case BFD_RELOC_MCORE_PCREL_IMM4BY2:	     mcore_reloc = R_MCORE_PCRELIMM4BY2; break;    case BFD_RELOC_32_PCREL:		     mcore_reloc = R_MCORE_PCREL32; break;    case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;    case BFD_RELOC_VTABLE_INHERIT:           mcore_reloc = R_MCORE_GNU_VTINHERIT; break;    case BFD_RELOC_VTABLE_ENTRY:             mcore_reloc = R_MCORE_GNU_VTENTRY; break;    case BFD_RELOC_RVA:                      mcore_reloc = R_MCORE_RELATIVE; break;    default:      return (reloc_howto_type *)NULL;    }  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])	/* Initialize howto table if needed */    mcore_elf_howto_init ();  return mcore_elf_howto_table [(int) mcore_reloc];};/* Set the howto pointer for a RCE ELF reloc.  */static voidmcore_elf_info_to_howto (abfd, cache_ptr, dst)     bfd * abfd ATTRIBUTE_UNUSED;     arelent * cache_ptr;     Elf32_Internal_Rela * dst;{  if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])	/* Initialize howto table if needed */    mcore_elf_howto_init ();  BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);  cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];}/* Function to set whether a module needs the -mrelocatable bit set.  */static booleanmcore_elf_set_private_flags (abfd, flags)     bfd * abfd;     flagword flags;{  BFD_ASSERT (! elf_flags_init (abfd)	      || elf_elfheader (abfd)->e_flags == flags);  elf_elfheader (abfd)->e_flags = flags;  elf_flags_init (abfd) = true;  return true;}/* Copy backend specific data from one object module to another.  */static booleanmcore_elf_copy_private_bfd_data (ibfd, obfd)     bfd * ibfd;     bfd * obfd;{  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)    return true;  BFD_ASSERT (! elf_flags_init (obfd)	      || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;  elf_flags_init (obfd) = true;  return true;}/* Merge backend specific data from an object file to the output   object file when linking.  */static booleanmcore_elf_merge_private_bfd_data (ibfd, obfd)     bfd * ibfd;     bfd * obfd;{  flagword old_flags;  flagword new_flags;  /* Check if we have the same endianess */  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)    return false;  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)    return true;  new_flags = elf_elfheader (ibfd)->e_flags;  old_flags = elf_elfheader (obfd)->e_flags;  if (! elf_flags_init (obfd))	/* First call, no flags set */    {      elf_flags_init (obfd) = true;      elf_elfheader (obfd)->e_flags = new_flags;    }  else if (new_flags == old_flags)	/* Compatible flags are ok */    ;  else    {      /* FIXME */    }  return true;}/* Don't pretend we can deal with unsupported relocs.  */static bfd_reloc_status_typemcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,			   output_bfd, error_message)     bfd * abfd;     arelent * reloc_entry;     asymbol * symbol ATTRIBUTE_UNUSED;     PTR data ATTRIBUTE_UNUSED;     asection * input_section ATTRIBUTE_UNUSED;     bfd * output_bfd ATTRIBUTE_UNUSED;     char ** error_message ATTRIBUTE_UNUSED;{  BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);  _bfd_error_handler (_("%s: Relocation %s (%d) is not currently supported.\n"),		      bfd_get_filename (abfd),		      reloc_entry->howto->name,		      reloc_entry->howto->type);  return bfd_reloc_notsupported;}/* The RELOCATE_SECTION function is called by the ELF backend linker   to handle the relocations for a section.   The relocs are always passed as Rela structures; if the section

⌨️ 快捷键说明

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