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

📄 elf64-mips.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
			     (const Elf64_Mips_External_Rela *) src,			     &mirela);  dst[0].r_offset = mirela.r_offset;  dst[0].r_info = ELF32_R_INFO (mirela.r_sym, mirela.r_type);  dst[0].r_addend = mirela.r_addend;  dst[1].r_offset = mirela.r_offset;  dst[1].r_info = ELF32_R_INFO (mirela.r_ssym, mirela.r_type2);  dst[1].r_addend = 0;  dst[2].r_offset = mirela.r_offset;  dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirela.r_type3);  dst[2].r_addend = 0;}/* Swap out a MIPS 64-bit Rel reloc.  */static voidmips_elf64_be_swap_reloc_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Rel *src;     bfd_byte *dst;{  Elf64_Mips_Internal_Rel mirel;  mirel.r_offset = src->r_offset;  mirel.r_type = ELF32_R_TYPE (src->r_info);  mirel.r_sym = ELF32_R_SYM (src->r_info);  mirel.r_type2 = R_MIPS_NONE;  mirel.r_ssym = STN_UNDEF;  mirel.r_type3 = R_MIPS_NONE;  mips_elf64_swap_reloc_out (abfd, &mirel,			     (Elf64_Mips_External_Rel *) dst);}/* Swap out a MIPS 64-bit Rela reloc.  */static voidmips_elf64_be_swap_reloca_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Rela *src;     bfd_byte *dst;{  Elf64_Mips_Internal_Rela mirela;  mirela.r_offset = src->r_offset;  mirela.r_type = ELF32_R_TYPE (src->r_info);  mirela.r_addend = src->r_addend;  mirela.r_sym = ELF32_R_SYM (src->r_info);  mirela.r_type2 = R_MIPS_NONE;  mirela.r_ssym = STN_UNDEF;  mirela.r_type3 = R_MIPS_NONE;  mips_elf64_swap_reloca_out (abfd, &mirela,			      (Elf64_Mips_External_Rela *) dst);}/* 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_CTOR, R_MIPS_64 },  { BFD_RELOC_32_PCREL, R_MIPS_REL32 },  { 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 *mips_elf64_reloc_type_lookup (abfd, code)     bfd *abfd ATTRIBUTE_UNUSED;     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)	{	  int v;	  v = (int) mips_reloc_map[i].elf_reloc_val;	  return &mips_elf64_howto_table_rel[v];	}    }  return NULL;}/* Since each entry in an SHT_REL or SHT_RELA section can represent up   to three relocs, we must tell the user to allocate more space.  */static longmips_elf64_get_reloc_upper_bound (abfd, sec)     bfd *abfd ATTRIBUTE_UNUSED;     asection *sec;{  return (sec->reloc_count * 3 + 1) * sizeof (arelent *);}/* Read the relocations from one reloc section.  */static booleanmips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)     bfd *abfd;     asection *asect;     asymbol **symbols;     const Elf_Internal_Shdr *rel_hdr;{  PTR allocated = NULL;  bfd_byte *native_relocs;  arelent *relents;  arelent *relent;  unsigned int count;  unsigned int i;  int entsize;  reloc_howto_type *howto_table;  allocated = (PTR) bfd_malloc (rel_hdr->sh_size);  if (allocated == NULL)    goto error_return;  if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0      || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))    goto error_return;  native_relocs = (bfd_byte *) allocated;  relents = asect->relocation + asect->reloc_count;  entsize = rel_hdr->sh_entsize;  BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)	      || entsize == sizeof (Elf64_Mips_External_Rela));  count = rel_hdr->sh_size / entsize;  if (entsize == sizeof (Elf64_Mips_External_Rel))    howto_table = mips_elf64_howto_table_rel;  else    howto_table = mips_elf64_howto_table_rela;  relent = relents;  for (i = 0; i < count; i++, native_relocs += entsize)    {      Elf64_Mips_Internal_Rela rela;      boolean used_sym, used_ssym;      int ir;      if (entsize == sizeof (Elf64_Mips_External_Rela))	mips_elf64_swap_reloca_in (abfd,				   (Elf64_Mips_External_Rela *) native_relocs,				   &rela);      else	{	  Elf64_Mips_Internal_Rel rel;	  mips_elf64_swap_reloc_in (abfd,				    (Elf64_Mips_External_Rel *) native_relocs,				    &rel);	  rela.r_offset = rel.r_offset;	  rela.r_sym = rel.r_sym;	  rela.r_ssym = rel.r_ssym;	  rela.r_type3 = rel.r_type3;	  rela.r_type2 = rel.r_type2;	  rela.r_type = rel.r_type;	  rela.r_addend = 0;	}      /* Each entry represents up to three actual relocations.  */      used_sym = false;      used_ssym = false;      for (ir = 0; ir < 3; ir++)	{	  enum elf_mips_reloc_type type;	  switch (ir)	    {	    default:	      abort ();	    case 0:	      type = (enum elf_mips_reloc_type) rela.r_type;	      break;	    case 1:	      type = (enum elf_mips_reloc_type) rela.r_type2;	      break;	    case 2:	      type = (enum elf_mips_reloc_type) rela.r_type3;	      break;	    }	  if (type == R_MIPS_NONE)	    {	      /* There are no more relocations in this entry.  If this                 is the first entry, we need to generate a dummy                 relocation so that the generic linker knows that                 there has been a break in the sequence of relocations                 applying to a particular address.  */	      if (ir == 0)		{		  relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;		  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)		    relent->address = rela.r_offset;		  else		    relent->address = rela.r_offset - asect->vma;		  relent->addend = 0;		  relent->howto = &howto_table[(int) R_MIPS_NONE];		  ++relent;		}	      break;	    }	  /* Some types require symbols, whereas some do not.  */	  switch (type)	    {	    case R_MIPS_NONE:	    case R_MIPS_LITERAL:	    case R_MIPS_INSERT_A:	    case R_MIPS_INSERT_B:	    case R_MIPS_DELETE:	      relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;	      break;	    default:	      if (! used_sym)		{		  if (rela.r_sym == 0)		    relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;		  else		    {		      asymbol **ps, *s;		      ps = symbols + rela.r_sym - 1;		      s = *ps;		      if ((s->flags & BSF_SECTION_SYM) == 0)			relent->sym_ptr_ptr = ps;		      else			relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;		    }		  used_sym = true;		}	      else if (! used_ssym)		{		  switch (rela.r_ssym)		    {		    case RSS_UNDEF:		      relent->sym_ptr_ptr =			bfd_abs_section_ptr->symbol_ptr_ptr;		      break;		    case RSS_GP:		    case RSS_GP0:		    case RSS_LOC:		      /* FIXME: I think these need to be handled using                         special howto structures.  */		      BFD_ASSERT (0);		      break;		    default:		      BFD_ASSERT (0);		      break;		    }		  used_ssym = true;		}	      else		relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;	      break;	    }	  /* The address of an ELF reloc is section relative for an	     object file, and absolute for an executable file or	     shared library.  The address of a BFD reloc is always	     section relative.  */	  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)	    relent->address = rela.r_offset;	  else	    relent->address = rela.r_offset - asect->vma;	  relent->addend = rela.r_addend;	  relent->howto = &howto_table[(int) type];	  ++relent;	}    }  asect->reloc_count += relent - relents;  if (allocated != NULL)    free (allocated);  return true; error_return:  if (allocated != NULL)    free (allocated);  return false;}/* Read the relocations.  On Irix 6, there can be two reloc sections   associated with a single data section.  */static booleanmips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)     bfd *abfd;     asection *asect;     asymbol **symbols;     boolean dynamic;{  struct bfd_elf_section_data * const d = elf_section_data (asect);  if (dynamic)    {      bfd_set_error (bfd_error_invalid_operation);      return false;    }  if (asect->relocation != NULL      || (asect->flags & SEC_RELOC) == 0      || asect->reloc_count == 0)    return true;  /* Allocate space for 3 arelent structures for each Rel structure.  */  asect->relocation = ((arelent *)		       bfd_alloc (abfd,				  asect->reloc_count * 3 * sizeof (arelent)));  if (asect->relocation == NULL)    return false;  /* The slurp_one_reloc_table routine increments reloc_count.  */  asect->reloc_count = 0;  if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))    return false;  if (d->rel_hdr2 != NULL)    {      if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,					      d->rel_hdr2))	return false;    }  return true;}/* Write out the relocations.  */static voidmips_elf64_write_relocs (abfd, sec, data)     bfd *abfd;     asection *sec;     PTR data;{  boolean *failedp = (boolean *) data;  unsigned int count;  Elf_Internal_Shdr *rela_hdr;  Elf64_Mips_External_Rela *ext_rela;  unsigned int idx;  asymbol *last_sym = 0;  int last_sym_idx = 0;  /* If we have already failed, don't do anything.  */  if (*failedp)    return;  if ((sec->flags & SEC_RELOC) == 0)    return;  /* The linker backend writes the relocs out itself, and sets the     reloc_count field to zero to inhibit writing them here.  Also,     sometimes the SEC_RELOC flag gets set even when there aren't any     relocs.  */  if (sec->reloc_count == 0)    return;  /* We can combine up to three relocs that refer to the same address     if the latter relocs have no associated symbol.  */  count = 0;  for (idx = 0; idx < sec->reloc_count; idx++)    {      bfd_vma addr;      unsigned int i;      ++count;      addr = sec->orelocation[idx]->address;      for (i = 0; i < 2; i++)	{	  arelent *r;	  if (idx + 1 >= sec->reloc_count)	    break;	  r = sec->orelocation[idx + 1];	  if (r->address != addr	      || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)	      || (*r->sym_ptr_ptr)->value != 0)	    break;	  /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */	  ++idx;	}    }

⌨️ 快捷键说明

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