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

📄 elf32-i386.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
  struct bfd_link_info *info = (struct bfd_link_info *) inf;  /* If a symbol has been forced local or we have found a regular     definition for the symbolic link case, then we won't be needing     any relocs.  */  if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0      && ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0	  || info->symbolic))    {      for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)	s->section->_raw_size -= s->count * sizeof (Elf32_External_Rel);    }  return true;}/* Relocate an i386 ELF section.  */static booleanelf_i386_relocate_section (output_bfd, info, input_bfd, input_section,			   contents, relocs, local_syms, local_sections)     bfd *output_bfd;     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;{  bfd *dynobj;  Elf_Internal_Shdr *symtab_hdr;  struct elf_link_hash_entry **sym_hashes;  bfd_vma *local_got_offsets;  asection *sgot;  asection *splt;  asection *sreloc;  Elf_Internal_Rela *rel;  Elf_Internal_Rela *relend;  dynobj = elf_hash_table (info)->dynobj;  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;  sym_hashes = elf_sym_hashes (input_bfd);  local_got_offsets = elf_local_got_offsets (input_bfd);  sreloc = NULL;  splt = NULL;  sgot = NULL;  if (dynobj != NULL)    {      splt = bfd_get_section_by_name (dynobj, ".plt");      sgot = bfd_get_section_by_name (dynobj, ".got");    }  rel = relocs;  relend = relocs + input_section->reloc_count;  for (; rel < relend; rel++)    {      int r_type;      reloc_howto_type *howto;      unsigned long r_symndx;      struct elf_link_hash_entry *h;      Elf_Internal_Sym *sym;      asection *sec;      bfd_vma relocation;      bfd_reloc_status_type r;      unsigned int indx;      r_type = ELF32_R_TYPE (rel->r_info);      if (r_type == (int) R_386_GNU_VTINHERIT	  || r_type == (int) R_386_GNU_VTENTRY)	continue;      if ((indx = (unsigned) r_type) >= R_386_standard	  && ((indx = (unsigned) r_type - R_386_ext_offset) - R_386_standard	      >= R_386_ext - R_386_standard))	{	  bfd_set_error (bfd_error_bad_value);	  return false;	}      howto = elf_howto_table + indx;      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.  */	  if (r_symndx < symtab_hdr->sh_info)	    {	      sym = local_syms + r_symndx;	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)		{		  bfd_vma val;		  sec = local_sections[r_symndx];		  val = bfd_get_32 (input_bfd, contents + rel->r_offset);		  val += sec->output_offset + sym->st_value;		  bfd_put_32 (input_bfd, val, contents + rel->r_offset);		}	    }	  continue;	}      /* This is a final link.  */      h = NULL;      sym = NULL;      sec = NULL;      if (r_symndx < symtab_hdr->sh_info)	{	  sym = local_syms + r_symndx;	  sec = local_sections[r_symndx];	  relocation = (sec->output_section->vma			+ sec->output_offset			+ sym->st_value);	}      else	{	  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;	  if (h->root.type == bfd_link_hash_defined	      || h->root.type == bfd_link_hash_defweak)	    {	      sec = h->root.u.def.section;	      if (r_type == R_386_GOTPC		  || (r_type == R_386_PLT32		      && splt != NULL		      && h->plt.offset != (bfd_vma) -1)		  || (r_type == R_386_GOT32		      && elf_hash_table (info)->dynamic_sections_created		      && (! info->shared			  || (! info->symbolic && h->dynindx != -1)			  || (h->elf_link_hash_flags			      & ELF_LINK_HASH_DEF_REGULAR) == 0))		  || (info->shared		      && ((! info->symbolic && h->dynindx != -1)			  || (h->elf_link_hash_flags			      & ELF_LINK_HASH_DEF_REGULAR) == 0)		      && (r_type == R_386_32			  || r_type == R_386_PC32)		      && ((input_section->flags & SEC_ALLOC) != 0			  /* DWARF will emit R_386_32 relocations in its			     sections against symbols defined externally			     in shared libraries.  We can't do anything			     with them here.  */			  || ((input_section->flags & SEC_DEBUGGING) != 0			      && (h->elf_link_hash_flags				  & ELF_LINK_HASH_DEF_DYNAMIC) != 0))))		{		  /* In these cases, we don't need the relocation                     value.  We check specially because in some                     obscure cases sec->output_section will be NULL.  */		  relocation = 0;		}	      else if (sec->output_section == 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		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->shared && !info->symbolic		   && !info->no_undefined		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)	    relocation = 0;	  else	    {	      if (! ((*info->callbacks->undefined_symbol)		     (info, h->root.root.string, input_bfd,		      input_section, rel->r_offset,		      (!info->shared || info->no_undefined		       || ELF_ST_VISIBILITY (h->other)))))		return false;	      relocation = 0;	    }	}      switch (r_type)	{	case R_386_GOT32:	  /* Relocation is to the entry for this symbol in the global	     offset table.  */	  BFD_ASSERT (sgot != NULL);	  if (h != NULL)	    {	      bfd_vma off;	      off = h->got.offset;	      BFD_ASSERT (off != (bfd_vma) -1);	      if (! elf_hash_table (info)->dynamic_sections_created		  || (info->shared		      && (info->symbolic || h->dynindx == -1)		      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))		{		  /* This is actually a static link, or it is a		     -Bsymbolic link and the symbol is defined		     locally, or the symbol was forced to be local		     because of a version file.  We must initialize		     this entry in the global offset table.  Since the		     offset must always be a multiple of 4, we use the		     least significant bit to record whether we have		     initialized it already.		     When doing a dynamic link, we create a .rel.got		     relocation entry to initialize the value.  This		     is done in the finish_dynamic_symbol routine.  */		  if ((off & 1) != 0)		    off &= ~1;		  else		    {		      bfd_put_32 (output_bfd, relocation,				  sgot->contents + off);		      h->got.offset |= 1;		    }		}	      relocation = sgot->output_offset + off;	    }	  else	    {	      bfd_vma off;	      BFD_ASSERT (local_got_offsets != NULL			  && local_got_offsets[r_symndx] != (bfd_vma) -1);	      off = local_got_offsets[r_symndx];	      /* The offset must always be a multiple of 4.  We use                 the least significant bit to record whether we have                 already generated the necessary reloc.  */	      if ((off & 1) != 0)		off &= ~1;	      else		{		  bfd_put_32 (output_bfd, relocation, sgot->contents + off);		  if (info->shared)		    {		      asection *srelgot;		      Elf_Internal_Rel outrel;		      srelgot = bfd_get_section_by_name (dynobj, ".rel.got");		      BFD_ASSERT (srelgot != NULL);		      outrel.r_offset = (sgot->output_section->vma					 + sgot->output_offset					 + off);		      outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);		      bfd_elf32_swap_reloc_out (output_bfd, &outrel,						(((Elf32_External_Rel *)						  srelgot->contents)						 + srelgot->reloc_count));		      ++srelgot->reloc_count;		    }		  local_got_offsets[r_symndx] |= 1;		}	      relocation = sgot->output_offset + off;	    }	  break;	case R_386_GOTOFF:	  /* Relocation is relative to the start of the global offset	     table.  */	  if (sgot == NULL)	    {	      sgot = bfd_get_section_by_name (dynobj, ".got");	      BFD_ASSERT (sgot != NULL);	    }	  /* Note that sgot->output_offset is not involved in this	     calculation.  We always want the start of .got.  If we	     defined _GLOBAL_OFFSET_TABLE in a different way, as is	     permitted by the ABI, we might have to change this	     calculation.  */	  relocation -= sgot->output_section->vma;	  break;	case R_386_GOTPC:	  /* Use global offset table as symbol value.  */	  if (sgot == NULL)	    {	      sgot = bfd_get_section_by_name (dynobj, ".got");	      BFD_ASSERT (sgot != NULL);	    }	  relocation = sgot->output_section->vma;	  break;	case R_386_PLT32:	  /* Relocation is to the entry for this symbol in the	     procedure linkage table.  */	  /* Resolve a PLT32 reloc against a local symbol directly,             without using the procedure linkage table.  */	  if (h == NULL)	    break;	  if (h->plt.offset == (bfd_vma) -1	      || splt == NULL)	    {	      /* We didn't make a PLT entry for this symbol.  This                 happens when statically linking PIC code, or when                 using -Bsymbolic.  */	      break;	    }	  relocation = (splt->output_section->vma			+ splt->output_offset			+ h->plt.offset);	  break;	case R_386_32:	case R_386_PC32:	  if (info->shared	      && (input_section->flags & SEC_ALLOC) != 0	      && (r_type != R_386_PC32		  || (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;	      /* When generating a shared object, these relocations		 are copied into the output file to be resolved at run		 time.  */	      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 false;		  if (strncmp (name, ".rel", 4) != 0		      || strcmp (bfd_get_section_name (input_bfd,						       input_section),				 name + 4) != 0)		    {		      if (input_bfd->my_archive)			(*_bfd_error_handler) (_("%s(%s): bad relocation section name `%s\'"),					       bfd_get_filename (input_bfd->my_archive),					       bfd_get_filename (input_bfd),					       name);		      else			(*_bfd_error_handler) (_("%s: bad relocation section name `%s\'"),					       bfd_get_filename (input_bfd),					       name);		      return false;		    }		  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_386_PC32)		{		  BFD_ASSERT (h != NULL && h->dynindx != -1);		  relocate = false;		  outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_PC32);		}	      else		{		  /* h->dynindx may be -1 if this symbol was marked to                     become local.  */		  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_386_RELATIVE);		    }		  else		    {		      BFD_ASSERT (h->dynindx != -1);

⌨️ 快捷键说明

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