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

📄 elf32-i386.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (ret != (struct elf_i386_link_hash_entry *) NULL)    {      ret->pcrel_relocs_copied = NULL;    }  return (struct bfd_hash_entry *) ret;}/* Create an i386 ELF linker hash table.  */static struct bfd_link_hash_table *elf_i386_link_hash_table_create (abfd)     bfd *abfd;{  struct elf_i386_link_hash_table *ret;  ret = ((struct elf_i386_link_hash_table *)	 bfd_alloc (abfd, sizeof (struct elf_i386_link_hash_table)));  if (ret == (struct elf_i386_link_hash_table *) NULL)    return NULL;  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,				       elf_i386_link_hash_newfunc))    {      bfd_release (abfd, ret);      return NULL;    }  return &ret->root.root;}/* Look through the relocs for a section during the first phase, and   allocate space in the global offset table or procedure linkage   table.  */static booleanelf_i386_check_relocs (abfd, info, sec, relocs)     bfd *abfd;     struct bfd_link_info *info;     asection *sec;     const Elf_Internal_Rela *relocs;{  bfd *dynobj;  Elf_Internal_Shdr *symtab_hdr;  struct elf_link_hash_entry **sym_hashes;  bfd_signed_vma *local_got_refcounts;  const Elf_Internal_Rela *rel;  const Elf_Internal_Rela *rel_end;  asection *sgot;  asection *srelgot;  asection *sreloc;  if (info->relocateable)    return true;  dynobj = elf_hash_table (info)->dynobj;  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;  sym_hashes = elf_sym_hashes (abfd);  local_got_refcounts = elf_local_got_refcounts (abfd);  sgot = NULL;  srelgot = NULL;  sreloc = NULL;  rel_end = relocs + sec->reloc_count;  for (rel = relocs; rel < rel_end; rel++)    {      unsigned long r_symndx;      struct elf_link_hash_entry *h;      r_symndx = ELF32_R_SYM (rel->r_info);      if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))	{	  if (abfd->my_archive)	    (*_bfd_error_handler) (_("%s(%s): bad symbol index: %d"),				   bfd_get_filename (abfd->my_archive),				   bfd_get_filename (abfd),				   r_symndx);	  else	    (*_bfd_error_handler) (_("%s: bad symbol index: %d"),				   bfd_get_filename (abfd),				   r_symndx);	  return false;	}      if (r_symndx < symtab_hdr->sh_info)	h = NULL;      else	h = sym_hashes[r_symndx - symtab_hdr->sh_info];      /* Some relocs require a global offset table.  */      if (dynobj == NULL)	{	  switch (ELF32_R_TYPE (rel->r_info))	    {	    case R_386_GOT32:	    case R_386_GOTOFF:	    case R_386_GOTPC:	      elf_hash_table (info)->dynobj = dynobj = abfd;	      if (! _bfd_elf_create_got_section (dynobj, info))		return false;	      break;	    default:	      break;	    }	}      switch (ELF32_R_TYPE (rel->r_info))	{	case R_386_GOT32:	  /* This symbol requires a global offset table entry.  */	  if (sgot == NULL)	    {	      sgot = bfd_get_section_by_name (dynobj, ".got");	      BFD_ASSERT (sgot != NULL);	    }	  if (srelgot == NULL	      && (h != NULL || info->shared))	    {	      srelgot = bfd_get_section_by_name (dynobj, ".rel.got");	      if (srelgot == NULL)		{		  srelgot = bfd_make_section (dynobj, ".rel.got");		  if (srelgot == NULL		      || ! bfd_set_section_flags (dynobj, srelgot,						  (SEC_ALLOC						   | SEC_LOAD						   | SEC_HAS_CONTENTS						   | SEC_IN_MEMORY						   | SEC_LINKER_CREATED						   | SEC_READONLY))		      || ! bfd_set_section_alignment (dynobj, srelgot, 2))		    return false;		}	    }	  if (h != NULL)	    {	      if (h->got.refcount == -1)		{		  h->got.refcount = 1;		  /* Make sure this symbol is output as a dynamic symbol.  */		  if (h->dynindx == -1)		    {		      if (! bfd_elf32_link_record_dynamic_symbol (info, h))			return false;		    }		  sgot->_raw_size += 4;		  srelgot->_raw_size += sizeof (Elf32_External_Rel);		}	      else		h->got.refcount += 1;	    }	  else	    {     	      /* This is a global offset table entry for a local symbol.  */	      if (local_got_refcounts == NULL)		{		  size_t size;		  size = symtab_hdr->sh_info * sizeof (bfd_signed_vma);		  local_got_refcounts = ((bfd_signed_vma *)					 bfd_alloc (abfd, size));		  if (local_got_refcounts == NULL)		    return false;		  elf_local_got_refcounts (abfd) = local_got_refcounts;		  memset (local_got_refcounts, -1, size);		}	      if (local_got_refcounts[r_symndx] == -1)		{		  local_got_refcounts[r_symndx] = 1;		  sgot->_raw_size += 4;		  if (info->shared)		    {		      /* If we are generating a shared object, we need to			 output a R_386_RELATIVE reloc so that the dynamic			 linker can adjust this GOT entry.  */		      srelgot->_raw_size += sizeof (Elf32_External_Rel);		    }		}	      else		local_got_refcounts[r_symndx] += 1;	    }	  break;	case R_386_PLT32:	  /* This symbol requires a procedure linkage table entry.  We             actually build the entry in adjust_dynamic_symbol,             because this might be a case of linking PIC code which is             never referenced by a dynamic object, in which case we             don't need to generate a procedure linkage table entry             after all.  */	  /* If this is a local symbol, we resolve it directly without             creating a procedure linkage table entry.  */	  if (h == NULL)	    continue;	  if (h->plt.refcount == -1)	    {	      h->plt.refcount = 1;	      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;	    }	  else	    h->plt.refcount += 1;	  break;	case R_386_32:	case R_386_PC32:	  if (h != NULL)	    h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;	  /* If we are creating a shared library, and this is a reloc	     against a global symbol, or a non PC relative reloc	     against a local symbol, then we need to copy the reloc	     into the shared library.  However, if we are linking with	     -Bsymbolic, we do not need to copy a reloc against a	     global symbol which is defined in an object we are	     including in the link (i.e., DEF_REGULAR is set).  At	     this point we have not seen all the input files, so it is	     possible that DEF_REGULAR is not set now but will be set	     later (it is never cleared).  In case of a weak definition,	     DEF_REGULAR may be cleared later by a strong definition in	     a shared library. We account for that possibility below by	     storing information in the relocs_copied field of the hash	     table entry.  A similar situation occurs when creating	     shared libraries and symbol visibility changes render the	     symbol local.  */	  if (info->shared	      && (sec->flags & SEC_ALLOC) != 0	      && (ELF32_R_TYPE (rel->r_info) != R_386_PC32		  || (h != NULL		      && (! info->symbolic			  || h->root.type == bfd_link_hash_defweak			  || (h->elf_link_hash_flags			      & ELF_LINK_HASH_DEF_REGULAR) == 0))))	    {	      /* When creating a shared object, we must copy these		 reloc types into the output file.  We create a reloc		 section in dynobj and make room for this reloc.  */	      if (sreloc == NULL)		{		  const char *name;		  name = (bfd_elf_string_from_elf_section			  (abfd,			   elf_elfheader (abfd)->e_shstrndx,			   elf_section_data (sec)->rel_hdr.sh_name));		  if (name == NULL)		    return false;		  if (strncmp (name, ".rel", 4) != 0		      || strcmp (bfd_get_section_name (abfd, sec),				 name + 4) != 0)		    {		      if (abfd->my_archive)			(*_bfd_error_handler) (_("%s(%s): bad relocation section name `%s\'"),					       bfd_get_filename (abfd->my_archive),					       bfd_get_filename (abfd),					       name);		      else			(*_bfd_error_handler) (_("%s: bad relocation section name `%s\'"),					       bfd_get_filename (abfd),					       name);		    }		  sreloc = bfd_get_section_by_name (dynobj, name);		  if (sreloc == NULL)		    {		      flagword flags;		      sreloc = bfd_make_section (dynobj, name);		      flags = (SEC_HAS_CONTENTS | SEC_READONLY			       | SEC_IN_MEMORY | SEC_LINKER_CREATED);		      if ((sec->flags & SEC_ALLOC) != 0)			flags |= SEC_ALLOC | SEC_LOAD;		      if (sreloc == NULL			  || ! bfd_set_section_flags (dynobj, sreloc, flags)			  || ! bfd_set_section_alignment (dynobj, sreloc, 2))			return false;		    }		}	      sreloc->_raw_size += sizeof (Elf32_External_Rel);	      /* If this is a global symbol, we count the number of PC		 relative relocations we have entered for this symbol,		 so that we can discard them later as necessary.  Note		 that this function is only called if we are using an		 elf_i386 linker hash table, which means that h is		 really a pointer to an elf_i386_link_hash_entry.  */	      if (h != NULL		  && ELF32_R_TYPE (rel->r_info) == R_386_PC32)		{		  struct elf_i386_link_hash_entry *eh;		  struct elf_i386_pcrel_relocs_copied *p;		  eh = (struct elf_i386_link_hash_entry *) h;		  for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)		    if (p->section == sreloc)		      break;		  if (p == NULL)		    {		      p = ((struct elf_i386_pcrel_relocs_copied *)			   bfd_alloc (dynobj, sizeof *p));		      if (p == NULL)			return false;		      p->next = eh->pcrel_relocs_copied;		      eh->pcrel_relocs_copied = p;		      p->section = sreloc;		      p->count = 0;		    }		  ++p->count;		}	    }	  break;	  /* This relocation describes the C++ object vtable hierarchy.	     Reconstruct it for later use during GC.  */	case R_386_GNU_VTINHERIT:	  if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))	    return false;	  break;	  /* This relocation describes which C++ vtable entries are actually	     used.  Record for later use during GC.  */	case R_386_GNU_VTENTRY:	  if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))	    return false;	  break;	default:	  break;	}    }  return true;}/* Return the section that should be marked against GC for a given   relocation.  */static asection *elf_i386_gc_mark_hook (abfd, info, rel, h, sym)     bfd *abfd;     struct bfd_link_info *info ATTRIBUTE_UNUSED;     Elf_Internal_Rela *rel;     struct elf_link_hash_entry *h;     Elf_Internal_Sym *sym;{  if (h != NULL)    {      switch (ELF32_R_TYPE (rel->r_info))	{	case R_386_GNU_VTINHERIT:	case R_386_GNU_VTENTRY:	  break;	default:	  switch (h->root.type)	    {	    case bfd_link_hash_defined:	    case bfd_link_hash_defweak:	      return h->root.u.def.section;	    case bfd_link_hash_common:	      return h->root.u.c.p->section;	    default:	      break;	    }	}    }  else    {      if (!(elf_bad_symtab (abfd)	    && ELF_ST_BIND (sym->st_info) != STB_LOCAL)	  && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)		&& sym->st_shndx != SHN_COMMON))	{	  return bfd_section_from_elf_index (abfd, sym->st_shndx);	}    }  return NULL;}/* Update the got entry reference counts for the section being removed.  */static booleanelf_i386_gc_sweep_hook (abfd, info, sec, relocs)     bfd *abfd;     struct bfd_link_info *info;     asection *sec;     const Elf_Internal_Rela *relocs;{  Elf_Internal_Shdr *symtab_hdr;  struct elf_link_hash_entry **sym_hashes;  bfd_signed_vma *local_got_refcounts;  const Elf_Internal_Rela *rel, *relend;  unsigned long r_symndx;  struct elf_link_hash_entry *h;  bfd *dynobj;  asection *sgot;  asection *srelgot;  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;  sym_hashes = elf_sym_hashes (abfd);  local_got_refcounts = elf_local_got_refcounts (abfd);  dynobj = elf_hash_table (info)->dynobj;  if (dynobj == NULL)    return true;  sgot = bfd_get_section_by_name (dynobj, ".got");  srelgot = bfd_get_section_by_name (dynobj, ".rel.got");  relend = relocs + sec->reloc_count;  for (rel = relocs; rel < relend; rel++)    switch (ELF32_R_TYPE (rel->r_info))

⌨️ 快捷键说明

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