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

📄 elf.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ELF executable support for BFD.   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.This file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//*SECTION	ELF backends	BFD support for ELF formats is being worked on.	Currently, the best supported back ends are for sparc and i386	(running svr4 or Solaris 2).	Documentation of the internals of the support code still needs	to be written.  The code is changing quickly enough that we	haven't bothered yet. *//* For sparc64-cross-sparc32.  */#define _SYSCALL32#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#define ARCH_SIZE 0#include "elf-bfd.h"static INLINE struct elf_segment_map *make_mapping  PARAMS ((bfd *, asection **, unsigned int, unsigned int, boolean));static boolean map_sections_to_segments PARAMS ((bfd *));static int elf_sort_sections PARAMS ((const PTR, const PTR));static boolean assign_file_positions_for_segments PARAMS ((bfd *));static boolean assign_file_positions_except_relocs PARAMS ((bfd *));static boolean prep_headers PARAMS ((bfd *));static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **, int));static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *));static char *elf_read PARAMS ((bfd *, long, unsigned int));static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));static boolean assign_section_numbers PARAMS ((bfd *));static INLINE int sym_is_global PARAMS ((bfd *, asymbol *));static boolean elf_map_symbols PARAMS ((bfd *));static bfd_size_type get_program_header_size PARAMS ((bfd *));static boolean elfcore_read_notes PARAMS ((bfd *, bfd_vma, bfd_vma));static boolean elf_find_function PARAMS ((bfd *, asection *,                                         asymbol **,                                         bfd_vma, const char **,                                         const char **));/* Swap version information in and out.  The version information is   currently size independent.  If that ever changes, this code will   need to move into elfcode.h.  *//* Swap in a Verdef structure.  */void_bfd_elf_swap_verdef_in (abfd, src, dst)     bfd *abfd;     const Elf_External_Verdef *src;     Elf_Internal_Verdef *dst;{  dst->vd_version = bfd_h_get_16 (abfd, src->vd_version);  dst->vd_flags   = bfd_h_get_16 (abfd, src->vd_flags);  dst->vd_ndx     = bfd_h_get_16 (abfd, src->vd_ndx);  dst->vd_cnt     = bfd_h_get_16 (abfd, src->vd_cnt);  dst->vd_hash    = bfd_h_get_32 (abfd, src->vd_hash);  dst->vd_aux     = bfd_h_get_32 (abfd, src->vd_aux);  dst->vd_next    = bfd_h_get_32 (abfd, src->vd_next);}/* Swap out a Verdef structure.  */void_bfd_elf_swap_verdef_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Verdef *src;     Elf_External_Verdef *dst;{  bfd_h_put_16 (abfd, src->vd_version, dst->vd_version);  bfd_h_put_16 (abfd, src->vd_flags, dst->vd_flags);  bfd_h_put_16 (abfd, src->vd_ndx, dst->vd_ndx);  bfd_h_put_16 (abfd, src->vd_cnt, dst->vd_cnt);  bfd_h_put_32 (abfd, src->vd_hash, dst->vd_hash);  bfd_h_put_32 (abfd, src->vd_aux, dst->vd_aux);  bfd_h_put_32 (abfd, src->vd_next, dst->vd_next);}/* Swap in a Verdaux structure.  */void_bfd_elf_swap_verdaux_in (abfd, src, dst)     bfd *abfd;     const Elf_External_Verdaux *src;     Elf_Internal_Verdaux *dst;{  dst->vda_name = bfd_h_get_32 (abfd, src->vda_name);  dst->vda_next = bfd_h_get_32 (abfd, src->vda_next);}/* Swap out a Verdaux structure.  */void_bfd_elf_swap_verdaux_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Verdaux *src;     Elf_External_Verdaux *dst;{  bfd_h_put_32 (abfd, src->vda_name, dst->vda_name);  bfd_h_put_32 (abfd, src->vda_next, dst->vda_next);}/* Swap in a Verneed structure.  */void_bfd_elf_swap_verneed_in (abfd, src, dst)     bfd *abfd;     const Elf_External_Verneed *src;     Elf_Internal_Verneed *dst;{  dst->vn_version = bfd_h_get_16 (abfd, src->vn_version);  dst->vn_cnt     = bfd_h_get_16 (abfd, src->vn_cnt);  dst->vn_file    = bfd_h_get_32 (abfd, src->vn_file);  dst->vn_aux     = bfd_h_get_32 (abfd, src->vn_aux);  dst->vn_next    = bfd_h_get_32 (abfd, src->vn_next);}/* Swap out a Verneed structure.  */void_bfd_elf_swap_verneed_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Verneed *src;     Elf_External_Verneed *dst;{  bfd_h_put_16 (abfd, src->vn_version, dst->vn_version);  bfd_h_put_16 (abfd, src->vn_cnt, dst->vn_cnt);  bfd_h_put_32 (abfd, src->vn_file, dst->vn_file);  bfd_h_put_32 (abfd, src->vn_aux, dst->vn_aux);  bfd_h_put_32 (abfd, src->vn_next, dst->vn_next);}/* Swap in a Vernaux structure.  */void_bfd_elf_swap_vernaux_in (abfd, src, dst)     bfd *abfd;     const Elf_External_Vernaux *src;     Elf_Internal_Vernaux *dst;{  dst->vna_hash  = bfd_h_get_32 (abfd, src->vna_hash);  dst->vna_flags = bfd_h_get_16 (abfd, src->vna_flags);  dst->vna_other = bfd_h_get_16 (abfd, src->vna_other);  dst->vna_name  = bfd_h_get_32 (abfd, src->vna_name);  dst->vna_next  = bfd_h_get_32 (abfd, src->vna_next);}/* Swap out a Vernaux structure.  */void_bfd_elf_swap_vernaux_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Vernaux *src;     Elf_External_Vernaux *dst;{  bfd_h_put_32 (abfd, src->vna_hash, dst->vna_hash);  bfd_h_put_16 (abfd, src->vna_flags, dst->vna_flags);  bfd_h_put_16 (abfd, src->vna_other, dst->vna_other);  bfd_h_put_32 (abfd, src->vna_name, dst->vna_name);  bfd_h_put_32 (abfd, src->vna_next, dst->vna_next);}/* Swap in a Versym structure.  */void_bfd_elf_swap_versym_in (abfd, src, dst)     bfd *abfd;     const Elf_External_Versym *src;     Elf_Internal_Versym *dst;{  dst->vs_vers = bfd_h_get_16 (abfd, src->vs_vers);}/* Swap out a Versym structure.  */void_bfd_elf_swap_versym_out (abfd, src, dst)     bfd *abfd;     const Elf_Internal_Versym *src;     Elf_External_Versym *dst;{  bfd_h_put_16 (abfd, src->vs_vers, dst->vs_vers);}/* Standard ELF hash function.  Do not change this function; you will   cause invalid hash tables to be generated.  */unsigned longbfd_elf_hash (namearg)     const char *namearg;{  const unsigned char *name = (const unsigned char *) namearg;  unsigned long h = 0;  unsigned long g;  int ch;  while ((ch = *name++) != '\0')    {      h = (h << 4) + ch;      if ((g = (h & 0xf0000000)) != 0)	{	  h ^= g >> 24;	  /* The ELF ABI says `h &= ~g', but this is equivalent in	     this case and on some machines one insn instead of two.  */	  h ^= g;	}    }  return h;}/* Read a specified number of bytes at a specified offset in an ELF   file, into a newly allocated buffer, and return a pointer to the   buffer.  */static char *elf_read (abfd, offset, size)     bfd *abfd;     long offset;     unsigned int size;{  char *buf;  if ((buf = bfd_alloc (abfd, size)) == NULL)    return NULL;  if (bfd_seek (abfd, offset, SEEK_SET) == -1)    return NULL;  if (bfd_read ((PTR) buf, size, 1, abfd) != size)    {      if (bfd_get_error () != bfd_error_system_call)	bfd_set_error (bfd_error_file_truncated);      return NULL;    }  return buf;}booleanbfd_elf_mkobject (abfd)     bfd *abfd;{  /* This just does initialization.  */  /* coff_mkobject zalloc's space for tdata.coff_obj_data ...  */  elf_tdata (abfd) = (struct elf_obj_tdata *)    bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));  if (elf_tdata (abfd) == 0)    return false;  /* Since everything is done at close time, do we need any     initialization?  */  return true;}booleanbfd_elf_mkcorefile (abfd)     bfd *abfd;{  /* I think this can be done just like an object file.  */  return bfd_elf_mkobject (abfd);}char *bfd_elf_get_str_section (abfd, shindex)     bfd *abfd;     unsigned int shindex;{  Elf_Internal_Shdr **i_shdrp;  char *shstrtab = NULL;  unsigned int offset;  unsigned int shstrtabsize;  i_shdrp = elf_elfsections (abfd);  if (i_shdrp == 0 || i_shdrp[shindex] == 0)    return 0;  shstrtab = (char *) i_shdrp[shindex]->contents;  if (shstrtab == NULL)    {      /* No cached one, attempt to read, and cache what we read.  */      offset = i_shdrp[shindex]->sh_offset;      shstrtabsize = i_shdrp[shindex]->sh_size;      shstrtab = elf_read (abfd, offset, shstrtabsize);      i_shdrp[shindex]->contents = (PTR) shstrtab;    }  return shstrtab;}char *bfd_elf_string_from_elf_section (abfd, shindex, strindex)     bfd *abfd;     unsigned int shindex;     unsigned int strindex;{  Elf_Internal_Shdr *hdr;  if (strindex == 0)    return "";  hdr = elf_elfsections (abfd)[shindex];  if (hdr->contents == NULL      && bfd_elf_get_str_section (abfd, shindex) == NULL)    return NULL;  if (strindex >= hdr->sh_size)    {      (*_bfd_error_handler)	(_("%s: invalid string offset %u >= %lu for section `%s'"),	 bfd_get_filename (abfd), strindex, (unsigned long) hdr->sh_size,	 ((shindex == elf_elfheader(abfd)->e_shstrndx	   && strindex == hdr->sh_name)	  ? ".shstrtab"	  : elf_string_from_elf_strtab (abfd, hdr->sh_name)));      return "";    }  return ((char *) hdr->contents) + strindex;}/* Make a BFD section from an ELF section.  We store a pointer to the   BFD section in the bfd_section field of the header.  */boolean_bfd_elf_make_section_from_shdr (abfd, hdr, name)     bfd *abfd;     Elf_Internal_Shdr *hdr;     const char *name;{  asection *newsect;  flagword flags;  struct elf_backend_data *bed;  if (hdr->bfd_section != NULL)    {      BFD_ASSERT (strcmp (name,			  bfd_get_section_name (abfd, hdr->bfd_section)) == 0);      return true;    }  newsect = bfd_make_section_anyway (abfd, name);  if (newsect == NULL)    return false;  newsect->filepos = hdr->sh_offset;  if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)      || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)      || ! bfd_set_section_alignment (abfd, newsect,				      bfd_log2 (hdr->sh_addralign)))    return false;  flags = SEC_NO_FLAGS;  if (hdr->sh_type != SHT_NOBITS)    flags |= SEC_HAS_CONTENTS;  if ((hdr->sh_flags & SHF_ALLOC) != 0)    {      flags |= SEC_ALLOC;      if (hdr->sh_type != SHT_NOBITS)	flags |= SEC_LOAD;    }  if ((hdr->sh_flags & SHF_WRITE) == 0)    flags |= SEC_READONLY;  if ((hdr->sh_flags & SHF_EXECINSTR) != 0)    flags |= SEC_CODE;  else if ((flags & SEC_LOAD) != 0)    flags |= SEC_DATA;  /* The debugging sections appear to be recognized only by name, not     any sort of flag.  */  {    static const char *debug_sec_names [] =    {      ".debug",      ".gnu.linkonce.wi.",      ".line",      ".stab"    };    int i;    for (i = sizeof (debug_sec_names) / sizeof (debug_sec_names[0]); i--;)      if (strncmp (name, debug_sec_names[i], strlen (debug_sec_names[i])) == 0)	break;    if (i >= 0)      flags |= SEC_DEBUGGING;  }  /* As a GNU extension, if the name begins with .gnu.linkonce, we     only link a single copy of the section.  This is used to support     g++.  g++ will emit each template expansion in its own section.     The symbols will be defined as weak, so that multiple definitions     are permitted.  The GNU linker extension is to actually discard     all but one of the sections.  */  if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0)    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;  bed = get_elf_backend_data (abfd);  if (bed->elf_backend_section_flags)    if (! bed->elf_backend_section_flags (&flags, hdr))      return false;  if (! bfd_set_section_flags (abfd, newsect, flags))    return false;  if ((flags & SEC_ALLOC) != 0)    {      Elf_Internal_Phdr *phdr;      unsigned int i;      /* Look through the phdrs to see if we need to adjust the lma.         If all the p_paddr fields are zero, we ignore them, since         some ELF linkers produce such output.  */      phdr = elf_tdata (abfd)->phdr;      for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)	{	  if (phdr->p_paddr != 0)	    break;	}      if (i < elf_elfheader (abfd)->e_phnum)	{	  phdr = elf_tdata (abfd)->phdr;	  for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)	    {	      if (phdr->p_type == PT_LOAD		  && phdr->p_vaddr != phdr->p_paddr		  && phdr->p_vaddr <= hdr->sh_addr		  && (phdr->p_vaddr + phdr->p_memsz		      >= hdr->sh_addr + hdr->sh_size)		  && ((flags & SEC_LOAD) == 0		      || (phdr->p_offset <= (bfd_vma) hdr->sh_offset			  && (phdr->p_offset + phdr->p_filesz			      >= hdr->sh_offset + hdr->sh_size))))

⌨️ 快捷键说明

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