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

📄 elf32-mips.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* MIPS-specific support for 32-bit ELF   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.   Most of the information added by Ian Lance Taylor, Cygnus Support,   <ian@cygnus.com>.   N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.   <mark@codesourcery.com>   Traditional MIPS targets support added by Koundinya.K, Dansk Data   Elektronik & Operations Research Group. <kk@ddeorg.soft.net>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 handles MIPS ELF targets.  SGI Irix 5 uses a slightly   different MIPS ELF from other targets.  This matters when linking.   This file supports both, switching at runtime.  */#include "bfd.h"#include "sysdep.h"#include "libbfd.h"#include "bfdlink.h"#include "genlink.h"#include "elf-bfd.h"#include "elf/mips.h"/* Get the ECOFF swapping routines.  */#include "coff/sym.h"#include "coff/symconst.h"#include "coff/internal.h"#include "coff/ecoff.h"#include "coff/mips.h"#define ECOFF_SIGNED_32#include "ecoffswap.h"/* This structure is used to hold .got information when linking.  It   is stored in the tdata field of the bfd_elf_section_data structure.  */struct mips_got_info{  /* The global symbol in the GOT with the lowest index in the dynamic     symbol table.  */  struct elf_link_hash_entry *global_gotsym;  /* The number of global .got entries.  */  unsigned int global_gotno;  /* The number of local .got entries.  */  unsigned int local_gotno;  /* The number of local .got entries we have used.  */  unsigned int assigned_gotno;};/* The MIPS ELF linker needs additional information for each symbol in   the global hash table.  */struct mips_elf_link_hash_entry{  struct elf_link_hash_entry root;  /* External symbol information.  */  EXTR esym;  /* Number of R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 relocs against     this symbol.  */  unsigned int possibly_dynamic_relocs;  /* The index of the first dynamic relocation (in the .rel.dyn     section) against this symbol.  */  unsigned int min_dyn_reloc_index;  /* We must not create a stub for a symbol that has relocations     related to taking the function's address, i.e. any but     R_MIPS_CALL*16 ones -- see "MIPS ABI Supplement, 3rd Edition",     p. 4-20.  */  boolean no_fn_stub;  /* If there is a stub that 32 bit functions should use to call this     16 bit function, this points to the section containing the stub.  */  asection *fn_stub;  /* Whether we need the fn_stub; this is set if this symbol appears     in any relocs other than a 16 bit call.  */  boolean need_fn_stub;  /* If there is a stub that 16 bit functions should use to call this     32 bit function, this points to the section containing the stub.  */  asection *call_stub;  /* This is like the call_stub field, but it is used if the function     being called returns a floating point value.  */  asection *call_fp_stub;};static bfd_reloc_status_type mips32_64bit_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup  PARAMS ((bfd *, bfd_reloc_code_real_type));static reloc_howto_type *mips_rtype_to_howto  PARAMS ((unsigned int));static void mips_info_to_howto_rel  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));static void mips_info_to_howto_rela  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));static void bfd_mips_elf32_swap_gptab_in  PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *));static void bfd_mips_elf32_swap_gptab_out  PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *));#if 0static void bfd_mips_elf_swap_msym_in  PARAMS ((bfd *, const Elf32_External_Msym *, Elf32_Internal_Msym *));#endifstatic void bfd_mips_elf_swap_msym_out  PARAMS ((bfd *, const Elf32_Internal_Msym *, Elf32_External_Msym *));static boolean mips_elf_sym_is_global PARAMS ((bfd *, asymbol *));static boolean mips_elf_create_procedure_table  PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *,	   struct ecoff_debug_info *));static INLINE int elf_mips_isa PARAMS ((flagword));static INLINE int elf_mips_mach PARAMS ((flagword));static INLINE char* elf_mips_abi_name PARAMS ((bfd *));static boolean mips_elf_is_local_label_name  PARAMS ((bfd *, const char *));static struct bfd_hash_entry *mips_elf_link_hash_newfunc  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));static int gptab_compare PARAMS ((const void *, const void *));static bfd_reloc_status_type mips16_jump_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static bfd_reloc_status_type mips16_gprel_reloc  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static boolean mips_elf_create_compact_rel_section  PARAMS ((bfd *, struct bfd_link_info *));static boolean mips_elf_create_got_section  PARAMS ((bfd *, struct bfd_link_info *));static bfd_reloc_status_type mips_elf_final_gp  PARAMS ((bfd *, asymbol *, boolean, char **, bfd_vma *));static bfd_byte *elf32_mips_get_relocated_section_contents  PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,	   bfd_byte *, boolean, asymbol **));static asection *mips_elf_create_msym_section  PARAMS ((bfd *));static void mips_elf_irix6_finish_dynamic_symbol  PARAMS ((bfd *, const char *, Elf_Internal_Sym *));static bfd_vma mips_elf_sign_extend PARAMS ((bfd_vma, int));static boolean mips_elf_overflow_p PARAMS ((bfd_vma, int));static bfd_vma mips_elf_high PARAMS ((bfd_vma));static bfd_vma mips_elf_higher PARAMS ((bfd_vma));static bfd_vma mips_elf_highest PARAMS ((bfd_vma));static bfd_vma mips_elf_global_got_index  PARAMS ((bfd *, struct elf_link_hash_entry *));static bfd_vma mips_elf_local_got_index  PARAMS ((bfd *, struct bfd_link_info *, bfd_vma));static bfd_vma mips_elf_got_offset_from_index  PARAMS ((bfd *, bfd *, bfd_vma));static boolean mips_elf_record_global_got_symbol  PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *,	   struct mips_got_info *));static bfd_vma mips_elf_got_page  PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *));static const Elf_Internal_Rela *mips_elf_next_relocation  PARAMS ((unsigned int, const Elf_Internal_Rela *,	   const Elf_Internal_Rela *));static bfd_reloc_status_type mips_elf_calculate_relocation  PARAMS ((bfd *, bfd *, asection *, struct bfd_link_info *,	   const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *,	   Elf_Internal_Sym *, asection **, bfd_vma *, const char **,	   boolean *));static bfd_vma mips_elf_obtain_contents  PARAMS ((reloc_howto_type *, const Elf_Internal_Rela *, bfd *, bfd_byte *));static boolean mips_elf_perform_relocation  PARAMS ((struct bfd_link_info *, reloc_howto_type *,	   const Elf_Internal_Rela *, bfd_vma,	   bfd *, asection *, bfd_byte *, boolean));static boolean mips_elf_assign_gp PARAMS ((bfd *, bfd_vma *));static boolean mips_elf_sort_hash_table_f  PARAMS ((struct mips_elf_link_hash_entry *, PTR));static boolean mips_elf_sort_hash_table  PARAMS ((struct bfd_link_info *, unsigned long));static asection * mips_elf_got_section PARAMS ((bfd *));static struct mips_got_info *mips_elf_got_info  PARAMS ((bfd *, asection **));static boolean mips_elf_local_relocation_p  PARAMS ((bfd *, const Elf_Internal_Rela *, asection **, boolean));static bfd_vma mips_elf_create_local_got_entry  PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));static bfd_vma mips_elf_got16_entry  PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, boolean));static boolean mips_elf_create_dynamic_relocation  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,	   struct mips_elf_link_hash_entry *, asection *,	   bfd_vma, bfd_vma *, asection *));static void mips_elf_allocate_dynamic_relocations  PARAMS ((bfd *, unsigned int));static boolean mips_elf_stub_section_p  PARAMS ((bfd *, asection *));static int sort_dynamic_relocs  PARAMS ((const void *, const void *));extern const bfd_target bfd_elf32_tradbigmips_vec;extern const bfd_target bfd_elf32_tradlittlemips_vec;#ifdef BFD64extern const bfd_target bfd_elf64_tradbigmips_vec;extern const bfd_target bfd_elf64_tradlittlemips_vec;#endif/* The level of IRIX compatibility we're striving for.  */typedef enum {  ict_none,  ict_irix5,  ict_irix6} irix_compat_t;/* This will be used when we sort the dynamic relocation records.  */static bfd *reldyn_sorting_bfd;/* Nonzero if ABFD is using the N32 ABI.  */#define ABI_N32_P(abfd) \  ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)/* Nonzero if ABFD is using the 64-bit ABI. */#define ABI_64_P(abfd) \  ((elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64) != 0)/* Depending on the target vector we generate some version of Irix   executables or "normal" MIPS ELF ABI executables.  */#ifdef BFD64#define IRIX_COMPAT(abfd) \  (((abfd->xvec == &bfd_elf64_tradbigmips_vec) || \    (abfd->xvec == &bfd_elf64_tradlittlemips_vec) || \    (abfd->xvec == &bfd_elf32_tradbigmips_vec) || \    (abfd->xvec == &bfd_elf32_tradlittlemips_vec)) ? ict_none : \  ((ABI_N32_P (abfd) || ABI_64_P (abfd)) ? ict_irix6 : ict_irix5))#else#define IRIX_COMPAT(abfd) \  (((abfd->xvec == &bfd_elf32_tradbigmips_vec) || \    (abfd->xvec == &bfd_elf32_tradlittlemips_vec)) ? ict_none : \  ((ABI_N32_P (abfd) || ABI_64_P (abfd)) ? ict_irix6 : ict_irix5))#endif/* Whether we are trying to be compatible with IRIX at all.  */#define SGI_COMPAT(abfd) \  (IRIX_COMPAT (abfd) != ict_none)/* The name of the msym section.  */#define MIPS_ELF_MSYM_SECTION_NAME(abfd) ".msym"/* The name of the srdata section.  */#define MIPS_ELF_SRDATA_SECTION_NAME(abfd) ".srdata"/* The name of the options section.  */#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.options" : ".options")/* The name of the stub section.  */#define MIPS_ELF_STUB_SECTION_NAME(abfd) \  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.stubs" : ".stub")/* The name of the dynamic relocation section.  */#define MIPS_ELF_REL_DYN_SECTION_NAME(abfd) ".rel.dyn"/* The size of an external REL relocation.  */#define MIPS_ELF_REL_SIZE(abfd) \  (get_elf_backend_data (abfd)->s->sizeof_rel)/* The size of an external dynamic table entry.  */#define MIPS_ELF_DYN_SIZE(abfd) \  (get_elf_backend_data (abfd)->s->sizeof_dyn)/* The size of a GOT entry.  */#define MIPS_ELF_GOT_SIZE(abfd) \  (get_elf_backend_data (abfd)->s->arch_size / 8)/* The size of a symbol-table entry.  */#define MIPS_ELF_SYM_SIZE(abfd) \  (get_elf_backend_data (abfd)->s->sizeof_sym)/* The default alignment for sections, as a power of two.  */#define MIPS_ELF_LOG_FILE_ALIGN(abfd)				\  (get_elf_backend_data (abfd)->s->file_align == 8 ? 3 : 2)/* Get word-sized data.  */#define MIPS_ELF_GET_WORD(abfd, ptr) \  (ABI_64_P (abfd) ? bfd_get_64 (abfd, ptr) : bfd_get_32 (abfd, ptr))/* Put out word-sized data.  */#define MIPS_ELF_PUT_WORD(abfd, val, ptr)	\  (ABI_64_P (abfd) 				\   ? bfd_put_64 (abfd, val, ptr) 		\   : bfd_put_32 (abfd, val, ptr))/* Add a dynamic symbol table-entry.  */#ifdef BFD64#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \  (ABI_64_P (elf_hash_table (info)->dynobj)	   \   ? bfd_elf64_add_dynamic_entry (info, tag, val)  \   : bfd_elf32_add_dynamic_entry (info, tag, val))#else#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \  (ABI_64_P (elf_hash_table (info)->dynobj)	   \   ? (abort (), false)                             \   : bfd_elf32_add_dynamic_entry (info, tag, val))#endif/* The number of local .got entries we reserve.  */#define MIPS_RESERVED_GOTNO (2)/* Instructions which appear in a stub.  For some reason the stub is   slightly different on an SGI system.  */#define ELF_MIPS_GP_OFFSET(abfd) (SGI_COMPAT (abfd) ? 0x7ff0 : 0x8000)#define STUB_LW(abfd)						\  (SGI_COMPAT (abfd)						\   ? (ABI_64_P (abfd)  						\      ? 0xdf998010		/* ld t9,0x8010(gp) */		\      : 0x8f998010)             /* lw t9,0x8010(gp) */		\   : 0x8f998010)		/* lw t9,0x8000(gp) */#define STUB_MOVE(abfd)                                         \  (SGI_COMPAT (abfd) ? 0x03e07825 : 0x03e07821)         /* move t7,ra */#define STUB_JALR 0x0320f809				/* jal t9 */#define STUB_LI16(abfd)                                         \  (SGI_COMPAT (abfd) ? 0x34180000 : 0x24180000)         /* ori t8,zero,0 */#define MIPS_FUNCTION_STUB_SIZE (16)#if 0/* We no longer try to identify particular sections for the .dynsym   section.  When we do, we wind up crashing if there are other random   sections with relocations.  *//* Names of sections which appear in the .dynsym section in an Irix 5   executable.  */static const char * const mips_elf_dynsym_sec_names[] ={  ".text",  ".init",  ".fini",  ".data",  ".rodata",  ".sdata",  ".sbss",  ".bss",  NULL};#define SIZEOF_MIPS_DYNSYM_SECNAMES \  (sizeof mips_elf_dynsym_sec_names / sizeof mips_elf_dynsym_sec_names[0])/* The number of entries in mips_elf_dynsym_sec_names which go in the   text segment.  */#define MIPS_TEXT_DYNSYM_SECNO (3)#endif /* 0 *//* The names of the runtime procedure table symbols used on Irix 5.  */static const char * const mips_elf_dynsym_rtproc_names[] ={  "_procedure_table",  "_procedure_string_table",  "_procedure_table_size",  NULL};/* These structures are used to generate the .compact_rel section on   Irix 5.  */typedef struct{  unsigned long id1;		/* Always one?  */  unsigned long num;		/* Number of compact relocation entries.  */  unsigned long id2;		/* Always two?  */  unsigned long offset;		/* The file offset of the first relocation.  */  unsigned long reserved0;	/* Zero?  */  unsigned long reserved1;	/* Zero?  */} Elf32_compact_rel;typedef struct{  bfd_byte id1[4];  bfd_byte num[4];  bfd_byte id2[4];  bfd_byte offset[4];  bfd_byte reserved0[4];  bfd_byte reserved1[4];} Elf32_External_compact_rel;typedef struct{  unsigned int ctype : 1;	/* 1: long 0: short format. See below.  */  unsigned int rtype : 4;	/* Relocation types. See below.  */  unsigned int dist2to : 8;  unsigned int relvaddr : 19;	/* (VADDR - vaddr of the previous entry)/ 4 */  unsigned long konst;		/* KONST field. See below.  */  unsigned long vaddr;		/* VADDR to be relocated.  */} Elf32_crinfo;typedef struct{  unsigned int ctype : 1;	/* 1: long 0: short format. See below.  */  unsigned int rtype : 4;	/* Relocation types. See below.  */  unsigned int dist2to : 8;  unsigned int relvaddr : 19;	/* (VADDR - vaddr of the previous entry)/ 4 */  unsigned long konst;		/* KONST field. See below.  */} Elf32_crinfo2;typedef struct{  bfd_byte info[4];  bfd_byte konst[4];  bfd_byte vaddr[4];} Elf32_External_crinfo;typedef struct{  bfd_byte info[4];  bfd_byte konst[4];} Elf32_External_crinfo2;

⌨️ 快捷键说明

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