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

📄 elf32-m32r.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	  bfd_set_section_flags (abfd, s, flags);	  bfd_set_section_alignment (abfd, s, 2);	}      h = (struct elf_link_hash_entry *)	bfd_link_hash_lookup (info->hash, "_SDA_BASE_", false, false, false);      if ((h == NULL || h->root.type == bfd_link_hash_undefined)	  && !(_bfd_generic_link_add_one_symbol (info,						 abfd,						 "_SDA_BASE_",						 BSF_GLOBAL,						 s,						 32768,						 (const char *) NULL,						 false,						 get_elf_backend_data (abfd)->collect,						 (struct bfd_link_hash_entry **) &h)))	return false;      h->type = STT_OBJECT;    }  switch (sym->st_shndx)    {    case SHN_M32R_SCOMMON:      *secp = bfd_make_section_old_way (abfd, ".scommon");      (*secp)->flags |= SEC_IS_COMMON;      *valp = sym->st_size;      break;    }  return true;}/* We have to figure out the SDA_BASE value, so that we can adjust the   symbol value correctly.  We look up the symbol _SDA_BASE_ in the output   BFD.  If we can't find it, we're stuck.  We cache it in the ELF   target data.  We don't need to adjust the symbol value for an   external symbol if we are producing relocateable output.  */static bfd_reloc_status_typem32r_elf_final_sda_base (output_bfd, info, error_message, psb)     bfd *output_bfd;     struct bfd_link_info *info;     const char **error_message;     bfd_vma *psb;{  if (elf_gp (output_bfd) == 0)    {      struct bfd_link_hash_entry *h;      h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", false, false, true);      if (h != (struct bfd_link_hash_entry *) NULL	  && h->type == bfd_link_hash_defined)	elf_gp (output_bfd) = (h->u.def.value			       + h->u.def.section->output_section->vma			       + h->u.def.section->output_offset);      else	{	  /* Only get the error once.  */	  *psb = elf_gp (output_bfd) = 4;	  *error_message =	    (const char *) _("SDA relocation when _SDA_BASE_ not defined");	  return bfd_reloc_dangerous;	}    }  *psb = elf_gp (output_bfd);  return bfd_reloc_ok;}/* Relocate an M32R/D ELF section.   There is some attempt to make this function usable for many architectures,   both USE_REL and USE_RELA ['twould be nice if such a critter existed],   if only to serve as a learning tool.   The RELOCATE_SECTION function is called by the new ELF backend linker   to handle the relocations for a section.   The relocs are always passed as Rela structures; if the section   actually uses Rel structures, the r_addend field will always be   zero.   This function is responsible for adjust the section contents as   necessary, and (if using Rela relocs and generating a   relocateable output file) adjusting the reloc addend as   necessary.   This function does not have to worry about setting the reloc   address or the reloc symbol index.   LOCAL_SYMS is a pointer to the swapped in local symbols.   LOCAL_SECTIONS is an array giving the section in the input file   corresponding to the st_shndx field of each local symbol.   The global hash table entry for the global symbols can be found   via elf_sym_hashes (input_bfd).   When generating relocateable output, this function must handle   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is   going to be the section symbol corresponding to the output   section, which means that the addend must be adjusted   accordingly.  */static booleanm32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,			   contents, relocs, local_syms, local_sections)     bfd *output_bfd ATTRIBUTE_UNUSED;     struct bfd_link_info *info;     bfd *input_bfd;     asection *input_section;     bfd_byte *contents;     Elf_Internal_Rela *relocs;     Elf_Internal_Sym *local_syms;     asection **local_sections;{  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);  Elf_Internal_Rela *rel, *relend;  /* Assume success.  */  boolean ret = true;  rel = relocs;  relend = relocs + input_section->reloc_count;  for (; rel < relend; rel++)    {      int r_type;      reloc_howto_type *howto;      unsigned long r_symndx;      /* We can't modify r_addend here as elf_link_input_bfd has an assert to	 ensure it's zero (we use REL relocs, not RELA).  Therefore this	 should be assigning zero to `addend', but for clarity we use	 `r_addend'.  */      bfd_vma addend = rel->r_addend;      bfd_vma offset = rel->r_offset;      struct elf_link_hash_entry *h;      Elf_Internal_Sym *sym;      asection *sec;      const char *sym_name;      bfd_reloc_status_type r;      const char *errmsg = NULL;      h = NULL;      r_type = ELF32_R_TYPE (rel->r_info);      if (r_type < 0 || r_type >= (int) R_M32R_max)	{	  (*_bfd_error_handler) (_("%s: unknown relocation type %d"),				 bfd_get_filename (input_bfd),				 (int) r_type);	  bfd_set_error (bfd_error_bad_value);	  ret = false;	  continue;	}      if (r_type == R_M32R_GNU_VTENTRY          || r_type == R_M32R_GNU_VTINHERIT)        continue;      howto = m32r_elf_howto_table + r_type;      r_symndx = ELF32_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.  */	  sec = NULL;	  if (r_symndx >= symtab_hdr->sh_info)	    {	      /* External symbol.  */	      continue;	    }	  /* Local symbol.  */	  sym = local_syms + r_symndx;	  sym_name = "<local symbol>";	  /* STT_SECTION: symbol is associated with a section.  */	  if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)	    {	      /* Symbol isn't associated with a section.  Nothing to do.  */	      continue;	    }	  sec = local_sections[r_symndx];	  addend += sec->output_offset + sym->st_value;#ifndef USE_REL	  /* This can't be done for USE_REL because it doesn't mean anything	     and elf_link_input_bfd asserts this stays zero.  */	  rel->r_addend = addend;#endif#ifndef USE_REL	  /* Addends are stored with relocs.  We're done.  */	  continue;#else /* USE_REL */	  /* If partial_inplace, we need to store any additional addend	     back in the section.  */	  if (! howto->partial_inplace)	    continue;	  /* ??? Here is a nice place to call a special_function	     like handler.  */	  if (r_type != R_M32R_HI16_SLO && r_type != R_M32R_HI16_ULO)	    r = _bfd_relocate_contents (howto, input_bfd,					addend, contents + offset);	  else	    {	      Elf_Internal_Rela *lorel;	      /* We allow an arbitrary number of HI16 relocs before the		 LO16 reloc.  This permits gcc to emit the HI and LO relocs		 itself.  */	      for (lorel = rel + 1;		   (lorel < relend		    && (ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_SLO			|| ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_ULO));		   lorel++)		continue;	      if (lorel < relend		  && ELF32_R_TYPE (lorel->r_info) == R_M32R_LO16)		{		  m32r_elf_relocate_hi16 (input_bfd, r_type, rel, lorel,					  contents, addend);		  r = bfd_reloc_ok;		}	      else		r = _bfd_relocate_contents (howto, input_bfd,					    addend, contents + offset);	    }#endif /* USE_REL */	}      else	{	  bfd_vma relocation;	  /* This is a final link.  */	  sym = NULL;	  sec = NULL;	  if (r_symndx < symtab_hdr->sh_info)	    {	      /* Local symbol.  */	      sym = local_syms + r_symndx;	      sec = local_sections[r_symndx];	      sym_name = "<local symbol>";	      relocation = (sec->output_section->vma			    + sec->output_offset			    + sym->st_value);	    }	  else	    {	      /* External symbol.  */	      h = sym_hashes[r_symndx - symtab_hdr->sh_info];	      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;	      sym_name = h->root.root.string;	      if (h->root.type == bfd_link_hash_defined		  || h->root.type == bfd_link_hash_defweak)		{		  sec = h->root.u.def.section;		  if (sec->output_section == NULL)		    relocation = 0;		  else		    relocation = (h->root.u.def.value				  + sec->output_section->vma				  + sec->output_offset);		}	      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, offset, true)))		    return false;		  relocation = 0;		}	    }	  /* Sanity check the address.  */	  if (offset > input_section->_raw_size)	    {	      r = bfd_reloc_outofrange;	      goto check_reloc;	    }	  switch ((int) r_type)	    {	    case (int) R_M32R_10_PCREL :	      r = m32r_elf_do_10_pcrel_reloc (input_bfd, howto, input_section,					      contents, offset,					      sec, relocation, addend);	      break;	    case (int) R_M32R_HI16_SLO :	    case (int) R_M32R_HI16_ULO :	      {		Elf_Internal_Rela *lorel;		/* We allow an arbitrary number of HI16 relocs before the		   LO16 reloc.  This permits gcc to emit the HI and LO relocs		   itself.  */		for (lorel = rel + 1;		     (lorel < relend		      && (ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_SLO			  || ELF32_R_TYPE (lorel->r_info) == R_M32R_HI16_ULO));		     lorel++)		  continue;		if (lorel < relend		    && ELF32_R_TYPE (lorel->r_info) == R_M32R_LO16)		  {		    m32r_elf_relocate_hi16 (input_bfd, r_type, rel, lorel,					    contents, relocation + addend);		    r = bfd_reloc_ok;		  }		else		  r = _bfd_final_link_relocate (howto, input_bfd, input_section,						contents, offset,						relocation, addend);	      }	      break;	    case (int) R_M32R_SDA16 :	      {		const char *name;		BFD_ASSERT (sec != NULL);		name = bfd_get_section_name (abfd, sec);		if (strcmp (name, ".sdata") == 0		    || strcmp (name, ".sbss") == 0		    || strcmp (name, ".scommon") == 0)		  {		    bfd_vma sda_base;		    bfd *out_bfd = sec->output_section->owner;		    r = m32r_elf_final_sda_base (out_bfd, info,						 &errmsg,						 &sda_base);		    if (r != bfd_reloc_ok)		      {			ret = false;			goto check_reloc;		      }		    /* At this point `relocation' contains the object's		       address.  */		    relocation -= sda_base;		    /* Now it contains the offset from _SDA_BASE_.  */		  }		else		  {		    (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),					   bfd_get_filename (input_bfd),					   sym_name,					   m32r_elf_howto_table[(int) r_type].name,					   bfd_get_section_name (abfd, sec));		    /*bfd_set_error (bfd_error_bad_value); ??? why? */		    ret = false;		    continue;		  }	      }	      /* fall through */	    default :	      r = _bfd_final_link_relocate (howto, input_bfd, input_section,					    contents, offset,					    relocation, addend);	      break;	    }	}    check_reloc:      if (r != bfd_reloc_ok)	{	  /* FIXME: This should be generic enough to go in a utility.  */	  const char *name;	  if (h != NULL)	    name = h->root.root.string;	  else	    {	      name = (bfd_elf_string_from_elf_section		      (input_bfd, symtab_hdr->sh_link, sym->st_name));	      if (name == NULL || *name == '\0')		name = bfd_section_name (input_bfd, sec);	    }	  if (errmsg != NULL)	    goto common_error;	  switch (r)	    {	    case bfd_reloc_overflow:	      if (! ((*info->callbacks->reloc_overflow)		     (info, name, howto->name, (bfd_vma) 0,		      input_bfd, input_section, offset)))		return false;	      break;	    case bfd_reloc_undefined:	      if (! ((*info->callbacks->undefined_symbol)		     (info, name, input_bfd, input_section,		      offset, true)))		return false;	      break;	    case bfd_reloc_outofrange:	      errmsg = _("internal error: out of range error");	      goto common_error;	    case bfd_reloc_notsupported:	      errmsg = _("internal error: unsupported relocation error");	      goto common_error;	    case bfd_reloc_dangerous:	      errmsg = _("internal error: dangerous error");	      goto common_error;	    default:	      errmsg = _("internal error: unknown error");	      /* fall through */	    common_error:

⌨️ 快捷键说明

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