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

📄 elf64-x86-64.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
		  off = (_bfd_stab_section_offset			 (output_bfd, &elf_hash_table (info)->stab_info,			  input_section,			  &elf_section_data (input_section)->stab_info,			  rela->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;		}	      /* h->dynindx may be -1 if this symbol was marked to		 become local.  */	      else if (h != NULL		       && ((! info->symbolic && h->dynindx != -1)			   || (h->elf_link_hash_flags			       & ELF_LINK_HASH_DEF_REGULAR) == 0))		{		  BFD_ASSERT (h->dynindx != -1);		  relocate = false;		  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);		  outrel.r_addend = relocation + rela->r_addend;		}	      else		{		  if (r_type == R_X86_64_64)		    {		      relocate = true;		      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);		      outrel.r_addend = relocation + rela->r_addend;		    }		  else		    {		      long indx;		      if (h == NULL)			sec = local_sections[r_symndx];		      else			{			  BFD_ASSERT (h->root.type == bfd_link_hash_defined				      || (h->root.type					  == bfd_link_hash_defweak));			  sec = h->root.u.def.section;			}		      if (sec != NULL && bfd_is_abs_section (sec))			indx = 0;		      else if (sec == NULL || sec->owner == NULL)			{			  bfd_set_error (bfd_error_bad_value);			  return false;			}		      else			{			  asection *osec;			  osec = sec->output_section;			  indx = elf_section_data (osec)->dynindx;			  BFD_ASSERT (indx > 0);			} 		      relocate = false;		      outrel.r_info = ELF64_R_INFO (indx, r_type); 		      outrel.r_addend = relocation + rela->r_addend; 		    }		}	      bfd_elf64_swap_reloca_out (output_bfd, &outrel,					(((Elf64_External_Rela *)					  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)		continue;	    }	  break;	default:	  break;	}      r = _bfd_final_link_relocate (howto, input_bfd, input_section,				    contents, rela->r_offset,				    relocation, rela->r_addend);      if (r != bfd_reloc_ok)	{	  switch (r)	    {	    default:	    case bfd_reloc_outofrange:	      abort ();	    case bfd_reloc_overflow:	      {		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)		      return false;		    if (*name == '\0')		      name = bfd_section_name (input_bfd, sec);		  }		if (! ((*info->callbacks->reloc_overflow)		       (info, name, howto->name, (bfd_vma) 0,			input_bfd, input_section, rela->r_offset)))		  return false;	      }	      break;	    }	}    }  return true;}/* Finish up dynamic symbol handling.  We set the contents of various   dynamic sections here.  */static booleanelf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)     bfd *output_bfd;     struct bfd_link_info *info;     struct elf_link_hash_entry *h;     Elf_Internal_Sym *sym;{  bfd *dynobj;  dynobj = elf_hash_table (info)->dynobj;  if (h->plt.offset != (bfd_vma) -1)    {      asection *splt;      asection *sgot;      asection *srela;      bfd_vma plt_index;      bfd_vma got_offset;      Elf_Internal_Rela rela;      /* This symbol has an entry in the procedure linkage table.  Set	 it up.	 */      BFD_ASSERT (h->dynindx != -1);      splt = bfd_get_section_by_name (dynobj, ".plt");      sgot = bfd_get_section_by_name (dynobj, ".got.plt");      srela = bfd_get_section_by_name (dynobj, ".rela.plt");      BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);      /* Get the index in the procedure linkage table which	 corresponds to this symbol.  This is the index of this symbol	 in all the symbols for which we are making plt entries.  The	 first entry in the procedure linkage table is reserved.  */      plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;      /* Get the offset into the .got table of the entry that	 corresponds to this function.	Each .got entry is GOT_ENTRY_SIZE	 bytes. The first three are reserved for the dynamic linker.  */      got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;      /* Fill in the entry in the procedure linkage table.  */      memcpy (splt->contents + h->plt.offset, elf64_x86_64_plt_entry,	      PLT_ENTRY_SIZE);      /* Insert the relocation positions of the plt section.  The magic	 numbers at the end of the statements are the positions of the	 relocations in the plt section.  */      /* Put offset for jmp *name@GOTPCREL(%rip), since the	 instruction uses 6 bytes, subtract this value.  */      bfd_put_32 (output_bfd,		      (sgot->output_section->vma		       + sgot->output_offset		       + got_offset		       - splt->output_section->vma		       - splt->output_offset		       - h->plt.offset		       - 6),		  splt->contents + h->plt.offset + 2);      /* Put relocation index.  */      bfd_put_32 (output_bfd, plt_index,		  splt->contents + h->plt.offset + 7);      /* Put offset for jmp .PLT0.  */      bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),		  splt->contents + h->plt.offset + 12);      /* Fill in the entry in the global offset table, initially this	 points to the pushq instruction in the PLT which is at offset 6.  */      bfd_put_64 (output_bfd, (splt->output_section->vma + splt->output_offset			       + h->plt.offset + 6),		  sgot->contents + got_offset);      /* Fill in the entry in the .rela.plt section.  */      rela.r_offset = (sgot->output_section->vma		       + sgot->output_offset		       + got_offset);      rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);      rela.r_addend = 0;      bfd_elf64_swap_reloca_out (output_bfd, &rela,				 ((Elf64_External_Rela *) srela->contents				  + plt_index));      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)	{	  /* Mark the symbol as undefined, rather than as defined in	     the .plt section.	Leave the value alone.	*/	  sym->st_shndx = SHN_UNDEF;	  /* If the symbol is weak, we do need to clear the value.	     Otherwise, the PLT entry would provide a definition for	     the symbol even if the symbol wasn't defined anywhere,	     and so the symbol would never be NULL.  */	  if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK)	      == 0)	    sym->st_value = 0;	}    }  if (h->got.offset != (bfd_vma) -1)    {      asection *sgot;      asection *srela;      Elf_Internal_Rela rela;      /* This symbol has an entry in the global offset table.  Set it         up.  */      sgot = bfd_get_section_by_name (dynobj, ".got");      srela = bfd_get_section_by_name (dynobj, ".rela.got");      BFD_ASSERT (sgot != NULL && srela != NULL);      rela.r_offset = (sgot->output_section->vma		       + sgot->output_offset		       + (h->got.offset &~ 1));      /* If this is a static link, or it is a -Bsymbolic link and the	 symbol is defined locally or was forced to be local because	 of a version file, we just want to emit a RELATIVE reloc.	 The entry in the global offset table will already have been	 initialized in the relocate_section function.  */      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)))	{	  BFD_ASSERT((h->got.offset & 1) != 0);	  rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);	  rela.r_addend = (h->root.u.def.value			   + h->root.u.def.section->output_section->vma			   + h->root.u.def.section->output_offset);	}      else	{	  BFD_ASSERT((h->got.offset & 1) == 0);	  bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);	  rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);	  rela.r_addend = 0;	}      bfd_elf64_swap_reloca_out (output_bfd, &rela,				 ((Elf64_External_Rela *) srela->contents				  + srela->reloc_count));      ++srela->reloc_count;    }  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)    {      asection *s;      Elf_Internal_Rela rela;      /* This symbol needs a copy reloc.  Set it up.  */      BFD_ASSERT (h->dynindx != -1		  && (h->root.type == bfd_link_hash_defined		      || h->root.type == bfd_link_hash_defweak));      s = bfd_get_section_by_name (h->root.u.def.section->owner,				   ".rela.bss");      BFD_ASSERT (s != NULL);      rela.r_offset = (h->root.u.def.value		       + h->root.u.def.section->output_section->vma		       + h->root.u.def.section->output_offset);      rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);      rela.r_addend = 0;      bfd_elf64_swap_reloca_out (output_bfd, &rela,				 ((Elf64_External_Rela *) s->contents				  + s->reloc_count));      ++s->reloc_count;    }  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */  if (strcmp (h->root.root.string, "_DYNAMIC") == 0      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)    sym->st_shndx = SHN_ABS;  return true;}/* Finish up the dynamic sections.  */static booleanelf64_x86_64_finish_dynamic_sections (output_bfd, info)     bfd *output_bfd;     struct bfd_link_info *info;{  bfd *dynobj;  asection *sdyn;  asection *sgot;  dynobj = elf_hash_table (info)->dynobj;  sgot = bfd_get_section_by_name (dynobj, ".got.plt");  BFD_ASSERT (sgot != NULL);  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");  if (elf_hash_table (info)->dynamic_sections_created)    {      asection *splt;      Elf64_External_Dyn *dyncon, *dynconend;      BFD_ASSERT (sdyn != NULL);      dyncon = (Elf64_External_Dyn *) sdyn->contents;      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);      for (; dyncon < dynconend; dyncon++)	{	  Elf_Internal_Dyn dyn;	  const char *name;	  asection *s;	  bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);	  switch (dyn.d_tag)	    {	    default:	      continue;	    case DT_PLTGOT:	      name = ".got";	      goto get_vma;	    case DT_JMPREL:	      name = ".rela.plt";	    get_vma:	      s = bfd_get_section_by_name (output_bfd, name);	      BFD_ASSERT (s != NULL);	      dyn.d_un.d_ptr = s->vma;	      break;	    case DT_RELASZ:	      /* FIXME: This comment and code is from elf64-alpha.c:  */	      /* My interpretation of the TIS v1.1 ELF document indicates		 that RELASZ should not include JMPREL.	 This is not what		 the rest of the BFD does.  It is, however, what the		 glibc ld.so wants.  Do this fixup here until we found		 out who is right.  */	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");	      if (s)		{		  /* Subtract JMPREL size from RELASZ.	*/		  dyn.d_un.d_val -=		    (s->_cooked_size ? s->_cooked_size : s->_raw_size);		}	      break;	    case DT_PLTRELSZ:	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");	      BFD_ASSERT (s != NULL);	      dyn.d_un.d_val =		(s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size);	      break;	    }	  bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);	}      /* Initialize the contents of the .plt section.  */      splt = bfd_get_section_by_name (dynobj, ".plt");      BFD_ASSERT (splt != NULL);      if (splt->_raw_size > 0)	{	  /* Fill in the first entry in the procedure linkage table.  */	  memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE);	  /* Add offset for pushq GOT+8(%rip), since the instruction	     uses 6 bytes subtract this value.  */	  bfd_put_32 (output_bfd,		      (sgot->output_section->vma		       + sgot->output_offset		       + 8		       - splt->output_section->vma		       - splt->output_offset		       - 6),		      splt->contents + 2);	  /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to	     the end of the instruction.  */	  bfd_put_32 (output_bfd,		      (sgot->output_section->vma		       + sgot->output_offset		       + 16		       - splt->output_section->vma		       - splt->output_offset		       - 12),		      splt->contents + 8);	}      elf_section_data (splt->output_section)->this_hdr.sh_entsize =	PLT_ENTRY_SIZE;    }  /* Set the first entry in the global offset table to the address of     the dynamic section.  */  if (sgot->_raw_size > 0)    {      if (sdyn == NULL)	bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents);      else	bfd_put_64 (output_bfd,		    sdyn->output_section->vma + sdyn->output_offset,		    sgot->contents);      /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */      bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE);      bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE*2);    }  elf_section_data (sgot->output_section)->this_hdr.sh_entsize =    GOT_ENTRY_SIZE;  return true;}#define TARGET_LITTLE_SYM		    bfd_elf64_x86_64_vec#define TARGET_LITTLE_NAME		    "elf64-x86-64"#define ELF_ARCH			    bfd_arch_i386#define ELF_MACHINE_CODE		    EM_X86_64#define ELF_MAXPAGESIZE			    0x100000#define elf_backend_can_gc_sections	    1#define elf_backend_want_got_plt	    1#define elf_backend_plt_readonly	    1#define elf_backend_want_plt_sym	    0#define elf_backend_got_header_size	    (GOT_ENTRY_SIZE*3)#define elf_backend_plt_header_size	    PLT_ENTRY_SIZE#define elf_info_to_howto		    elf64_x86_64_info_to_howto#define bfd_elf64_bfd_final_link	    _bfd_elf64_gc_common_final_link#define bfd_elf64_bfd_link_hash_table_create \  elf64_x86_64_link_hash_table_create#define bfd_elf64_bfd_reloc_type_lookup	    elf64_x86_64_reloc_type_lookup#define elf_backend_adjust_dynamic_symbol   elf64_x86_64_adjust_dynamic_symbol#define elf_backend_check_relocs	    elf64_x86_64_check_relocs#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections#define elf_backend_finish_dynamic_sections \  elf64_x86_64_finish_dynamic_sections#define elf_backend_finish_dynamic_symbol   elf64_x86_64_finish_dynamic_symbol#define elf_backend_gc_mark_hook	    elf64_x86_64_gc_mark_hook#define elf_backend_gc_sweep_hook	    elf64_x86_64_gc_sweep_hook#define elf_backend_relocate_section	    elf64_x86_64_relocate_section#define elf_backend_size_dynamic_sections   elf64_x86_64_size_dynamic_sections#define elf_backend_object_p		    elf64_x86_64_elf_object_p#include "elf64-target.h"

⌨️ 快捷键说明

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