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 + -
显示快捷键?