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

📄 elf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ELF executable support for BFD.   Copyright 1991, 1992 Free Software Foundation, Inc.   Written by Fred Fish @ Cygnus Support, from information published   in "UNIX System V Release 4, Programmers Guide: ANSI C and   Programming Support Tools".  Sufficient support for gdb.   Rewritten by Mark Eichin @ Cygnus Support, from information   published in "System V Application Binary Interface", chapters 4   and 5, as well as the various "Processor Supplement" documents   derived from it. Added support for assembler and other object file   utilities.   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., 675 Mass Ave, Cambridge, MA 02139, USA.  */	/****************************************	  		WARNING	This is only a partial ELF implementation,	incorporating only those parts that are	required to get gdb up and running.  It is	expected that it will be expanded to a full	ELF implementation at some future date.	Unimplemented stubs call abort() to ensure	that they get proper attention if they are	ever called.  The stubs are here since	this version was hacked from the COFF	version, and thus they will probably	go away or get expanded appropriately in a	future version.	fnf@cygnus.com	*****************************************//* Problems and other issues to resolve.   (1)	BFD expects there to be some fixed number of "sections" in        the object file.  I.E. there is a "section_count" variable in the	bfd structure which contains the number of sections.  However, ELF	supports multiple "views" of a file.  In particular, with current	implementations, executable files typically have two tables, a	program header table and a section header table, both of which	partition the executable.	In ELF-speak, the "linking view" of the file uses the section header	table to access "sections" within the file, and the "execution view"	uses the program header table to access "segments" within the file.	"Segments" typically may contain all the data from one or more	"sections".	Note that the section header table is optional in ELF executables,	but it is this information that is most useful to gdb.  If the	section header table is missing, then gdb should probably try	to make do with the program header table.  (FIXME)*/#include "bfd.h"#include "sysdep.h"#include "libbfd.h"#include "obstack.h"#include "elf/common.h"#include "elf/internal.h"#include "elf/external.h"#ifdef HAVE_PROCFS	/* Some core file support requires host /proc files */#include <sys/procfs.h>#else#define bfd_prstatus(abfd, descdata, descsz, filepos)	/* Define away */#define bfd_fpregset(abfd, descdata, descsz, filepos)	/* Define away */#define bfd_prpsinfo(abfd, descdata, descsz, filepos)	/* Define away */#endif/* Forward data declarations */extern bfd_target elf_little_vec, elf_big_vec;/* Currently the elf_symbol_type struct just contains the generic bfd   symbol structure. */typedef struct{  asymbol symbol;} elf_symbol_type;/* Some private data is stashed away for future use using the tdata pointer   in the bfd structure.  */struct elf_obj_tdata{  Elf_Internal_Ehdr elf_header[1];	/* Actual data, but ref like ptr */  Elf_Internal_Shdr *elf_sect_ptr;  struct strtab     *strtab_ptr;  int		    symtab_section;  void 		    *prstatus;		/* The raw /proc prstatus structure */  void 		    *prpsinfo;		/* The raw /proc prpsinfo structure */};#define elf_tdata(bfd)		((bfd) -> tdata.elf_obj_data)#define elf_elfheader(bfd)	(elf_tdata(bfd) -> elf_header)#define elf_elfsections(bfd)	(elf_tdata(bfd) -> elf_sect_ptr)#define elf_shstrtab(bfd)	(elf_tdata(bfd) -> strtab_ptr)#define elf_onesymtab(bfd)	(elf_tdata(bfd) -> symtab_section)#define core_prpsinfo(bfd)	(elf_tdata(bfd) -> prpsinfo)#define core_prstatus(bfd)	(elf_tdata(bfd) -> prstatus)/* Translate an ELF symbol in external format into an ELF symbol in internal   format. */static voidDEFUN(elf_swap_symbol_in,(abfd, src, dst),      bfd               *abfd AND      Elf_External_Sym *src AND      Elf_Internal_Sym *dst){  dst -> st_name = bfd_h_get_32 (abfd, (bfd_byte *) src -> st_name);  dst -> st_value = bfd_h_get_32 (abfd, (bfd_byte *) src -> st_value);  dst -> st_size = bfd_h_get_32 (abfd, (bfd_byte *) src -> st_size);  dst -> st_info = bfd_h_get_8 (abfd, (bfd_byte *) src -> st_info);  dst -> st_other = bfd_h_get_8 (abfd, (bfd_byte *) src -> st_other);  dst -> st_shndx = bfd_h_get_16 (abfd, (bfd_byte *) src -> st_shndx);}/* Translate an ELF symbol in internal format into an ELF symbol in external   format. */static voidDEFUN(elf_swap_symbol_out,(abfd, src, dst),      bfd               *abfd AND      Elf_Internal_Sym *src AND      Elf_External_Sym *dst){  bfd_h_put_32 (abfd, src->st_name, dst->st_name);  bfd_h_put_32 (abfd, src->st_value, dst->st_value);  bfd_h_put_32 (abfd, src->st_size, dst->st_size);  bfd_h_put_8  (abfd, src->st_info, dst->st_info);  bfd_h_put_8  (abfd, src->st_other, dst->st_other);  bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx);}/* Translate an ELF file header in external format into an ELF file header in   internal format. */static voidDEFUN(elf_swap_ehdr_in,(abfd, src, dst),      bfd               *abfd AND      Elf_External_Ehdr *src AND      Elf_Internal_Ehdr *dst){  memcpy (dst -> e_ident, src -> e_ident, EI_NIDENT);  dst -> e_type = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_type);  dst -> e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_machine);  dst -> e_version = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_version);  dst -> e_entry = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_entry);  dst -> e_phoff = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_phoff);  dst -> e_shoff = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_shoff);  dst -> e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src -> e_flags);  dst -> e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_ehsize);  dst -> e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_phentsize);  dst -> e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_phnum);  dst -> e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shentsize);  dst -> e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shnum);  dst -> e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src -> e_shstrndx);}/* Translate an ELF file header in internal format into an ELF file header in   external format. */static voidDEFUN(elf_swap_ehdr_out,(abfd, src, dst),      bfd               *abfd AND      Elf_Internal_Ehdr *src AND      Elf_External_Ehdr *dst){  memcpy (dst -> e_ident, src -> e_ident, EI_NIDENT);  /* note that all elements of dst are *arrays of unsigned char* already... */  bfd_h_put_16 (abfd, src->e_type, dst->e_type);  bfd_h_put_16 (abfd, src->e_machine, dst->e_machine);  bfd_h_put_32 (abfd, src->e_version, dst->e_version);  bfd_h_put_32 (abfd, src->e_entry, dst->e_entry);  bfd_h_put_32 (abfd, src->e_phoff, dst->e_phoff);  bfd_h_put_32 (abfd, src->e_shoff, dst->e_shoff);  bfd_h_put_32 (abfd, src->e_flags, dst->e_flags);  bfd_h_put_16 (abfd, src->e_ehsize, dst->e_ehsize);  bfd_h_put_16 (abfd, src->e_phentsize, dst->e_phentsize);  bfd_h_put_16 (abfd, src->e_phnum, dst->e_phnum);  bfd_h_put_16 (abfd, src->e_shentsize, dst->e_shentsize);  bfd_h_put_16 (abfd, src->e_shnum, dst->e_shnum);  bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx);}/* Translate an ELF section header table entry in external format into an   ELF section header table entry in internal format. */static voidDEFUN(elf_swap_shdr_in,(abfd, src, dst),      bfd               *abfd AND      Elf_External_Shdr *src AND      Elf_Internal_Shdr *dst){  dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name);  dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type);  dst->sh_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_flags);  dst->sh_addr = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_addr);  dst->sh_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_offset);  dst->sh_size = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_size);  dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link);  dst->sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_info);  dst->sh_addralign = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_addralign);  dst->sh_entsize = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_entsize);  /* we haven't done any processing on it yet, so... */  dst->rawdata = (void*)0;}/* Translate an ELF section header table entry in internal format into an   ELF section header table entry in external format. */static voidDEFUN(elf_swap_shdr_out,(abfd, src, dst),      bfd               *abfd AND      Elf_Internal_Shdr *src AND      Elf_External_Shdr *dst){  /* note that all elements of dst are *arrays of unsigned char* already... */  bfd_h_put_32 (abfd, src->sh_name, dst->sh_name);  bfd_h_put_32 (abfd, src->sh_type, dst->sh_type);  bfd_h_put_32 (abfd, src->sh_flags, dst->sh_flags);  bfd_h_put_32 (abfd, src->sh_addr, dst->sh_addr);  bfd_h_put_32 (abfd, src->sh_offset, dst->sh_offset);  bfd_h_put_32 (abfd, src->sh_size, dst->sh_size);  bfd_h_put_32 (abfd, src->sh_link, dst->sh_link);  bfd_h_put_32 (abfd, src->sh_info, dst->sh_info);  bfd_h_put_32 (abfd, src->sh_addralign, dst->sh_addralign);  bfd_h_put_32 (abfd, src->sh_entsize, dst->sh_entsize);}/* Translate an ELF program header table entry in external format into an   ELF program header table entry in internal format. */static voidDEFUN(elf_swap_phdr_in,(abfd, src, dst),      bfd               *abfd AND      Elf_External_Phdr *src AND      Elf_Internal_Phdr *dst){  dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type);  dst->p_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->p_offset);  dst->p_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) src->p_vaddr);  dst->p_paddr = bfd_h_get_32 (abfd, (bfd_byte *) src->p_paddr);  dst->p_filesz = bfd_h_get_32 (abfd, (bfd_byte *) src->p_filesz);  dst->p_memsz = bfd_h_get_32 (abfd, (bfd_byte *) src->p_memsz);  dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags);  dst->p_align = bfd_h_get_32 (abfd, (bfd_byte *) src->p_align);}/* Translate an ELF reloc from external format to internal format. */static voidDEFUN(elf_swap_reloc_in,(abfd, src, dst),      bfd            *abfd AND      Elf_External_Rel *src AND      Elf_Internal_Rel *dst){  dst->r_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->r_offset);  dst->r_info = bfd_h_get_32 (abfd, (bfd_byte *) src->r_info);}static voidDEFUN(elf_swap_reloca_in,(abfd, src, dst),      bfd            *abfd AND      Elf_External_Rela *src AND      Elf_Internal_Rela *dst){  dst->r_offset = bfd_h_get_32 (abfd, (bfd_byte *) src->r_offset);  dst->r_info = bfd_h_get_32 (abfd, (bfd_byte *) src->r_info);  dst->r_addend = bfd_h_get_32 (abfd, (bfd_byte *) src->r_addend);}/* Translate an ELF reloc from internal format to external format. */static voidDEFUN(elf_swap_reloc_out,(abfd, src, dst),      bfd            *abfd AND      Elf_Internal_Rel *src AND      Elf_External_Rel *dst){  bfd_h_put_32 (abfd, src->r_offset, dst->r_offset);  bfd_h_put_32 (abfd, src->r_info, dst->r_info);}static voidDEFUN(elf_swap_reloca_out,(abfd, src, dst),      bfd            *abfd AND      Elf_Internal_Rela *src AND      Elf_External_Rela *dst){  bfd_h_put_32 (abfd, src->r_offset, dst->r_offset);  bfd_h_put_32 (abfd, src->r_info, dst->r_info);  bfd_h_put_32 (abfd, src->r_addend, dst->r_addend);}static char *EXFUN(elf_read, (bfd *, long, int));static struct sec * EXFUN(section_from_elf_index, (bfd *, int));static int EXFUN(elf_section_from_bfd_section, (bfd *, struct sec *));static boolean EXFUN(elf_slurp_symbol_table, (bfd *, asymbol **));static void EXFUN(elf_info_to_howto, (bfd *, arelent *, Elf_Internal_Rela *));static char *EXFUN(elf_get_str_section, (bfd *, unsigned int));     /* INTERNAL_FUNCTION	bfd_elf_find_sectionSYNOPSIS	struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);DESCRIPTION	Helper functions for GDB to locate the string tables.	Since BFD hides string tables from callers, GDB needs to use an	internal hook to find them.  Sun's .stabstr, in particular,	isn't even pointed to by the .stab section, so ordinary	mechanisms wouldn't work to find it, even if we had some.*/struct elf_internal_shdr *DEFUN(bfd_elf_find_section, (abfd, name),      bfd		*abfd AND      char		*name){  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  char *shstrtab = elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx);  unsigned int max = elf_elfheader (abfd)->e_shnum;  unsigned int i;  for (i = 1; i < max; i++)    if (!strcmp (&shstrtab[i_shdrp[i].sh_name], name))      return &i_shdrp[i];  return 0;}/* End of GDB support.  */static char *DEFUN(elf_get_str_section, (abfd, shindex),      bfd		*abfd AND      unsigned int	shindex){  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  unsigned int shstrtabsize = i_shdrp[shindex].sh_size;  unsigned int offset = i_shdrp[shindex].sh_offset;  char *shstrtab = i_shdrp[shindex].rawdata;  if (shstrtab)    return shstrtab;  if ((shstrtab = elf_read (abfd, offset, shstrtabsize)) == NULL)    {      return (NULL);    }  i_shdrp[shindex].rawdata = (void*)shstrtab;  return shstrtab;}static char *DEFUN(elf_string_from_elf_section, (abfd, shindex, strindex),      bfd		*abfd AND      unsigned int	shindex AND      unsigned int	strindex){  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  Elf_Internal_Shdr *hdr = i_shdrp + shindex;  if (! hdr->rawdata)    {      if (elf_get_str_section (abfd, shindex) == NULL)	{	  return NULL;	}    }  return ((char*)hdr->rawdata)+strindex;}#define elf_string_from_elf_strtab(abfd, strindex) \  elf_string_from_elf_section (abfd, elf_elfheader(abfd)->e_shstrndx, strindex)/* Create a new bfd section from an ELF section header. */static booleanDEFUN(bfd_section_from_shdr, (abfd, shindex),      bfd               *abfd AND      unsigned int	shindex){  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  Elf_Internal_Shdr *hdr = i_shdrp + shindex;  asection *newsect;  char *name;  name = hdr->sh_name ?    elf_string_from_elf_strtab (abfd, hdr->sh_name) : "unnamed";  switch(hdr->sh_type) {  case SHT_NULL:    /* inactive section. Throw it away. */    return true;

⌨️ 快捷键说明

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