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

📄 elf32-arm.h

📁 基于4个mips核的noc设计
💻 H
📖 第 1 页 / 共 5 页
字号:
  /* Now go back and fix up the original BL insn to point     to here.  */  ret_offset =    s->output_offset    + my_offset    - (input_section->output_offset       + offset + addend)    - 8;  tmp = bfd_get_32 (input_bfd, hit_data		    - input_section->vma);  bfd_put_32 (output_bfd,	      insert_thumb_branch (tmp, ret_offset),	      hit_data - input_section->vma);  return true;}/* Arm code calling a Thumb function.  */static intelf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,			 hit_data, sym_sec, offset, addend, val)     struct bfd_link_info * info;     const char *           name;     bfd *                  input_bfd;     bfd *                  output_bfd;     asection *             input_section;     bfd_byte *             hit_data;     asection *             sym_sec;     bfd_vma                offset;     bfd_signed_vma         addend;     bfd_vma                val;{  unsigned long int tmp;  long int my_offset;  asection * s;  long int ret_offset;  struct elf_link_hash_entry * myh;  struct elf32_arm_link_hash_table * globals;  myh = find_arm_glue (info, name, input_bfd);  if (myh == NULL)    return false;  globals = elf32_arm_hash_table (info);  BFD_ASSERT (globals != NULL);  BFD_ASSERT (globals->bfd_of_glue_owner != NULL);  my_offset = myh->root.u.def.value;  s = bfd_get_section_by_name (globals->bfd_of_glue_owner,			       ARM2THUMB_GLUE_SECTION_NAME);  BFD_ASSERT (s != NULL);  BFD_ASSERT (s->contents != NULL);  BFD_ASSERT (s->output_section != NULL);  if ((my_offset & 0x01) == 0x01)    {      if (sym_sec != NULL	  && sym_sec->owner != NULL	  && !INTERWORK_FLAG (sym_sec->owner))	{	  _bfd_error_handler	    (_("%s(%s): warning: interworking not enabled."),	     bfd_get_filename (sym_sec->owner), name);	  _bfd_error_handler	    (_("  first occurrence: %s: arm call to thumb"),	     bfd_get_filename (input_bfd));	}      --my_offset;      myh->root.u.def.value = my_offset;      bfd_put_32 (output_bfd, a2t1_ldr_insn,		  s->contents + my_offset);      bfd_put_32 (output_bfd, a2t2_bx_r12_insn,		  s->contents + my_offset + 4);      /* It's a thumb address.  Add the low order bit.  */      bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,		  s->contents + my_offset + 8);    }  BFD_ASSERT (my_offset <= globals->arm_glue_size);  tmp = bfd_get_32 (input_bfd, hit_data);  tmp = tmp & 0xFF000000;  /* Somehow these are both 4 too far, so subtract 8.  */  ret_offset = s->output_offset    + my_offset    + s->output_section->vma    - (input_section->output_offset       + input_section->output_section->vma       + offset + addend)    - 8;  tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);  bfd_put_32 (output_bfd, tmp, hit_data	      - input_section->vma);  return true;}/* Perform a relocation as part of a final link.  */static bfd_reloc_status_typeelf32_arm_final_link_relocate (howto, input_bfd, output_bfd,			       input_section, contents, rel, value,			       info, sym_sec, sym_name, sym_flags, h)     reloc_howto_type *     howto;     bfd *                  input_bfd;     bfd *                  output_bfd;     asection *             input_section;     bfd_byte *             contents;     Elf_Internal_Rela *    rel;     bfd_vma                value;     struct bfd_link_info * info;     asection *             sym_sec;     const char *           sym_name;     unsigned char          sym_flags;     struct elf_link_hash_entry * h;{  unsigned long                 r_type = howto->type;  unsigned long                 r_symndx;  bfd_byte *                    hit_data = contents + rel->r_offset;  bfd *                         dynobj = NULL;  Elf_Internal_Shdr *           symtab_hdr;  struct elf_link_hash_entry ** sym_hashes;  bfd_vma *                     local_got_offsets;  asection *                    sgot = NULL;  asection *                    splt = NULL;  asection *                    sreloc = NULL;  bfd_vma                       addend;  bfd_signed_vma                signed_addend;  struct elf32_arm_link_hash_table * globals;  /* If the start address has been set, then set the EF_ARM_HASENTRY     flag.  Setting this more than once is redundant, but the cost is     not too high, and it keeps the code simple.          The test is done  here, rather than somewhere else, because the     start address is only set just before the final link commences.     Note - if the user deliberately sets a start address of 0, the     flag will not be set.  */  if (bfd_get_start_address (output_bfd) != 0)    elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;        globals = elf32_arm_hash_table (info);  dynobj = elf_hash_table (info)->dynobj;  if (dynobj)    {      sgot = bfd_get_section_by_name (dynobj, ".got");      splt = bfd_get_section_by_name (dynobj, ".plt");    }  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;  sym_hashes = elf_sym_hashes (input_bfd);  local_got_offsets = elf_local_got_offsets (input_bfd);  r_symndx = ELF32_R_SYM (rel->r_info);#ifdef USE_REL  addend = bfd_get_32 (input_bfd, hit_data) & howto->src_mask;  if (addend & ((howto->src_mask + 1) >> 1))    {      signed_addend = -1;      signed_addend &= ~ howto->src_mask;      signed_addend |= addend;    }  else    signed_addend = addend;#else  addend = signed_addend = rel->r_addend;#endif  switch (r_type)    {    case R_ARM_NONE:      return bfd_reloc_ok;    case R_ARM_PC24:    case R_ARM_ABS32:    case R_ARM_REL32:#ifndef OLD_ARM_ABI    case R_ARM_XPC25:#endif      /* When generating a shared object, these relocations are copied	 into the output file to be resolved at run time.  */      if (info->shared	  && (r_type != R_ARM_PC24 	      || (h != NULL	          && h->dynindx != -1		  && (! info->symbolic		      || (h->elf_link_hash_flags			  & ELF_LINK_HASH_DEF_REGULAR) == 0))))	{	  Elf_Internal_Rel outrel;	  boolean skip, relocate;	  if (sreloc == NULL)	    {	      const char * name;	      name = (bfd_elf_string_from_elf_section		      (input_bfd,		       elf_elfheader (input_bfd)->e_shstrndx,		       elf_section_data (input_section)->rel_hdr.sh_name));	      if (name == NULL)		return bfd_reloc_notsupported;	      BFD_ASSERT (strncmp (name, ".rel", 4) == 0			  && strcmp (bfd_get_section_name (input_bfd,							   input_section),				     name + 4) == 0);	      sreloc = bfd_get_section_by_name (dynobj, name);	      BFD_ASSERT (sreloc != NULL);	    }	  skip = false;	  if (elf_section_data (input_section)->stab_info == NULL)	    outrel.r_offset = rel->r_offset;	  else	    {	      bfd_vma off;	      off = (_bfd_stab_section_offset		     (output_bfd, &elf_hash_table (info)->stab_info,		      input_section,		      & elf_section_data (input_section)->stab_info,		      rel->r_offset));	      if (off == (bfd_vma) -1)		skip = true;	      outrel.r_offset = off;	    }	  outrel.r_offset += (input_section->output_section->vma			      + input_section->output_offset);	  if (skip)	    {	      memset (&outrel, 0, sizeof outrel);	      relocate = false;	    }	  else if (r_type == R_ARM_PC24)	    {	      BFD_ASSERT (h != NULL && h->dynindx != -1);	      if ((input_section->flags & SEC_ALLOC) != 0)		relocate = false;	      else		relocate = true;	      outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_PC24);	    }	  else	    {	      if (h == NULL		  || ((info->symbolic || h->dynindx == -1)		      && (h->elf_link_hash_flags			  & ELF_LINK_HASH_DEF_REGULAR) != 0))		{		  relocate = true;		  outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);		}	      else		{		  BFD_ASSERT (h->dynindx != -1);		  if ((input_section->flags & SEC_ALLOC) != 0)		    relocate = false;		  else		    relocate = true;		  outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_ABS32);		}	    }	  bfd_elf32_swap_reloc_out (output_bfd, &outrel,				    (((Elf32_External_Rel *)				      sreloc->contents)				     + sreloc->reloc_count));	  ++sreloc->reloc_count;	  /* If this reloc is against an external symbol, we do not want to	     fiddle with the addend.  Otherwise, we need to include the symbol	     value so that it becomes an addend for the dynamic reloc.  */	  if (! relocate)	    return bfd_reloc_ok;	  return _bfd_final_link_relocate (howto, input_bfd, input_section,					   contents, rel->r_offset, value,					   (bfd_vma) 0);	}      else switch (r_type)	{#ifndef OLD_ARM_ABI	case R_ARM_XPC25:	  /* Arm BLX instruction.  */#endif	case R_ARM_PC24:	  /* Arm B/BL instruction */#ifndef OLD_ARM_ABI	  if (r_type == R_ARM_XPC25)	    {	      /* Check for Arm calling Arm function.  */	      /* FIXME: Should we translate the instruction into a BL		 instruction instead ?  */	      if (sym_flags != STT_ARM_TFUNC)		_bfd_error_handler (_("\%s: Warning: Arm BLX instruction targets Arm function '%s'."),				    bfd_get_filename (input_bfd),				    h ? h->root.root.string : "(local)");	    }	  else#endif	    {	      /* Check for Arm calling Thumb function.  */	      if (sym_flags == STT_ARM_TFUNC)		{		  elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,					   input_section, hit_data, sym_sec, rel->r_offset,					   signed_addend, value);		  return bfd_reloc_ok;		}	    }	  if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0	      || strcmp (bfd_get_target (input_bfd), "elf32-bigarm-oabi") == 0)	    {	      /* The old way of doing things.  Trearing the addend as a		 byte sized field and adding in the pipeline offset.  */	      value -= (input_section->output_section->vma			+ input_section->output_offset);	      value -= rel->r_offset;	      value += addend;	      if (! globals->no_pipeline_knowledge)		value -= 8;	    }	  else	    {	      /* The ARM ELF ABI says that this reloc is computed as: S - P + A		 where:		  S is the address of the symbol in the relocation.		  P is address of the instruction being relocated.		  A is the addend (extracted from the instruction) in bytes.		 S is held in 'value'.		 P is the base address of the section containing the instruction		   plus the offset of the reloc into that section, ie:		     (input_section->output_section->vma +		      input_section->output_offset +		      rel->r_offset).		 A is the addend, converted into bytes, ie:		     (signed_addend * 4)		 Note: None of these operations have knowledge of the pipeline		 size of the processor, thus it is up to the assembler to encode		 this information into the addend.  */	      value -= (input_section->output_section->vma			+ input_section->output_offset);	      value -= rel->r_offset;	      value += (signed_addend << howto->size);	      /* Previous versions of this code also used to add in the pipeline		 offset here.  This is wrong because the linker is not supposed		 to know about such things, and one day it might change.  In order		 to support old binaries that need the old behaviour however, so		 we attempt to detect which ABI was used to create the reloc.  */	      if (! globals->no_pipeline_knowledge)		{		  Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form */		  i_ehdrp = elf_elfheader (input_bfd);		  if (i_ehdrp->e_ident[EI_OSABI] == 0)		    value -= 8;		}	    }	  signed_addend = value;	  signed_addend >>= howto->rightshift;	  /* It is not an error for an undefined weak reference to be	     out of range.  Any program that branches to such a symbol	     is going to crash anyway, so there is no point worrying	     about getting the destination exactly right.  */	  if (! h || h->root.type != bfd_link_hash_undefweak)	    {	      /* Perform a signed range check.  */	      if (   signed_addend >   ((bfd_signed_vma)  (howto->dst_mask >> 1))		  || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))		return bfd_reloc_overflow;	    }#ifndef OLD_ARM_ABI	  /* If necessary set the H bit in the BLX instruction.  */	  if (r_type == R_ARM_XPC25 && ((value & 2) == 2))	    value = (signed_addend & howto->dst_mask)	      | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask))	      | (1 << 24);	  else#endif	    value = (signed_addend & howto->dst_mask)	      | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));	  break;	case R_ARM_ABS32:	  value += addend;	  if (sym_flags == STT_ARM_TFUNC)	    value |= 1;	  break;	case R_ARM_REL32:	  value -= (input_section->output_section->vma		    + input_section->output_offset);	  value += addend;	  break;	}      bfd_put_32 (input_bfd, value, hit_data);      return bfd_reloc_ok;    case R_ARM_ABS8:      value += addend;      if ((long) value > 0x7f || (long) value < -0x80)	return bfd_reloc_overflow;      bfd_put_8 (input_bfd, value, hit_data);      return bfd_reloc_ok;    case R_ARM_ABS16:      value += addend;      if ((long) value > 0x7fff || (long) value < -0x8000)	return bfd_reloc_overflow;      bfd_put_16 (input_bfd, value, hit_data);

⌨️ 快捷键说明

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