⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elf32-i386.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Intel 80386/80486-specific support for 32-bit ELF   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 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.  */#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#include "elf-bfd.h"static reloc_howto_type *elf_i386_reloc_type_lookup  PARAMS ((bfd *, bfd_reloc_code_real_type));static void elf_i386_info_to_howto  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));static void elf_i386_info_to_howto_rel  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));static boolean elf_i386_is_local_label_name PARAMS ((bfd *, const char *));static struct bfd_hash_entry *elf_i386_link_hash_newfunc  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));static struct bfd_link_hash_table *elf_i386_link_hash_table_create  PARAMS ((bfd *));static boolean elf_i386_check_relocs  PARAMS ((bfd *, struct bfd_link_info *, asection *,	   const Elf_Internal_Rela *));static boolean elf_i386_adjust_dynamic_symbol  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));static boolean elf_i386_size_dynamic_sections  PARAMS ((bfd *, struct bfd_link_info *));static boolean elf_i386_relocate_section  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));static boolean elf_i386_finish_dynamic_symbol  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,	   Elf_Internal_Sym *));static boolean elf_i386_finish_dynamic_sections  PARAMS ((bfd *, struct bfd_link_info *));#define USE_REL	1		/* 386 uses REL relocations instead of RELA */#include "elf/i386.h"static reloc_howto_type elf_howto_table[]={  HOWTO(R_386_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_NONE",	true, 0x00000000, 0x00000000, false),  HOWTO(R_386_32, 0, 2, 32, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_32",	true, 0xffffffff, 0xffffffff, false),  HOWTO(R_386_PC32, 0, 2, 32, true, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_PC32",	true, 0xffffffff, 0xffffffff, true),  HOWTO(R_386_GOT32, 0, 2, 32, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_GOT32",	true, 0xffffffff, 0xffffffff, false),  HOWTO(R_386_PLT32, 0, 2, 32, true, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_PLT32",	true, 0xffffffff, 0xffffffff, true),  HOWTO(R_386_COPY, 0, 2, 32, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_COPY",	true, 0xffffffff, 0xffffffff, false),  HOWTO(R_386_GLOB_DAT, 0, 2, 32, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_GLOB_DAT",	true, 0xffffffff, 0xffffffff, false),  HOWTO(R_386_JUMP_SLOT, 0, 2, 32, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_JUMP_SLOT",	true, 0xffffffff, 0xffffffff, false),  HOWTO(R_386_RELATIVE, 0, 2, 32, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_RELATIVE",	true, 0xffffffff, 0xffffffff, false),  HOWTO(R_386_GOTOFF, 0, 2, 32, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_GOTOFF",	true, 0xffffffff, 0xffffffff, false),  HOWTO(R_386_GOTPC, 0, 2, 32, true, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_GOTPC",	true, 0xffffffff, 0xffffffff, true),  /* We have a gap in the reloc numbers here.     R_386_standard counts the number up to this point, and     R_386_ext_offset is the value to subtract from a reloc type of     R_386_16 thru R_386_PC8 to form an index into this table.  */#define R_386_standard ((unsigned int) R_386_GOTPC + 1)#define R_386_ext_offset ((unsigned int) R_386_16 - R_386_standard)  /* The remaining relocs are a GNU extension.  */  HOWTO(R_386_16, 0, 1, 16, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_16",	true, 0xffff, 0xffff, false),  HOWTO(R_386_PC16, 0, 1, 16, true, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_PC16",	true, 0xffff, 0xffff, true),  HOWTO(R_386_8, 0, 0, 8, false, 0, complain_overflow_bitfield,	bfd_elf_generic_reloc, "R_386_8",	true, 0xff, 0xff, false),  HOWTO(R_386_PC8, 0, 0, 8, true, 0, complain_overflow_signed,	bfd_elf_generic_reloc, "R_386_PC8",	true, 0xff, 0xff, true),  /* Another gap.  */#define R_386_ext ((unsigned int) R_386_PC8 + 1 - R_386_ext_offset)#define R_386_vt_offset ((unsigned int) R_386_GNU_VTINHERIT - R_386_ext)/* GNU extension to record C++ vtable hierarchy.  */  HOWTO (R_386_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_386_GNU_VTINHERIT",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false),/* GNU extension to record C++ vtable member usage.  */  HOWTO (R_386_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_386_GNU_VTENTRY",	/* name */	 false,			/* partial_inplace */	 0,			/* src_mask */	 0,			/* dst_mask */	 false)#define R_386_vt ((unsigned int) R_386_GNU_VTENTRY + 1 - R_386_vt_offset)};#ifdef DEBUG_GEN_RELOC#define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)#else#define TRACE(str)#endifstatic reloc_howto_type *elf_i386_reloc_type_lookup (abfd, code)     bfd *abfd ATTRIBUTE_UNUSED;     bfd_reloc_code_real_type code;{  switch (code)    {    case BFD_RELOC_NONE:      TRACE ("BFD_RELOC_NONE");      return &elf_howto_table[(unsigned int) R_386_NONE ];    case BFD_RELOC_32:      TRACE ("BFD_RELOC_32");      return &elf_howto_table[(unsigned int) R_386_32 ];    case BFD_RELOC_CTOR:      TRACE ("BFD_RELOC_CTOR");      return &elf_howto_table[(unsigned int) R_386_32 ];    case BFD_RELOC_32_PCREL:      TRACE ("BFD_RELOC_PC32");      return &elf_howto_table[(unsigned int) R_386_PC32 ];    case BFD_RELOC_386_GOT32:      TRACE ("BFD_RELOC_386_GOT32");      return &elf_howto_table[(unsigned int) R_386_GOT32 ];    case BFD_RELOC_386_PLT32:      TRACE ("BFD_RELOC_386_PLT32");      return &elf_howto_table[(unsigned int) R_386_PLT32 ];    case BFD_RELOC_386_COPY:      TRACE ("BFD_RELOC_386_COPY");      return &elf_howto_table[(unsigned int) R_386_COPY ];    case BFD_RELOC_386_GLOB_DAT:      TRACE ("BFD_RELOC_386_GLOB_DAT");      return &elf_howto_table[(unsigned int) R_386_GLOB_DAT ];    case BFD_RELOC_386_JUMP_SLOT:      TRACE ("BFD_RELOC_386_JUMP_SLOT");      return &elf_howto_table[(unsigned int) R_386_JUMP_SLOT ];    case BFD_RELOC_386_RELATIVE:      TRACE ("BFD_RELOC_386_RELATIVE");      return &elf_howto_table[(unsigned int) R_386_RELATIVE ];    case BFD_RELOC_386_GOTOFF:      TRACE ("BFD_RELOC_386_GOTOFF");      return &elf_howto_table[(unsigned int) R_386_GOTOFF ];    case BFD_RELOC_386_GOTPC:      TRACE ("BFD_RELOC_386_GOTPC");      return &elf_howto_table[(unsigned int) R_386_GOTPC ];      /* The remaining relocs are a GNU extension.  */    case BFD_RELOC_16:      TRACE ("BFD_RELOC_16");      return &elf_howto_table[(unsigned int) R_386_16 - R_386_ext_offset];    case BFD_RELOC_16_PCREL:      TRACE ("BFD_RELOC_16_PCREL");      return &elf_howto_table[(unsigned int) R_386_PC16 - R_386_ext_offset];    case BFD_RELOC_8:      TRACE ("BFD_RELOC_8");      return &elf_howto_table[(unsigned int) R_386_8 - R_386_ext_offset];    case BFD_RELOC_8_PCREL:      TRACE ("BFD_RELOC_8_PCREL");      return &elf_howto_table[(unsigned int) R_386_PC8 - R_386_ext_offset];    case BFD_RELOC_VTABLE_INHERIT:      TRACE ("BFD_RELOC_VTABLE_INHERIT");      return &elf_howto_table[(unsigned int) R_386_GNU_VTINHERIT			     - R_386_vt_offset];    case BFD_RELOC_VTABLE_ENTRY:      TRACE ("BFD_RELOC_VTABLE_ENTRY");      return &elf_howto_table[(unsigned int) R_386_GNU_VTENTRY			     - R_386_vt_offset];    default:      break;    }  TRACE ("Unknown");  return 0;}static voidelf_i386_info_to_howto (abfd, cache_ptr, dst)     bfd		*abfd ATTRIBUTE_UNUSED;     arelent		*cache_ptr ATTRIBUTE_UNUSED;     Elf32_Internal_Rela *dst ATTRIBUTE_UNUSED;{  abort ();}static voidelf_i386_info_to_howto_rel (abfd, cache_ptr, dst)     bfd *abfd ATTRIBUTE_UNUSED;     arelent *cache_ptr;     Elf32_Internal_Rel *dst;{  unsigned int r_type = ELF32_R_TYPE (dst->r_info);  unsigned int indx;  if ((indx = r_type) >= R_386_standard      && ((indx = r_type - R_386_ext_offset) - R_386_standard	  >= R_386_ext - R_386_standard)      && ((indx = r_type - R_386_vt_offset) - R_386_ext	  >= R_386_vt - R_386_ext))    {      (*_bfd_error_handler) (_("%s: invalid relocation type %d"),			     bfd_get_filename (abfd), (int) r_type);      indx = (unsigned int) R_386_NONE;    }  cache_ptr->howto = &elf_howto_table[indx];}/* Return whether a symbol name implies a local label.  The UnixWare   2.1 cc generates temporary symbols that start with .X, so we   recognize them here.  FIXME: do other SVR4 compilers also use .X?.   If so, we should move the .X recognition into   _bfd_elf_is_local_label_name.  */static booleanelf_i386_is_local_label_name (abfd, name)     bfd *abfd;     const char *name;{  if (name[0] == '.' && name[1] == 'X')    return true;  return _bfd_elf_is_local_label_name (abfd, name);}/* Functions for the i386 ELF linker.  *//* The name of the dynamic interpreter.  This is put in the .interp   section.  */#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"/* The size in bytes of an entry in the procedure linkage table.  */#define PLT_ENTRY_SIZE 16/* The first entry in an absolute procedure linkage table looks like   this.  See the SVR4 ABI i386 supplement to see how this works.  */static const bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] ={  0xff, 0x35,	/* pushl contents of address */  0, 0, 0, 0,	/* replaced with address of .got + 4.  */  0xff, 0x25,	/* jmp indirect */  0, 0, 0, 0,	/* replaced with address of .got + 8.  */  0, 0, 0, 0	/* pad out to 16 bytes.  */};/* Subsequent entries in an absolute procedure linkage table look like   this.  */static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] ={  0xff, 0x25,	/* jmp indirect */  0, 0, 0, 0,	/* replaced with address of this symbol in .got.  */  0x68,		/* pushl immediate */  0, 0, 0, 0,	/* replaced with offset into relocation table.  */  0xe9,		/* jmp relative */  0, 0, 0, 0	/* replaced with offset to start of .plt.  */};/* The first entry in a PIC procedure linkage table look like this.  */static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] ={  0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx) */  0xff, 0xa3, 8, 0, 0, 0,	/* jmp *8(%ebx) */  0, 0, 0, 0			/* pad out to 16 bytes.  */};/* Subsequent entries in a PIC procedure linkage table look like this.  */static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] ={  0xff, 0xa3,	/* jmp *offset(%ebx) */  0, 0, 0, 0,	/* replaced with offset of this symbol in .got.  */  0x68,		/* pushl immediate */  0, 0, 0, 0,	/* replaced with offset into relocation table.  */  0xe9,		/* jmp relative */  0, 0, 0, 0	/* replaced with offset to start of .plt.  */};/* The i386 linker needs to keep track of the number of relocs that it   decides to copy in check_relocs for each symbol.  This is so that   it can discard PC relative relocs if it doesn't need them when   linking with -Bsymbolic.  We store the information in a field   extending the regular ELF linker hash table.  *//* This structure keeps track of the number of PC relative relocs we   have copied for a given symbol.  */struct elf_i386_pcrel_relocs_copied{  /* Next section.  */  struct elf_i386_pcrel_relocs_copied *next;  /* A section in dynobj.  */  asection *section;  /* Number of relocs copied in this section.  */  bfd_size_type count;};/* i386 ELF linker hash entry.  */struct elf_i386_link_hash_entry{  struct elf_link_hash_entry root;  /* Number of PC relative relocs copied for this symbol.  */  struct elf_i386_pcrel_relocs_copied *pcrel_relocs_copied;};/* i386 ELF linker hash table.  */struct elf_i386_link_hash_table{  struct elf_link_hash_table root;};/* Declare this now that the above structures are defined.  */static boolean elf_i386_discard_copies  PARAMS ((struct elf_i386_link_hash_entry *, PTR));/* Traverse an i386 ELF linker hash table.  */#define elf_i386_link_hash_traverse(table, func, info)			\  (elf_link_hash_traverse						\   (&(table)->root,							\    (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func),	\    (info)))/* Get the i386 ELF linker hash table from a link_info structure.  */#define elf_i386_hash_table(p) \  ((struct elf_i386_link_hash_table *) ((p)->hash))/* Create an entry in an i386 ELF linker hash table.  */static struct bfd_hash_entry *elf_i386_link_hash_newfunc (entry, table, string)     struct bfd_hash_entry *entry;     struct bfd_hash_table *table;     const char *string;{  struct elf_i386_link_hash_entry *ret =    (struct elf_i386_link_hash_entry *) entry;  /* Allocate the structure if it has not already been allocated by a     subclass.  */  if (ret == (struct elf_i386_link_hash_entry *) NULL)    ret = ((struct elf_i386_link_hash_entry *)	   bfd_hash_allocate (table,			      sizeof (struct elf_i386_link_hash_entry)));  if (ret == (struct elf_i386_link_hash_entry *) NULL)    return (struct bfd_hash_entry *) ret;  /* Call the allocation method of the superclass.  */  ret = ((struct elf_i386_link_hash_entry *)	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,				     table, string));

⌨️ 快捷键说明

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