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

📄 elf32-mips.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
     bfd *abfd ATTRIBUTE_UNUSED;     arelent *reloc_entry;     asymbol *symbol;     PTR data ATTRIBUTE_UNUSED;     asection *input_section;     bfd *output_bfd;     char **error_message ATTRIBUTE_UNUSED;{  if (output_bfd != (bfd *) NULL      && (symbol->flags & BSF_SECTION_SYM) == 0      && reloc_entry->addend == 0)    {      reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  /* FIXME.  */  {    static boolean warned;    if (! warned)      (*_bfd_error_handler)	(_("Linking mips16 objects into %s format is not supported"),	 bfd_get_target (input_section->output_section->owner));    warned = true;  }  return bfd_reloc_undefined;}/* Handle a mips16 GP relative reloc.  */static bfd_reloc_status_typemips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,		    output_bfd, error_message)     bfd *abfd;     arelent *reloc_entry;     asymbol *symbol;     PTR data;     asection *input_section;     bfd *output_bfd;     char **error_message;{  boolean relocateable;  bfd_reloc_status_type ret;  bfd_vma gp;  unsigned short extend, insn;  unsigned long final;  /* If we're relocating, and this is an external symbol with no     addend, we don't want to change anything.  We will only have an     addend if this is a newly created reloc, not read from an ELF     file.  */  if (output_bfd != NULL      && (symbol->flags & BSF_SECTION_SYM) == 0      && reloc_entry->addend == 0)    {      reloc_entry->address += input_section->output_offset;      return bfd_reloc_ok;    }  if (output_bfd != NULL)    relocateable = true;  else    {      relocateable = false;      output_bfd = symbol->section->output_section->owner;    }  ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message,			   &gp);  if (ret != bfd_reloc_ok)    return ret;  if (reloc_entry->address > input_section->_cooked_size)    return bfd_reloc_outofrange;  /* Pick up the mips16 extend instruction and the real instruction.  */  extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);  insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);  /* Stuff the current addend back as a 32 bit value, do the usual     relocation, and then clean up.  */  bfd_put_32 (abfd,	      (((extend & 0x1f) << 11)	       | (extend & 0x7e0)	       | (insn & 0x1f)),	      (bfd_byte *) data + reloc_entry->address);  ret = gprel16_with_gp (abfd, symbol, reloc_entry, input_section,			 relocateable, data, gp);  final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);  bfd_put_16 (abfd,	      ((extend & 0xf800)	       | ((final >> 11) & 0x1f)	       | (final & 0x7e0)),	      (bfd_byte *) data + reloc_entry->address);  bfd_put_16 (abfd,	      ((insn & 0xffe0)	       | (final & 0x1f)),	      (bfd_byte *) data + reloc_entry->address + 2);  return ret;}/* Return the ISA for a MIPS e_flags value.  */static INLINE intelf_mips_isa (flags)     flagword flags;{  switch (flags & EF_MIPS_ARCH)    {    case E_MIPS_ARCH_1:      return 1;    case E_MIPS_ARCH_2:      return 2;    case E_MIPS_ARCH_3:      return 3;    case E_MIPS_ARCH_4:      return 4;    case E_MIPS_ARCH_5:      return 5;    case E_MIPS_ARCH_32:      return 32;    case E_MIPS_ARCH_64:      return 64;    }  return 4;}/* Return the MACH for a MIPS e_flags value.  */static INLINE intelf_mips_mach (flags)     flagword flags;{  switch (flags & EF_MIPS_MACH)    {    case E_MIPS_MACH_3900:      return bfd_mach_mips3900;    case E_MIPS_MACH_4010:      return bfd_mach_mips4010;    case E_MIPS_MACH_4100:      return bfd_mach_mips4100;    case E_MIPS_MACH_4111:      return bfd_mach_mips4111;    case E_MIPS_MACH_4650:      return bfd_mach_mips4650;    case E_MIPS_MACH_MIPS32_4K:      return bfd_mach_mips32_4k;    case E_MIPS_MACH_SB1:      return bfd_mach_mips_sb1;    default:      switch (flags & EF_MIPS_ARCH)	{	default:	case E_MIPS_ARCH_1:	  return bfd_mach_mips3000;	  break;	case E_MIPS_ARCH_2:	  return bfd_mach_mips6000;	  break;	case E_MIPS_ARCH_3:	  return bfd_mach_mips4000;	  break;	case E_MIPS_ARCH_4:	  return bfd_mach_mips8000;	  break;	case E_MIPS_ARCH_5:	  return bfd_mach_mips5;	  break;	case E_MIPS_ARCH_32:	  return bfd_mach_mips32;	  break;	case E_MIPS_ARCH_64:	  return bfd_mach_mips64;	  break;	}    }  return 0;}/* Return printable name for ABI.  */static INLINE char *elf_mips_abi_name (abfd)     bfd *abfd;{  flagword flags;  if (ABI_N32_P (abfd))    return "N32";  else if (ABI_64_P (abfd))    return "64";  flags = elf_elfheader (abfd)->e_flags;  switch (flags & EF_MIPS_ABI)    {    case 0:      return "none";    case E_MIPS_ABI_O32:      return "O32";    case E_MIPS_ABI_O64:      return "O64";    case E_MIPS_ABI_EABI32:      return "EABI32";    case E_MIPS_ABI_EABI64:      return "EABI64";    default:      return "unknown abi";    }}/* A mapping from BFD reloc types to MIPS ELF reloc types.  */struct elf_reloc_map {  bfd_reloc_code_real_type bfd_reloc_val;  enum elf_mips_reloc_type elf_reloc_val;};static CONST struct elf_reloc_map mips_reloc_map[] ={  { BFD_RELOC_NONE, R_MIPS_NONE, },  { BFD_RELOC_16, R_MIPS_16 },  { BFD_RELOC_32, R_MIPS_32 },  { BFD_RELOC_64, R_MIPS_64 },  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },  { BFD_RELOC_HI16_S, R_MIPS_HI16 },  { BFD_RELOC_LO16, R_MIPS_LO16 },  { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },  { BFD_RELOC_16_PCREL, R_MIPS_PC16 },  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },  { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }};/* Given a BFD reloc type, return a howto structure.  */static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup (abfd, code)     bfd *abfd;     bfd_reloc_code_real_type code;{  unsigned int i;  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)    {      if (mips_reloc_map[i].bfd_reloc_val == code)	return &elf_mips_howto_table[(int) mips_reloc_map[i].elf_reloc_val];    }  switch (code)    {    default:      bfd_set_error (bfd_error_bad_value);      return NULL;    case BFD_RELOC_CTOR:      /* We need to handle BFD_RELOC_CTOR specially.	 Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the	 size of addresses on this architecture.  */      if (bfd_arch_bits_per_address (abfd) == 32)	return &elf_mips_howto_table[(int) R_MIPS_32];      else	return &elf_mips_ctor64_howto;    case BFD_RELOC_MIPS16_JMP:      return &elf_mips16_jump_howto;    case BFD_RELOC_MIPS16_GPREL:      return &elf_mips16_gprel_howto;    case BFD_RELOC_VTABLE_INHERIT:      return &elf_mips_gnu_vtinherit_howto;    case BFD_RELOC_VTABLE_ENTRY:      return &elf_mips_gnu_vtentry_howto;    case BFD_RELOC_PCREL_HI16_S:      return &elf_mips_gnu_rel_hi16;    case BFD_RELOC_PCREL_LO16:      return &elf_mips_gnu_rel_lo16;    case BFD_RELOC_16_PCREL_S2:      return &elf_mips_gnu_rel16_s2;    case BFD_RELOC_64_PCREL:      return &elf_mips_gnu_pcrel64;    case BFD_RELOC_32_PCREL:      return &elf_mips_gnu_pcrel32;    }}/* Given a MIPS Elf32_Internal_Rel, fill in an arelent structure.  */static reloc_howto_type *mips_rtype_to_howto (r_type)     unsigned int r_type;{  switch (r_type)    {    case R_MIPS16_26:      return &elf_mips16_jump_howto;      break;    case R_MIPS16_GPREL:      return &elf_mips16_gprel_howto;      break;    case R_MIPS_GNU_VTINHERIT:      return &elf_mips_gnu_vtinherit_howto;      break;    case R_MIPS_GNU_VTENTRY:      return &elf_mips_gnu_vtentry_howto;      break;    case R_MIPS_GNU_REL_HI16:      return &elf_mips_gnu_rel_hi16;      break;    case R_MIPS_GNU_REL_LO16:      return &elf_mips_gnu_rel_lo16;      break;    case R_MIPS_GNU_REL16_S2:      return &elf_mips_gnu_rel16_s2;      break;    case R_MIPS_PC64:      return &elf_mips_gnu_pcrel64;      break;    case R_MIPS_PC32:      return &elf_mips_gnu_pcrel32;      break;    default:      BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);      return &elf_mips_howto_table[r_type];      break;    }}/* Given a MIPS Elf32_Internal_Rel, fill in an arelent structure.  */static voidmips_info_to_howto_rel (abfd, cache_ptr, dst)     bfd *abfd;     arelent *cache_ptr;     Elf32_Internal_Rel *dst;{  unsigned int r_type;  r_type = ELF32_R_TYPE (dst->r_info);  cache_ptr->howto = mips_rtype_to_howto (r_type);  /* The addend for a GPREL16 or LITERAL relocation comes from the GP     value for the object file.  We get the addend now, rather than     when we do the relocation, because the symbol manipulations done     by the linker may cause us to lose track of the input BFD.  */  if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0      && (r_type == (unsigned int) R_MIPS_GPREL16	  || r_type == (unsigned int) R_MIPS_LITERAL))    cache_ptr->addend = elf_gp (abfd);}/* Given a MIPS Elf32_Internal_Rela, fill in an arelent structure.  */static voidmips_info_to_howto_rela (abfd, cache_ptr, dst)     bfd *abfd;     arelent *cache_ptr;     Elf32_Internal_Rela *dst;{  /* Since an Elf32_Internal_Rel is an initial prefix of an     Elf32_Internal_Rela, we can just use mips_info_to_howto_rel     above.  */  mips_info_to_howto_rel (abfd, cache_ptr, (Elf32_Internal_Rel *) dst);  /* If we ever need to do any extra processing with dst->r_addend     (the field omitted in an Elf32_Internal_Rel) we can do it here.  */}/* A .reginfo section holds a single Elf32_RegInfo structure.  These   routines swap this structure in and out.  They are used outside of   BFD, so they are globally visible.  */voidbfd_mips_elf32_swap_reginfo_in (abfd, ex, in)     bfd *abfd;     const Elf32_External_RegInfo *ex;     Elf32_RegInfo *in;{  in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);  in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);  in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);  in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);  in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);  in->ri_gp_value = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gp_value);}voidbfd_mips_elf32_swap_reginfo_out (abfd, in, ex)     bfd *abfd;     const Elf32_RegInfo *in;     Elf32_External_RegInfo *ex;{  bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,		(bfd_byte *) ex->ri_gprmask);  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],		(bfd_byte *) ex->ri_cprmask[0]);  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],		(bfd_byte *) ex->ri_cprmask[1]);  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],		(bfd_byte *) ex->ri_cprmask[2]);  bfd_h_put_3

⌨️ 快捷键说明

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