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

📄 elf32-arm.h

📁 基于4个mips核的noc设计
💻 H
📖 第 1 页 / 共 5 页
字号:
/* 32-bit ELF support for ARM   Copyright 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 modify   it under the terms of the GNU General Public License as published by   the 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 of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */typedef unsigned long int insn32;typedef unsigned short int insn16;static boolean elf32_arm_set_private_flags  PARAMS ((bfd *, flagword));static boolean elf32_arm_copy_private_bfd_data  PARAMS ((bfd *, bfd *));static boolean elf32_arm_merge_private_bfd_data  PARAMS ((bfd *, bfd *));static boolean elf32_arm_print_private_bfd_data  PARAMS ((bfd *, PTR));static int elf32_arm_get_symbol_type  PARAMS (( Elf_Internal_Sym *, int));static struct bfd_link_hash_table *elf32_arm_link_hash_table_create  PARAMS ((bfd *));static bfd_reloc_status_type elf32_arm_final_link_relocate  PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,	   Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *,	   const char *, unsigned char, struct elf_link_hash_entry *));static insn32 insert_thumb_branch  PARAMS ((insn32, int));static struct elf_link_hash_entry *find_thumb_glue  PARAMS ((struct bfd_link_info *, CONST char *, bfd *));static struct elf_link_hash_entry *find_arm_glue  PARAMS ((struct bfd_link_info *, CONST char *, bfd *));static void record_arm_to_thumb_glue  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));static void record_thumb_to_arm_glue  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));static void elf32_arm_post_process_headers  PARAMS ((bfd *, struct bfd_link_info *));static int elf32_arm_to_thumb_stub  PARAMS ((struct bfd_link_info *, const char *, bfd *, bfd *, asection *,	   bfd_byte *, asection *, bfd_vma, bfd_signed_vma, bfd_vma));static int elf32_thumb_to_arm_stub  PARAMS ((struct bfd_link_info *, const char *, bfd *, bfd *, asection *,	   bfd_byte *, asection *, bfd_vma, bfd_signed_vma, bfd_vma));#define INTERWORK_FLAG(abfd)   (elf_elfheader (abfd)->e_flags & EF_INTERWORK)/* The linker script knows the section names for placement.   The entry_names are used to do simple name mangling on the stubs.   Given a function name, and its type, the stub can be found. The   name can be changed. The only requirement is the %s be present.  */#define THUMB2ARM_GLUE_SECTION_NAME ".glue_7t"#define THUMB2ARM_GLUE_ENTRY_NAME   "__%s_from_thumb"#define ARM2THUMB_GLUE_SECTION_NAME ".glue_7"#define ARM2THUMB_GLUE_ENTRY_NAME   "__%s_from_arm"/* The name of the dynamic interpreter.  This is put in the .interp   section.  */#define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"/* The size in bytes of an entry in the procedure linkage table.  */#define PLT_ENTRY_SIZE 16/* The first entry in a procedure linkage table looks like   this.  It is set up so that any shared library function that is   called before the relocation has been set up calls the dynamic   linker first.  */static const unsigned long elf32_arm_plt0_entry [PLT_ENTRY_SIZE / 4] ={  0xe52de004,	/* str   lr, [sp, #-4]!     */  0xe59fe010,	/* ldr   lr, [pc, #16]      */  0xe08fe00e,	/* add   lr, pc, lr         */  0xe5bef008	/* ldr   pc, [lr, #8]!      */};/* Subsequent entries in a procedure linkage table look like   this.  */static const unsigned long elf32_arm_plt_entry [PLT_ENTRY_SIZE / 4] ={  0xe59fc004,	/* ldr   ip, [pc, #4]       */  0xe08fc00c,	/* add   ip, pc, ip         */  0xe59cf000,	/* ldr   pc, [ip]           */  0x00000000	/* offset to symbol in got  */};/* The ARM 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 elf32_arm_pcrel_relocs_copied{  /* Next section.  */  struct elf32_arm_pcrel_relocs_copied * next;  /* A section in dynobj.  */  asection * section;  /* Number of relocs copied in this section.  */  bfd_size_type count;};/* Arm ELF linker hash entry.  */struct elf32_arm_link_hash_entry{  struct elf_link_hash_entry root;  /* Number of PC relative relocs copied for this symbol.  */  struct elf32_arm_pcrel_relocs_copied * pcrel_relocs_copied;};/* Declare this now that the above structures are defined.  */static boolean elf32_arm_discard_copies  PARAMS ((struct elf32_arm_link_hash_entry *, PTR));/* Traverse an arm ELF linker hash table.  */#define elf32_arm_link_hash_traverse(table, func, info)			\  (elf_link_hash_traverse						\   (&(table)->root,							\    (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func),	\    (info)))/* Get the ARM elf linker hash table from a link_info structure.  */#define elf32_arm_hash_table(info) \  ((struct elf32_arm_link_hash_table *) ((info)->hash))/* ARM ELF linker hash table.  */struct elf32_arm_link_hash_table{  /* The main hash table.  */  struct elf_link_hash_table root;  /* The size in bytes of the section containg the Thumb-to-ARM glue.  */  long int thumb_glue_size;  /* The size in bytes of the section containg the ARM-to-Thumb glue.  */  long int arm_glue_size;  /* An arbitary input BFD chosen to hold the glue sections.  */  bfd * bfd_of_glue_owner;  /* A boolean indicating whether knowledge of the ARM's pipeline     length should be applied by the linker.  */  int no_pipeline_knowledge;};/* Create an entry in an ARM ELF linker hash table.  */static struct bfd_hash_entry *elf32_arm_link_hash_newfunc (entry, table, string)     struct bfd_hash_entry * entry;     struct bfd_hash_table * table;     const char * string;{  struct elf32_arm_link_hash_entry * ret =    (struct elf32_arm_link_hash_entry *) entry;  /* Allocate the structure if it has not already been allocated by a     subclass.  */  if (ret == (struct elf32_arm_link_hash_entry *) NULL)    ret = ((struct elf32_arm_link_hash_entry *)	   bfd_hash_allocate (table,			      sizeof (struct elf32_arm_link_hash_entry)));  if (ret == (struct elf32_arm_link_hash_entry *) NULL)    return (struct bfd_hash_entry *) ret;  /* Call the allocation method of the superclass.  */  ret = ((struct elf32_arm_link_hash_entry *)	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,				     table, string));  if (ret != (struct elf32_arm_link_hash_entry *) NULL)    ret->pcrel_relocs_copied = NULL;  return (struct bfd_hash_entry *) ret;}/* Create an ARM elf linker hash table.  */static struct bfd_link_hash_table *elf32_arm_link_hash_table_create (abfd)     bfd *abfd;{  struct elf32_arm_link_hash_table *ret;  ret = ((struct elf32_arm_link_hash_table *)	 bfd_alloc (abfd, sizeof (struct elf32_arm_link_hash_table)));  if (ret == (struct elf32_arm_link_hash_table *) NULL)    return NULL;  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,				      elf32_arm_link_hash_newfunc))    {      bfd_release (abfd, ret);      return NULL;    }  ret->thumb_glue_size = 0;  ret->arm_glue_size = 0;  ret->bfd_of_glue_owner = NULL;  ret->no_pipeline_knowledge = 0;  return &ret->root.root;}/* Locate the Thumb encoded calling stub for NAME.  */static struct elf_link_hash_entry *find_thumb_glue (link_info, name, input_bfd)     struct bfd_link_info *link_info;     CONST char *name;     bfd *input_bfd;{  char *tmp_name;  struct elf_link_hash_entry *hash;  struct elf32_arm_link_hash_table *hash_table;  /* We need a pointer to the armelf specific hash table.  */  hash_table = elf32_arm_hash_table (link_info);  tmp_name = ((char *)       bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1));  BFD_ASSERT (tmp_name);  sprintf (tmp_name, THUMB2ARM_GLUE_ENTRY_NAME, name);  hash = elf_link_hash_lookup    (&(hash_table)->root, tmp_name, false, false, true);  if (hash == NULL)    /* xgettext:c-format */    _bfd_error_handler (_("%s: unable to find THUMB glue '%s' for `%s'"),			bfd_get_filename (input_bfd), tmp_name, name);  free (tmp_name);  return hash;}/* Locate the ARM encoded calling stub for NAME.  */static struct elf_link_hash_entry *find_arm_glue (link_info, name, input_bfd)     struct bfd_link_info *link_info;     CONST char *name;     bfd *input_bfd;{  char *tmp_name;  struct elf_link_hash_entry *myh;  struct elf32_arm_link_hash_table *hash_table;  /* We need a pointer to the elfarm specific hash table.  */  hash_table = elf32_arm_hash_table (link_info);  tmp_name = ((char *)       bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));  BFD_ASSERT (tmp_name);  sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);  myh = elf_link_hash_lookup    (&(hash_table)->root, tmp_name, false, false, true);  if (myh == NULL)    /* xgettext:c-format */    _bfd_error_handler (_("%s: unable to find ARM glue '%s' for `%s'"),			bfd_get_filename (input_bfd), tmp_name, name);  free (tmp_name);  return myh;}/* ARM->Thumb glue:   .arm   __func_from_arm:   ldr r12, __func_addr   bx  r12   __func_addr:   .word func    @ behave as if you saw a ARM_32 reloc.  */#define ARM2THUMB_GLUE_SIZE 12static const insn32 a2t1_ldr_insn = 0xe59fc000;static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;static const insn32 a2t3_func_addr_insn = 0x00000001;/* Thumb->ARM:                          Thumb->(non-interworking aware) ARM   .thumb                               .thumb   .align 2                             .align 2   __func_from_thumb:              __func_from_thumb:   bx pc                                push {r6, lr}   nop                                  ldr  r6, __func_addr   .arm                                         mov  lr, pc   __func_change_to_arm:                        bx   r6   b func                       .arm   __func_back_to_thumb:   ldmia r13! {r6, lr}   bx    lr   __func_addr:   .word        func  */#define THUMB2ARM_GLUE_SIZE 8static const insn16 t2a1_bx_pc_insn = 0x4778;static const insn16 t2a2_noop_insn = 0x46c0;static const insn32 t2a3_b_insn = 0xea000000;static const insn16 t2a1_push_insn = 0xb540;static const insn16 t2a2_ldr_insn = 0x4e03;static const insn16 t2a3_mov_insn = 0x46fe;static const insn16 t2a4_bx_insn = 0x4730;static const insn32 t2a5_pop_insn = 0xe8bd4040;static const insn32 t2a6_bx_insn = 0xe12fff1e;booleanbfd_elf32_arm_allocate_interworking_sections (info)     struct bfd_link_info * info;{  asection * s;  bfd_byte * foo;  struct elf32_arm_link_hash_table * globals;  globals = elf32_arm_hash_table (info);  BFD_ASSERT (globals != NULL);  if (globals->arm_glue_size != 0)    {      BFD_ASSERT (globals->bfd_of_glue_owner != NULL);      s = bfd_get_section_by_name	(globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);      BFD_ASSERT (s != NULL);      foo = (bfd_byte *) bfd_alloc	(globals->bfd_of_glue_owner, globals->arm_glue_size);      s->_raw_size = s->_cooked_size = globals->arm_glue_size;      s->contents = foo;    }  if (globals->thumb_glue_size != 0)    {      BFD_ASSERT (globals->bfd_of_glue_owner != NULL);      s = bfd_get_section_by_name	(globals->bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);      BFD_ASSERT (s != NULL);      foo = (bfd_byte *) bfd_alloc	(globals->bfd_of_glue_owner, globals->thumb_glue_size);      s->_raw_size = s->_cooked_size = globals->thumb_glue_size;      s->contents = foo;    }  return true;}static voidrecord_arm_to_thumb_glue (link_info, h)     struct bfd_link_info * link_info;     struct elf_link_hash_entry * h;{  const char * name = h->root.root.string;  register asection * s;  char * tmp_name;  struct elf_link_hash_entry * myh;  struct elf32_arm_link_hash_table * globals;  globals = elf32_arm_hash_table (link_info);  BFD_ASSERT (globals != NULL);  BFD_ASSERT (globals->bfd_of_glue_owner != NULL);  s = bfd_get_section_by_name    (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);  BFD_ASSERT (s != NULL);  tmp_name = ((char *)       bfd_malloc (strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1));  BFD_ASSERT (tmp_name);  sprintf (tmp_name, ARM2THUMB_GLUE_ENTRY_NAME, name);  myh = elf_link_hash_lookup    (&(globals)->root, tmp_name, false, false, true);  if (myh != NULL)    {      /* We've already seen this guy.  */      free (tmp_name);      return;    }  /* The only trick here is using hash_table->arm_glue_size as the value. Even     though the section isn't allocated yet, this is where we will be putting     it.  */  _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner, tmp_name,				    BSF_GLOBAL,				    s, globals->arm_glue_size + 1,				    NULL, true, false,				    (struct bfd_link_hash_entry **) &myh);  free (tmp_name);  globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;  return;}static voidrecord_thumb_to_arm_glue (link_info, h)     struct bfd_link_info *link_info;     struct elf_link_hash_entry *h;{  const char *name = h->root.root.string;  register asection *s;  char *tmp_name;  struct elf_link_hash_entry *myh;

⌨️ 快捷键说明

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