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

📄 elf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Check to see if the core file could reasonably be expected to have   come for the current executable file.  Note that by default we return   true unless we find something that indicates that there might be a   problem.   */static booleanDEFUN(elf_core_file_matches_executable_p, (core_bfd, exec_bfd),      bfd *core_bfd AND      bfd *exec_bfd){#ifdef HAVE_PROCFS  char *corename;  char *execname;#endif  /* First, xvecs must match since both are ELF files for the same target. */  if (core_bfd->xvec != exec_bfd->xvec)    {      bfd_error = system_call_error;      return (false);    }#ifdef HAVE_PROCFS  /* If no prpsinfo, just return true.  Otherwise, grab the last component     of the exec'd pathname from the prpsinfo. */  if (core_prpsinfo (core_bfd))    {      corename = (((struct prpsinfo *) core_prpsinfo (core_bfd)) -> pr_fname);    }    else    {      return (true);    }  /* Find the last component of the executable pathname. */  if ((execname = strrchr (exec_bfd -> filename, '/')) != NULL)    {      execname++;    }  else    {      execname = (char *) exec_bfd -> filename;    }  /* See if they match */  return (strcmp (execname, corename) ? false : true);#else  return (true);#endif	/* HAVE_PROCFS */}/* ELF core files contain a segment of type PT_NOTE, that holds much of   the information that would normally be available from the /proc interface   for the process, at the time the process dumped core.  Currently this   includes copies of the prstatus, prpsinfo, and fpregset structures.   Since these structures are potentially machine dependent in size and   ordering, bfd provides two levels of support for them.  The first level,   available on all machines since it does not require that the host   have /proc support or the relevant include files, is to create a bfd   section for each of the prstatus, prpsinfo, and fpregset structures,   without any interpretation of their contents.  With just this support,   the bfd client will have to interpret the structures itself.  Even with   /proc support, it might want these full structures for it's own reasons.   In the second level of support, where HAVE_PROCFS is defined, bfd will   pick apart the structures to gather some additional information that   clients may want, such as the general register set, the name of the   exec'ed file and its arguments, the signal (if any) that caused the   core dump, etc.   */static booleanDEFUN(elf_corefile_note, (abfd, hdr),      bfd               *abfd AND      Elf_Internal_Phdr *hdr){  Elf_External_Note *x_note_p;	/* Elf note, external form */  Elf_Internal_Note i_note;	/* Elf note, internal form */  char *buf = NULL;		/* Entire note segment contents */  char *namedata;		/* Name portion of the note */  char *descdata;		/* Descriptor portion of the note */  char *sectname;		/* Name to use for new section */  long filepos;			/* File offset to descriptor data */  asection *newsect;  if (hdr -> p_filesz > 0      && (buf = (char *) bfd_xmalloc (hdr -> p_filesz)) != NULL      && bfd_seek (abfd, hdr -> p_offset, SEEK_SET) != -1      && bfd_read ((PTR) buf, hdr -> p_filesz, 1, abfd) == hdr -> p_filesz)    {      x_note_p = (Elf_External_Note *) buf;      while ((char *) x_note_p < (buf + hdr -> p_filesz))	{	  i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p -> namesz);	  i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p -> descsz);	  i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p -> type);	  namedata = x_note_p -> name;	  descdata = namedata + BFD_ALIGN (i_note.namesz, 4);	  filepos = hdr -> p_offset + (descdata - buf);	  switch (i_note.type) {	    case NT_PRSTATUS:	      /* process descdata as prstatus info */	      bfd_prstatus (abfd, descdata, i_note.descsz, filepos);	      sectname = ".prstatus";	      break;	    case NT_FPREGSET:	      /* process descdata as fpregset info */	      bfd_fpregset (abfd, descdata, i_note.descsz, filepos);	      sectname = ".fpregset";	      break;	    case NT_PRPSINFO:	      /* process descdata as prpsinfo */	      bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos);	      sectname = ".prpsinfo";	      break;	    default:	      /* Unknown descriptor, just ignore it. */	      sectname = NULL;	      break;	  }	  if (sectname != NULL)	    {	      newsect = bfd_make_section (abfd, sectname);	      newsect -> _raw_size = i_note.descsz;	      newsect -> filepos = filepos;	      newsect -> flags = SEC_ALLOC | SEC_HAS_CONTENTS;	      newsect -> alignment_power = 2;	    }	  x_note_p = (Elf_External_Note *)			(descdata + BFD_ALIGN (i_note.descsz, 4));	}    }  if (buf != NULL)    {      free (buf);    }  return true;  }/* 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 *DEFUN(elf_read, (abfd, offset, size),      bfd	*abfd AND      long	offset AND      int	size){  char *buf;  if ((buf = bfd_alloc (abfd, size)) == NULL)    {      bfd_error = no_memory;      return (NULL);    }  if (bfd_seek (abfd, offset, SEEK_SET) == -1)    {      bfd_error = system_call_error;      return (NULL);    }  if (bfd_read ((PTR) buf, size, 1, abfd) != size)    {      bfd_error = system_call_error;      return (NULL);    }  return (buf);}/* Begin processing a given object.   First we validate the file by reading in the ELF header and checking   the magic number.   */static bfd_target *DEFUN (elf_object_p, (abfd), bfd *abfd){  Elf_External_Ehdr x_ehdr;	/* Elf file header, external form */  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */  Elf_External_Shdr x_shdr;	/* Section header table entry, external form */  Elf_Internal_Shdr *i_shdrp;	/* Section header table, internal form */  int shindex;  char *shstrtab;		/* Internal copy of section header stringtab */    /* Read in the ELF header in external format.  */  if (bfd_read ((PTR) &x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))    {      bfd_error = system_call_error;      return (NULL);    }  /* Now check to see if we have a valid ELF file, and one that BFD can     make use of.  The magic number must match, the address size ('class')     and byte-swapping must match our XVEC entry, and it must have a     section header table (FIXME: See comments re sections at top of this     file). */  if (x_ehdr.e_ident[EI_MAG0] != ELFMAG0 ||      x_ehdr.e_ident[EI_MAG1] != ELFMAG1 ||      x_ehdr.e_ident[EI_MAG2] != ELFMAG2 ||      x_ehdr.e_ident[EI_MAG3] != ELFMAG3)    {wrong:      bfd_error = wrong_format;      return (NULL);    }  /* FIXME, Check EI_VERSION here !  */  switch (x_ehdr.e_ident[EI_CLASS])    {    case ELFCLASSNONE:		/* address size not specified */      goto wrong;		/* No support if can't tell address size */    case ELFCLASS32:		/* 32-bit addresses */      break;    case ELFCLASS64:		/* 64-bit addresses */      goto wrong;		/* FIXME: 64 bits not yet supported */    default:      goto wrong;		/* No support if unknown address class */    }  /* Switch xvec to match the specified byte order.  */  switch (x_ehdr.e_ident[EI_DATA])    {    case ELFDATA2MSB:		/* Big-endian */       if (!abfd->xvec->header_byteorder_big_p)	goto wrong;      break;    case ELFDATA2LSB:		/* Little-endian */      if (abfd->xvec->header_byteorder_big_p)	goto wrong;      break;    case ELFDATANONE:		/* No data encoding specified */    default:			/* Unknown data encoding specified */      goto wrong;    }    /* Allocate an instance of the elf_obj_tdata structure and hook it up to     the tdata pointer in the bfd. */  if (NULL == (elf_tdata (abfd) = (struct elf_obj_tdata *)               bfd_zalloc (abfd, sizeof (struct elf_obj_tdata))))    {      bfd_error = no_memory;      return (NULL);    }  /* FIXME:  Any `wrong' exits below here will leak memory (tdata).  */  /* Now that we know the byte order, swap in the rest of the header */  i_ehdrp = elf_elfheader (abfd);  elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);    /* If there is no section header table, we're hosed. */  if (i_ehdrp->e_shoff == 0)    goto wrong;  if (i_ehdrp->e_type == ET_EXEC || i_ehdrp->e_type == ET_DYN)    abfd -> flags |= EXEC_P;  switch (i_ehdrp->e_machine)    {    case EM_NONE:    case EM_M32:		/* or should this be bfd_arch_obscure? */      bfd_default_set_arch_mach(abfd, bfd_arch_unknown, 0);      break;    case EM_SPARC:      bfd_default_set_arch_mach(abfd, bfd_arch_sparc, 0);      break;    case EM_386:      bfd_default_set_arch_mach(abfd, bfd_arch_i386, 0);      break;    case EM_68K:      bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0);      break;    case EM_88K:      bfd_default_set_arch_mach(abfd, bfd_arch_m88k, 0);      break;    case EM_860:      bfd_default_set_arch_mach(abfd, bfd_arch_i860, 0);      break;    case EM_MIPS:      bfd_default_set_arch_mach(abfd, bfd_arch_mips, 0);      break;    default:      goto wrong;    }    /* Allocate space for a copy of the section header table in      internal form, seek to the section header table in the file,     read it in, and convert it to internal form.  As a simple sanity     check, verify that the what BFD thinks is the size of each section     header table entry actually matches the size recorded in the file. */  if (i_ehdrp->e_shentsize != sizeof (x_shdr))    goto wrong;  i_shdrp = (Elf_Internal_Shdr *)    bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum);  if (! i_shdrp)    {      bfd_error = no_memory;      return (NULL);    }  if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) == -1)    {      bfd_error = system_call_error;      return (NULL);    }  for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++)    {      if (bfd_read ((PTR) &x_shdr, sizeof x_shdr, 1, abfd)	  != sizeof (x_shdr))	{	  bfd_error = system_call_error;	  return (NULL);	}      elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);    }  elf_elfsections (abfd) = i_shdrp;    /* Read in the string table containing the names of the sections.  We     will need the base pointer to this table later. */  /* We read this inline now, so that we don't have to go through     bfd_section_from_shdr with it (since this particular strtab is     used to find all of the ELF section names.) */  shstrtab = elf_get_str_section (abfd, i_ehdrp->e_shstrndx);  if (! shstrtab)    return (NULL);    /* Once all of the section headers have been read and converted, we     can start processing them.  Note that the first section header is     a dummy placeholder entry, so we ignore it.     We also watch for the symbol table section and remember the file     offset and section size for both the symbol table section and the     associated string table section. */  for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)    {      bfd_section_from_shdr (abfd, shindex);    }  /* Remember the entry point specified in the ELF file header. */  bfd_get_start_address (abfd) = i_ehdrp->e_entry;  return (abfd->xvec);}/*  Core files are simply standard ELF formatted files that partition    the file using the execution view of the file (program header table)    rather than the linking view.  In fact, there is no section header    table in a core file.    The process status information (including the contents of the general    register set) and the floating point register set are stored in a    segment of type PT_NOTE.  We handcraft a couple of extra bfd sections    that allow standard bfd access to the general registers (.reg) and the    floating point registers (.reg2). */static bfd_target *DEFUN (elf_core_file_p, (abfd), bfd *abfd){  Elf_External_Ehdr x_ehdr;	/* Elf file header, external form */  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */  Elf_External_Phdr x_phdr;	/* Program header table entry, external form */  Elf_Internal_Phdr *i_phdrp;	/* Program header table, internal form */  unsigned int phindex;    /* Read in the ELF header in external format.  */  if (bfd_read ((PTR) &x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))    {      bfd_error = system_call_error;      return (NULL);    }  /* Now check to see if we have a valid ELF file, and one that BFD can     make use of.  The magic number must match, the address size ('class')     and byte-swapping must match our XVEC entry, and it must have a     program header table (FIXME: See comments re segments at top of this     file). */  if (x_ehdr.e_ident[EI_MAG0] != ELFMAG0 ||      x_ehdr.e_ident[EI_MAG1] != ELFMAG1 ||      x_ehdr.e_ident[EI_MAG2] != ELFMAG2 ||      x_ehdr.e_ident[EI_MAG3] != ELFMAG3)    {wrong:      bfd_error = wrong_format;      return (NULL);    }  /* FIXME, Check EI_VERSION here !  */  switch (x_ehdr.e_ident[EI_CLASS])    {    case ELFCLASSNONE:		/* address size not specified */      goto wrong;		/* No support if can't tell address size */    case ELFCLASS32:		/* 32-bit addresses */      break;    case ELFCLASS64:		/* 64-bit addresses */      goto wrong;		/* FIXME: 64 bits not yet supported */    default:      goto wrong;		/* No support if unknown address class */

⌨️ 快捷键说明

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