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

📄 elf-hppa.h

📁 基于4个mips核的noc设计
💻 H
📖 第 1 页 / 共 5 页
字号:
{  Elf_Internal_Shdr *symtab_hdr;  Elf_Internal_Rela *rel;  Elf_Internal_Rela *relend;  struct elf64_hppa_link_hash_table *hppa_info = elf64_hppa_hash_table (info);  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;  rel = relocs;  relend = relocs + input_section->reloc_count;  for (; rel < relend; rel++)    {      int r_type;      reloc_howto_type *howto = elf_hppa_howto_table + ELF_R_TYPE (rel->r_info);      unsigned long r_symndx;      struct elf_link_hash_entry *h;      Elf_Internal_Sym *sym;      asection *sym_sec;      bfd_vma relocation;      bfd_reloc_status_type r;      const char *sym_name;      const char *dyn_name;      char *dynh_buf = NULL;      size_t dynh_buflen = 0;      struct elf64_hppa_dyn_hash_entry *dyn_h = NULL;      r_type = ELF_R_TYPE (rel->r_info);      if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)	{	  bfd_set_error (bfd_error_bad_value);	  return false;	}      r_symndx = ELF_R_SYM (rel->r_info);      if (info->relocateable)	{	  /* This is a relocateable link.  We don't have to change	     anything, unless the reloc is against a section symbol,	     in which case we have to adjust according to where the	     section symbol winds up in the output section.  */	  if (r_symndx < symtab_hdr->sh_info)	    {	      sym = local_syms + r_symndx;	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)		{		  sym_sec = local_sections[r_symndx];		  rel->r_addend += sym_sec->output_offset;		}	    }	  continue;	}      /* This is a final link.  */      h = NULL;      sym = NULL;      sym_sec = NULL;      if (r_symndx < symtab_hdr->sh_info)	{	  /* This is a local symbol.  */	  sym = local_syms + r_symndx;	  sym_sec = local_sections[r_symndx];	  relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION			   ? 0 : sym->st_value)			 + sym_sec->output_offset			 + sym_sec->output_section->vma);	  /* If this symbol has an entry in the PA64 dynamic hash	     table, then get it.  */	  dyn_name = get_dyn_name (input_section, h, rel,				   &dynh_buf, &dynh_buflen);	  dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,					      dyn_name, false, false);	}      else	{	  /* This is not a local symbol.  */	  long indx;	  indx = r_symndx - symtab_hdr->sh_info;	  h = elf_sym_hashes (input_bfd)[indx];	  while (h->root.type == bfd_link_hash_indirect		 || h->root.type == bfd_link_hash_warning)	    h = (struct elf_link_hash_entry *) h->root.u.i.link;	  if (h->root.type == bfd_link_hash_defined	      || h->root.type == bfd_link_hash_defweak)	    {	      sym_sec = h->root.u.def.section;	      /* If this symbol has an entry in the PA64 dynamic hash		 table, then get it.  */	      dyn_name = get_dyn_name (input_section, h, rel,				       &dynh_buf, &dynh_buflen);	      dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,						  dyn_name, false, false);	      /* If we have a relocation against a symbol defined in a		 shared library and we have not created an entry in the		 PA64 dynamic symbol hash table for it, then we lose.  */	      if (sym_sec->output_section == NULL && dyn_h == NULL)		{		  (*_bfd_error_handler)		    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),		     bfd_get_filename (input_bfd), h->root.root.string,		     bfd_get_section_name (input_bfd, input_section));		  relocation = 0;		}	      else if (sym_sec->output_section)		relocation = (h->root.u.def.value			      + sym_sec->output_offset			      + sym_sec->output_section->vma);	      /* Value will be provided via one of the offsets in the		 dyn_h hash table entry.  */	      else		relocation = 0;	    }	  /* Allow undefined symbols in shared libraries.  */          else if (info->shared && !info->no_undefined		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)	    {	      if (info->symbolic)		(*info->callbacks->undefined_symbol)		  (info, h->root.root.string, input_bfd,		   input_section, rel->r_offset, false);	      /* If this symbol has an entry in the PA64 dynamic hash		 table, then get it.  */	      dyn_name = get_dyn_name (input_section, h, rel,				       &dynh_buf, &dynh_buflen);	      dyn_h = elf64_hppa_dyn_hash_lookup (&hppa_info->dyn_hash_table,						  dyn_name, false, false);	      if (dyn_h == NULL)		{		  (*_bfd_error_handler)		    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),		     bfd_get_filename (input_bfd), h->root.root.string,		     bfd_get_section_name (input_bfd, input_section));		  relocation = 0;		}	      relocation = 0;	    }	  else if (h->root.type == bfd_link_hash_undefweak)	    relocation = 0;	  else	    {	      if (!((*info->callbacks->undefined_symbol)		    (info, h->root.root.string, input_bfd,		     input_section, rel->r_offset, true)))		return false;	      break;	    }	}      if (h != NULL)	sym_name = h->root.root.string;      else	{	  sym_name = bfd_elf_string_from_elf_section (input_bfd,						      symtab_hdr->sh_link,						      sym->st_name);	  if (sym_name == NULL)	    return false;	  if (*sym_name == '\0')	    sym_name = bfd_section_name (input_bfd, sym_sec);	}      r = elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,					input_section, contents,					relocation, info, sym_sec,					h, dyn_h);      if (r != bfd_reloc_ok)	{	  switch (r)	    {	    default:	      abort ();	    case bfd_reloc_overflow:	      {		if (!((*info->callbacks->reloc_overflow)		      (info, sym_name, howto->name, (bfd_vma) 0,			input_bfd, input_section, rel->r_offset)))		  return false;	      }	      break;	    }	}    }  return true;}/* Compute the value for a relocation (REL) during a final link stage,   then insert the value into the proper location in CONTENTS.   VALUE is a tentative value for the relocation and may be overridden   and modified here based on the specific relocation to be performed.   For example we do conversions for PC-relative branches in this routine   or redirection of calls to external routines to stubs.   The work of actually applying the relocation is left to a helper   routine in an attempt to reduce the complexity and size of this   function.  */static bfd_reloc_status_typeelf_hppa_final_link_relocate (rel, input_bfd, output_bfd,			      input_section, contents, value,			      info, sym_sec, h, dyn_h)     Elf_Internal_Rela *rel;     bfd *input_bfd;     bfd *output_bfd;     asection *input_section;     bfd_byte *contents;     bfd_vma value;     struct bfd_link_info *info;     asection *sym_sec;     struct elf_link_hash_entry *h ATTRIBUTE_UNUSED;     struct elf64_hppa_dyn_hash_entry *dyn_h;{  unsigned int insn;  bfd_vma offset = rel->r_offset;  bfd_vma addend = rel->r_addend;  reloc_howto_type *howto = elf_hppa_howto_table + ELF_R_TYPE (rel->r_info);  unsigned int r_type = howto->type;  bfd_byte *hit_data = contents + offset;  struct elf64_hppa_link_hash_table *hppa_info = elf64_hppa_hash_table (info);  insn = bfd_get_32 (input_bfd, hit_data);  switch (r_type)    {    case R_PARISC_NONE:      break;    /* Basic function call support.  I'm not entirely sure if PCREL14F is       actually needed or even handled correctly.       Note for a call to a function defined in another dynamic library       we want to redirect the call to a stub.  */    /* Random PC relative relocs.  */    case R_PARISC_PCREL21L:    case R_PARISC_PCREL14R:    case R_PARISC_PCREL14F:    case R_PARISC_PCREL14WR:    case R_PARISC_PCREL14DR:    case R_PARISC_PCREL16F:    case R_PARISC_PCREL16WF:    case R_PARISC_PCREL16DF:      {	/* If this is a call to a function defined in another dynamic	   library, then redirect the call to the local stub for this	   function.  */	if (sym_sec == NULL || sym_sec->output_section == NULL)	  value = (dyn_h->stub_offset + hppa_info->stub_sec->output_offset		   + hppa_info->stub_sec->output_section->vma);	/* Turn VALUE into a proper PC relative address.  */	value -= (offset + input_section->output_offset		  + input_section->output_section->vma);	/* Adjust for any field selectors.  */	if (r_type == R_PARISC_PCREL21L)	  value = hppa_field_adjust (value, -8 + addend, e_lsel);	else if (r_type == R_PARISC_PCREL14F		 || r_type == R_PARISC_PCREL16F		 || r_type == R_PARISC_PCREL16WF		 || r_type == R_PARISC_PCREL16DF)	  value = hppa_field_adjust (value, -8 + addend, e_fsel);	else	  value = hppa_field_adjust (value, -8 + addend, e_rsel);	/* Apply the relocation to the given instruction.  */	insn = elf_hppa_relocate_insn (insn, value, r_type);	break;      }    case R_PARISC_PCREL12F:    case R_PARISC_PCREL22F:    case R_PARISC_PCREL17F:    case R_PARISC_PCREL22C:    case R_PARISC_PCREL17C:    case R_PARISC_PCREL17R:      {	/* If this is a call to a function defined in another dynamic	   library, then redirect the call to the local stub for this	   function.  */	if (sym_sec == NULL || sym_sec->output_section == NULL)	  value = (dyn_h->stub_offset + hppa_info->stub_sec->output_offset		   + hppa_info->stub_sec->output_section->vma);	/* Turn VALUE into a proper PC relative address.  */	value -= (offset + input_section->output_offset		  + input_section->output_section->vma);	/* Adjust for any field selectors.  */	if (r_type == R_PARISC_PCREL17R)	  value = hppa_field_adjust (value, -8 + addend, e_rsel);	else	  value = hppa_field_adjust (value, -8 + addend, e_fsel);	/* All branches are implicitly shifted by 2 places.  */	value >>= 2;	/* Apply the relocation to the given instruction.  */	insn = elf_hppa_relocate_insn (insn, value, r_type);	break;      }    /* Indirect references to data through the DLT.  */    case R_PARISC_DLTIND14

⌨️ 快捷键说明

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