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