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

📄 elf64-x86-64.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
	    }	}      else if (strncmp (name, ".rela", 5) == 0)	{	  if (s->_raw_size == 0)	    {	      /* If we don't need this section, strip it from the		 output file.  This is mostly to handle .rela.bss and		 .rela.plt.  We must create both sections in		 create_dynamic_sections, because they must be created		 before the linker maps input sections to output		 sections.  The linker does that before		 adjust_dynamic_symbol is called, and it is that		 function which decides whether anything needs to go		 into these sections.  */	      strip = true;	    }	  else	    {	      asection *target;	      /* Remember whether there are any reloc sections other		 than .rela.plt.  */	      if (strcmp (name, ".rela.plt") != 0)		{		  const char *outname;		  relocs = true;		  /* If this relocation section applies to a read only		     section, then we probably need a DT_TEXTREL		     entry.  The entries in the .rela.plt section		     really apply to the .got section, which we		     created ourselves and so know is not readonly.  */		  outname = bfd_get_section_name (output_bfd,						  s->output_section);		  target = bfd_get_section_by_name (output_bfd, outname + 5);		  if (target != NULL		      && (target->flags & SEC_READONLY) != 0		      && (target->flags & SEC_ALLOC) != 0)		    reltext = true;		}	      /* We use the reloc_count field as a counter if we need		 to copy relocs into the output file.  */	      s->reloc_count = 0;	    }	}      else if (strncmp (name, ".got", 4) != 0)	{	  /* It's not one of our sections, so don't allocate space.  */	  continue;	}      if (strip)	{	  _bfd_strip_section_from_output (info, s);	  continue;	}      /* Allocate memory for the section contents.  We use bfd_zalloc	 here in case unused entries are not reclaimed before the	 section's contents are written out.  This should not happen,	 but this way if it does, we get a R_X86_64_NONE reloc instead	 of garbage.  */      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);      if (s->contents == NULL && s->_raw_size != 0)	return false;    }  if (elf_hash_table (info)->dynamic_sections_created)    {      /* Add some entries to the .dynamic section.  We fill in the	 values later, in elf64_x86_64_finish_dynamic_sections, but we	 must add the entries now so that we get the correct size for	 the .dynamic section.	The DT_DEBUG entry is filled in by the	 dynamic linker and used by the debugger.  */      if (! info->shared)	{	  if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))	    return false;	}      if (plt)	{	  if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)	      || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)	      || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)	      || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))	    return false;	}      if (relocs)	{	  if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)	      || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)	      || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,						sizeof (Elf64_External_Rela)))	    return false;	}      if (reltext)	{	  if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))	    return false;	  info->flags |= DF_TEXTREL;	}    }  return true;}/* This function is called via elf64_x86_64_link_hash_traverse if we are   creating a shared object.  In the -Bsymbolic case, it discards the   space allocated to copy PC relative relocs against symbols which   are defined in regular objects.  For the normal non-symbolic case,   we also discard space for relocs that have become local due to   symbol visibility changes.  We allocated space for them in the   check_relocs routine, but we won't fill them in in the   relocate_section routine.  */static booleanelf64_x86_64_discard_copies (h, inf)     struct elf64_x86_64_link_hash_entry *h;     PTR inf;{  struct elf64_x86_64_pcrel_relocs_copied *s;  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 (Elf64_External_Rela);    }  return true;}/* Relocate an x86_64 ELF section.  */static booleanelf64_x86_64_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 *rela;  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 = splt = sgot = NULL;  if (dynobj != NULL)    {      splt = bfd_get_section_by_name (dynobj, ".plt");      sgot = bfd_get_section_by_name (dynobj, ".got");    }  rela = relocs;  relend = relocs + input_section->reloc_count;  for (; rela < relend; rela++)    {      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 = ELF64_R_TYPE (rela->r_info);      if ((indx = (unsigned) r_type) >= R_X86_64_max)	{	  bfd_set_error (bfd_error_bad_value);	  return false;	}      howto = x86_64_elf_howto_table + indx;      r_symndx = ELF64_R_SYM (rela->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)		{		  sec = local_sections[r_symndx];		  rela->r_addend += sec->output_offset + sym->st_value;		}	    }	  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_X86_64_PLT32		   && splt != NULL		   && h->plt.offset != (bfd_vma) -1)		  || ((r_type == R_X86_64_GOT32 || r_type == R_X86_64_GOTPCREL)		      && 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_X86_64_8			  || r_type == R_X86_64_16			  || r_type == R_X86_64_32			  || r_type == R_X86_64_64			  || r_type == R_X86_64_PC8			  || r_type == R_X86_64_PC16			  || r_type == R_X86_64_PC32)                      && ((input_section->flags & SEC_ALLOC) != 0                          /* DWARF will emit R_X86_64_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, rela->r_offset,		      (!info->shared || info->no_undefined		       || ELF_ST_VISIBILITY (h->other)))))		return false;	      relocation = 0;	    }	}      /* When generating a shared object, the relocations handled here are	 copied into the output file to be resolved at run time.  */      switch (r_type)	{	case R_X86_64_GOT32:	  /* Relocation is to the entry for this symbol in the global	     offset table.  */	case R_X86_64_GOTPCREL:	  /* Use global offset table as symbol value.  */	  BFD_ASSERT (sgot != NULL);	  if (h != NULL)	    {	      bfd_vma 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 8, we		     use the least significant bit to record whether we		     have initialized it already.		     When doing a dynamic link, we create a .rela.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_64 (output_bfd, relocation,				  sgot->contents + off);		      h->got.offset |= 1;		    }		}	      if (r_type == R_X86_64_GOTPCREL)		relocation = sgot->output_section->vma + sgot->output_offset + off;	      else		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 8.  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_64 (output_bfd, relocation, sgot->contents + off);		  if (info->shared)		    {		      asection *srelgot;		      Elf_Internal_Rela outrel;		      /* We need to generate a R_X86_64_RELATIVE reloc			 for the dynamic linker.  */		      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");		      BFD_ASSERT (srelgot != NULL);		      outrel.r_offset = (sgot->output_section->vma					 + sgot->output_offset					 + off);		      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);		      outrel.r_addend = relocation;		      bfd_elf64_swap_reloca_out (output_bfd, &outrel,						 (((Elf64_External_Rela *)						   srelgot->contents)						  + srelgot->reloc_count));		      ++srelgot->reloc_count;		    }		  local_got_offsets[r_symndx] |= 1;		}	      if (r_type == R_X86_64_GOTPCREL)		relocation = sgot->output_section->vma + sgot->output_offset + off;	      else		relocation = sgot->output_offset + off;	    }	  break;	case R_X86_64_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_X86_64_PC8:	case R_X86_64_PC16:	case R_X86_64_PC32:	  if (h == NULL)	    break;	  /* Fall through.  */	case R_X86_64_8:	case R_X86_64_16:	case R_X86_64_32:	case R_X86_64_64:	  /* FIXME: The ABI says the linker should make sure the value is	     the same when it's zeroextended to 64 bit.	 */	  if (info->shared	      && (input_section->flags & SEC_ALLOC) != 0	      && ((r_type != R_X86_64_PC8		   && r_type != R_X86_64_PC16		   && r_type != R_X86_64_PC32)		  || (! info->symbolic		      || (h->elf_link_hash_flags			  & ELF_LINK_HASH_DEF_REGULAR) == 0)))	    {	      Elf_Internal_Rela 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;		  BFD_ASSERT (strncmp (name, ".rela", 5) == 0			      && strcmp (bfd_get_section_name (input_bfd,							       input_section),					 name + 5) == 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 = rela->r_offset;	      else		{		  bfd_vma off;

⌨️ 快捷键说明

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