elf32-i370.c

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

C
1,723
字号
/* i370-specific support for 32-bit ELF   Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001   Free Software Foundation, Inc.   Written by Ian Lance Taylor, Cygnus Support.   Hacked by Linas Vepstas for i370 linas@linas.orgThis 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 PowerPC ELF ABI.   But its been hacked on for the IBM 360/370 architectures.   Basically, the 31bit relocation works, and just about everything   else is a wild card.  In particular, don't expect shared libs or   dynamic loading to work ...  its never been tested ...*/#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#include "elf-bfd.h"#include "elf/i370.h"#define USE_RELA		/* we want RELA relocations, not REL *//* i370 relocations *//* Note that there is really just one relocation that we currently * support (and only one that we seem to need, at the moment), and * that is the 31-bit address relocation.  Note that the 370/390 * only supports a 31-bit (2GB) address space. */enum i370_reloc_type{  R_I370_NONE		=   0,  R_I370_ADDR31		=   1,  R_I370_ADDR32		=   2,  R_I370_ADDR16		=   3,  R_I370_REL31		=   4,  R_I370_REL32		=   5,  R_I370_ADDR12		=   6,  R_I370_REL12		=   7,  R_I370_ADDR8		=   8,  R_I370_REL8		=   9,  R_I370_COPY		=  10,  R_I370_RELATIVE	=  11,  R_I370_max};static reloc_howto_type *i370_elf_howto_table[ (int)R_I370_max ];static reloc_howto_type i370_elf_howto_raw[] ={  /* This reloc does nothing.  */  HOWTO (R_I370_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_I370_NONE",		/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),		/* pcrel_offset */  /* A standard 31 bit relocation.  */  HOWTO (R_I370_ADDR31,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 31,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_I370_ADDR31",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0x7fffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A standard 32 bit relocation.  */  HOWTO (R_I370_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 */	 "R_I370_ADDR32",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* A standard 16 bit relocation.  */  HOWTO (R_I370_ADDR16,		/* 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_I370_ADDR16",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xffff,		/* dst_mask */	 false),		/* pcrel_offset */  /* 31-bit PC relative */  HOWTO (R_I370_REL31,		/* type */	 0,			/* rightshift */	 2,			/* size (0 = byte, 1 = short, 2 = long) */	 31,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_I370_REL31",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0x7fffffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* 32-bit PC relative */  HOWTO (R_I370_REL32,		/* 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_I370_REL32",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xffffffff,		/* dst_mask */	 true),			/* pcrel_offset */  /* A standard 12 bit relocation.  */  HOWTO (R_I370_ADDR12,		/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 12,			/* bitsize */	 false,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_I370_ADDR12",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xfff,			/* dst_mask */	 false),		/* pcrel_offset */  /* 12-bit PC relative */  HOWTO (R_I370_REL12,		/* type */	 0,			/* rightshift */	 1,			/* size (0 = byte, 1 = short, 2 = long) */	 12,			/* bitsize */	 true,			/* pc_relative */	 0,			/* bitpos */	 complain_overflow_bitfield, /* complain_on_overflow */	 bfd_elf_generic_reloc,	/* special_function */	 "R_I370_REL12",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xfff,			/* dst_mask */	 true),			/* pcrel_offset */  /* A standard 8 bit relocation.  */  HOWTO (R_I370_ADDR8,		/* 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_I370_ADDR8",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xff,			/* dst_mask */	 false),		/* pcrel_offset */  /* 8-bit PC relative */  HOWTO (R_I370_REL8,		/* 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_I370_REL8",		/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xff,			/* dst_mask */	 true),			/* pcrel_offset */  /* This is used only by the dynamic linker.  The symbol should exist     both in the object being run and in some shared library.  The     dynamic linker copies the data addressed by the symbol from the     shared library into the object, because the object being     run has to have the data at some particular address.  */  HOWTO (R_I370_COPY,		/* 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_I370_COPY",		/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),		/* pcrel_offset */  /* Used only by the dynamic linker.  When the object is run, this     longword is set to the load address of the object, plus the     addend.  */  HOWTO (R_I370_RELATIVE,	/* 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_I370_RELATIVE",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0xffffffff,		/* dst_mask */	 false),		/* pcrel_offset */};static void i370_elf_howto_init PARAMS ((void));static void i370_elf_info_to_howto PARAMS ((bfd *abfd, arelent *cache_ptr,					    Elf32_Internal_Rela *dst));static boolean i370_elf_set_private_flags PARAMS ((bfd *, flagword));/* Initialize the i370_elf_howto_table, so that linear accesses can be done.  */static voidi370_elf_howto_init (){  unsigned int i, type;  for (i = 0; i < sizeof (i370_elf_howto_raw) / sizeof (i370_elf_howto_raw[0]); i++)    {      type = i370_elf_howto_raw[i].type;      BFD_ASSERT (type < sizeof (i370_elf_howto_table) / sizeof (i370_elf_howto_table[0]));      i370_elf_howto_table[type] = &i370_elf_howto_raw[i];    }}static reloc_howto_type *i370_elf_reloc_type_lookup (abfd, code)     bfd *abfd ATTRIBUTE_UNUSED;     bfd_reloc_code_real_type code;{  enum i370_reloc_type i370_reloc = R_I370_NONE;  if (!i370_elf_howto_table[ R_I370_ADDR31 ])	/* Initialize howto table if needed */    i370_elf_howto_init ();  switch ((int)code)    {    default:      return (reloc_howto_type *)NULL;    case BFD_RELOC_NONE:	i370_reloc = R_I370_NONE;	break;    case BFD_RELOC_32:		i370_reloc = R_I370_ADDR31;	break;    case BFD_RELOC_16:		i370_reloc = R_I370_ADDR16;	break;    case BFD_RELOC_32_PCREL:	i370_reloc = R_I370_REL31;	break;    case BFD_RELOC_CTOR:	i370_reloc = R_I370_ADDR31;	break;    case BFD_RELOC_I370_D12:	i370_reloc = R_I370_ADDR12;	break;    }  return i370_elf_howto_table[ (int)i370_reloc ];};static boolean i370_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));static boolean i370_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));static boolean i370_elf_relocate_section PARAMS ((bfd *,						  struct bfd_link_info *info,						  bfd *,						  asection *,						  bfd_byte *,						  Elf_Internal_Rela *relocs,						  Elf_Internal_Sym *local_syms,						  asection **));static boolean i370_elf_create_dynamic_sections PARAMS ((bfd *,							 struct bfd_link_info *));static boolean i370_elf_section_from_shdr PARAMS ((bfd *,						   Elf32_Internal_Shdr *,						   char *));static boolean i370_elf_fake_sections PARAMS ((bfd *,					       Elf32_Internal_Shdr *,					       asection *));#if 0static elf_linker_section_t *i370_elf_create_linker_section  PARAMS ((bfd *abfd,	   struct bfd_link_info *info,	   enum elf_linker_section_enum));#endifstatic boolean i370_elf_check_relocs PARAMS ((bfd *,					     struct bfd_link_info *,					     asection *,					     const Elf_Internal_Rela *));static boolean i370_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *,						      struct elf_link_hash_entry *));static boolean i370_elf_adjust_dynindx PARAMS ((struct elf_link_hash_entry *, PTR));static boolean i370_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));static boolean i370_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *));/* The name of the dynamic interpreter.  This is put in the .interp    section.  */#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"/* Set the howto pointer for an i370 ELF reloc.  */static voidi370_elf_info_to_howto (abfd, cache_ptr, dst)     bfd *abfd ATTRIBUTE_UNUSED;     arelent *cache_ptr;     Elf32_Internal_Rela *dst;{  if (!i370_elf_howto_table[ R_I370_ADDR31 ])	/* Initialize howto table */    i370_elf_howto_init ();  BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_I370_max);  cache_ptr->howto = i370_elf_howto_table[ELF32_R_TYPE (dst->r_info)];}/* hack alert --  the following several routines look generic to me ... * why are we bothering with them ??? *//* Function to set whether a module needs the -mrelocatable bit set.  */static booleani370_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 booleani370_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 booleani370_elf_merge_private_bfd_data (ibfd, obfd)     bfd *ibfd;     bfd *obfd;{  flagword old_flags;  flagword new_flags;  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					/* Incompatible flags */    {      (*_bfd_error_handler)	("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)",	 bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);      bfd_set_error (bfd_error_bad_value);      return false;    }

⌨️ 快捷键说明

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