OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [elfcore.h] - Diff between revs 816 and 818

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 816 Rev 818
/* ELF core file support for BFD.
/* ELF core file support for BFD.
   Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007,
   Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007,
   2008 Free Software Foundation, Inc.
   2008 Free Software Foundation, Inc.
 
 
   This file is part of BFD, the Binary File Descriptor library.
   This file is part of BFD, the Binary File Descriptor library.
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
char*
char*
elf_core_file_failing_command (bfd *abfd)
elf_core_file_failing_command (bfd *abfd)
{
{
  return elf_tdata (abfd)->core_command;
  return elf_tdata (abfd)->core_command;
}
}
 
 
int
int
elf_core_file_failing_signal (bfd *abfd)
elf_core_file_failing_signal (bfd *abfd)
{
{
  return elf_tdata (abfd)->core_signal;
  return elf_tdata (abfd)->core_signal;
}
}
 
 
bfd_boolean
bfd_boolean
elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
{
{
  char* corename;
  char* corename;
 
 
  /* xvecs must match if both are ELF files for the same target.  */
  /* xvecs must match if both are ELF files for the same target.  */
 
 
  if (core_bfd->xvec != exec_bfd->xvec)
  if (core_bfd->xvec != exec_bfd->xvec)
    {
    {
      bfd_set_error (bfd_error_system_call);
      bfd_set_error (bfd_error_system_call);
      return FALSE;
      return FALSE;
    }
    }
 
 
  /* See if the name in the corefile matches the executable name.  */
  /* See if the name in the corefile matches the executable name.  */
  corename = elf_tdata (core_bfd)->core_program;
  corename = elf_tdata (core_bfd)->core_program;
  if (corename != NULL)
  if (corename != NULL)
    {
    {
      const char* execname = strrchr (exec_bfd->filename, '/');
      const char* execname = strrchr (exec_bfd->filename, '/');
 
 
      execname = execname ? execname + 1 : exec_bfd->filename;
      execname = execname ? execname + 1 : exec_bfd->filename;
 
 
      if (strcmp (execname, corename) != 0)
      if (strcmp (execname, corename) != 0)
        return FALSE;
        return FALSE;
    }
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/*  Core files are simply standard ELF formatted files that partition
/*  Core files are simply standard ELF formatted files that partition
    the file using the execution view of the file (program header table)
    the file using the execution view of the file (program header table)
    rather than the linking view.  In fact, there is no section header
    rather than the linking view.  In fact, there is no section header
    table in a core file.
    table in a core file.
 
 
    The process status information (including the contents of the general
    The process status information (including the contents of the general
    register set) and the floating point register set are stored in a
    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
    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
    that allow standard bfd access to the general registers (.reg) and the
    floating point registers (.reg2).  */
    floating point registers (.reg2).  */
 
 
const bfd_target *
const bfd_target *
elf_core_file_p (bfd *abfd)
elf_core_file_p (bfd *abfd)
{
{
  Elf_External_Ehdr x_ehdr;     /* Elf file header, external form.  */
  Elf_External_Ehdr x_ehdr;     /* Elf file header, external form.  */
  Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form.  */
  Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form.  */
  Elf_Internal_Phdr *i_phdrp;   /* Elf program header, internal form.  */
  Elf_Internal_Phdr *i_phdrp;   /* Elf program header, internal form.  */
  unsigned int phindex;
  unsigned int phindex;
  const struct elf_backend_data *ebd;
  const struct elf_backend_data *ebd;
  struct bfd_preserve preserve;
  struct bfd_preserve preserve;
  bfd_size_type amt;
  bfd_size_type amt;
 
 
  preserve.marker = NULL;
  preserve.marker = NULL;
 
 
  /* Read in the ELF header in external format.  */
  /* Read in the ELF header in external format.  */
  if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
  if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
    {
    {
      if (bfd_get_error () != bfd_error_system_call)
      if (bfd_get_error () != bfd_error_system_call)
        goto wrong;
        goto wrong;
      else
      else
        goto fail;
        goto fail;
    }
    }
 
 
  /* Check the magic number.  */
  /* Check the magic number.  */
  if (! elf_file_p (&x_ehdr))
  if (! elf_file_p (&x_ehdr))
    goto wrong;
    goto wrong;
 
 
  /* FIXME: Check EI_VERSION here !  */
  /* FIXME: Check EI_VERSION here !  */
 
 
  /* Check the address size ("class").  */
  /* Check the address size ("class").  */
  if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
  if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
    goto wrong;
    goto wrong;
 
 
  /* Check the byteorder.  */
  /* Check the byteorder.  */
  switch (x_ehdr.e_ident[EI_DATA])
  switch (x_ehdr.e_ident[EI_DATA])
    {
    {
    case ELFDATA2MSB:           /* Big-endian.  */
    case ELFDATA2MSB:           /* Big-endian.  */
      if (! bfd_big_endian (abfd))
      if (! bfd_big_endian (abfd))
        goto wrong;
        goto wrong;
      break;
      break;
    case ELFDATA2LSB:           /* Little-endian.  */
    case ELFDATA2LSB:           /* Little-endian.  */
      if (! bfd_little_endian (abfd))
      if (! bfd_little_endian (abfd))
        goto wrong;
        goto wrong;
      break;
      break;
    default:
    default:
      goto wrong;
      goto wrong;
    }
    }
 
 
  if (!bfd_preserve_save (abfd, &preserve))
  if (!bfd_preserve_save (abfd, &preserve))
    goto fail;
    goto fail;
 
 
  /* Give abfd an elf_obj_tdata.  */
  /* Give abfd an elf_obj_tdata.  */
  if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
  if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
    goto fail;
    goto fail;
  preserve.marker = elf_tdata (abfd);
  preserve.marker = elf_tdata (abfd);
 
 
  /* Swap in the rest of the header, now that we have the byte order.  */
  /* Swap in the rest of the header, now that we have the byte order.  */
  i_ehdrp = elf_elfheader (abfd);
  i_ehdrp = elf_elfheader (abfd);
  elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
  elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
 
 
#if DEBUG & 1
#if DEBUG & 1
  elf_debug_file (i_ehdrp);
  elf_debug_file (i_ehdrp);
#endif
#endif
 
 
  ebd = get_elf_backend_data (abfd);
  ebd = get_elf_backend_data (abfd);
 
 
  /* Check that the ELF e_machine field matches what this particular
  /* Check that the ELF e_machine field matches what this particular
     BFD format expects.  */
     BFD format expects.  */
 
 
  if (ebd->elf_machine_code != i_ehdrp->e_machine
  if (ebd->elf_machine_code != i_ehdrp->e_machine
      && (ebd->elf_machine_alt1 == 0
      && (ebd->elf_machine_alt1 == 0
          || i_ehdrp->e_machine != ebd->elf_machine_alt1)
          || i_ehdrp->e_machine != ebd->elf_machine_alt1)
      && (ebd->elf_machine_alt2 == 0
      && (ebd->elf_machine_alt2 == 0
          || i_ehdrp->e_machine != ebd->elf_machine_alt2))
          || i_ehdrp->e_machine != ebd->elf_machine_alt2))
    {
    {
      const bfd_target * const *target_ptr;
      const bfd_target * const *target_ptr;
 
 
      if (ebd->elf_machine_code != EM_NONE)
      if (ebd->elf_machine_code != EM_NONE)
        goto wrong;
        goto wrong;
 
 
      /* This is the generic ELF target.  Let it match any ELF target
      /* This is the generic ELF target.  Let it match any ELF target
         for which we do not have a specific backend.  */
         for which we do not have a specific backend.  */
 
 
      for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
      for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
        {
        {
          const struct elf_backend_data *back;
          const struct elf_backend_data *back;
 
 
          if ((*target_ptr)->flavour != bfd_target_elf_flavour)
          if ((*target_ptr)->flavour != bfd_target_elf_flavour)
            continue;
            continue;
          back = xvec_get_elf_backend_data (*target_ptr);
          back = xvec_get_elf_backend_data (*target_ptr);
          if (back->s->arch_size != ARCH_SIZE)
          if (back->s->arch_size != ARCH_SIZE)
            continue;
            continue;
          if (back->elf_machine_code == i_ehdrp->e_machine
          if (back->elf_machine_code == i_ehdrp->e_machine
              || (back->elf_machine_alt1 != 0
              || (back->elf_machine_alt1 != 0
                  && i_ehdrp->e_machine == back->elf_machine_alt1)
                  && i_ehdrp->e_machine == back->elf_machine_alt1)
              || (back->elf_machine_alt2 != 0
              || (back->elf_machine_alt2 != 0
                  && i_ehdrp->e_machine == back->elf_machine_alt2))
                  && i_ehdrp->e_machine == back->elf_machine_alt2))
            {
            {
              /* target_ptr is an ELF backend which matches this
              /* target_ptr is an ELF backend which matches this
                 object file, so reject the generic ELF target.  */
                 object file, so reject the generic ELF target.  */
              goto wrong;
              goto wrong;
            }
            }
        }
        }
    }
    }
 
 
  /* If there is no program header, or the type is not a core file, then
  /* If there is no program header, or the type is not a core file, then
     we are hosed.  */
     we are hosed.  */
  if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
  if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
    goto wrong;
    goto wrong;
 
 
  /* Does BFD's idea of the phdr size match the size
  /* Does BFD's idea of the phdr size match the size
     recorded in the file? */
     recorded in the file? */
  if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
  if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
    goto wrong;
    goto wrong;
 
 
  /* Move to the start of the program headers.  */
  /* Move to the start of the program headers.  */
  if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
  if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
    goto wrong;
    goto wrong;
 
 
  /* Allocate space for the program headers.  */
  /* Allocate space for the program headers.  */
  amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
  amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
  i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
  i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
  if (!i_phdrp)
  if (!i_phdrp)
    goto fail;
    goto fail;
 
 
  elf_tdata (abfd)->phdr = i_phdrp;
  elf_tdata (abfd)->phdr = i_phdrp;
 
 
  /* Read and convert to internal form.  */
  /* Read and convert to internal form.  */
  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
    {
    {
      Elf_External_Phdr x_phdr;
      Elf_External_Phdr x_phdr;
 
 
      if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
      if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
        goto fail;
        goto fail;
 
 
      elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
      elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
    }
    }
 
 
  /* Set the machine architecture.  Do this before processing the
  /* Set the machine architecture.  Do this before processing the
     program headers since we need to know the architecture type
     program headers since we need to know the architecture type
     when processing the notes of some systems' core files.  */
     when processing the notes of some systems' core files.  */
  if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
  if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
      /* It's OK if this fails for the generic target.  */
      /* It's OK if this fails for the generic target.  */
      && ebd->elf_machine_code != EM_NONE)
      && ebd->elf_machine_code != EM_NONE)
    goto fail;
    goto fail;
 
 
  /* Let the backend double check the format and override global
  /* Let the backend double check the format and override global
     information.  We do this before processing the program headers
     information.  We do this before processing the program headers
     to allow the correct machine (as opposed to just the default
     to allow the correct machine (as opposed to just the default
     machine) to be set, making it possible for grok_prstatus and
     machine) to be set, making it possible for grok_prstatus and
     grok_psinfo to rely on the mach setting.  */
     grok_psinfo to rely on the mach setting.  */
  if (ebd->elf_backend_object_p != NULL
  if (ebd->elf_backend_object_p != NULL
      && ! ebd->elf_backend_object_p (abfd))
      && ! ebd->elf_backend_object_p (abfd))
    goto wrong;
    goto wrong;
 
 
  /* Process each program header.  */
  /* Process each program header.  */
  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
    if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
    if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
      goto fail;
      goto fail;
 
 
  /* Check for core truncation.  */
  /* Check for core truncation.  */
  {
  {
    bfd_size_type high = 0;
    bfd_size_type high = 0;
    struct stat statbuf;
    struct stat statbuf;
    for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
    for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
      {
      {
        Elf_Internal_Phdr *p = i_phdrp + phindex;
        Elf_Internal_Phdr *p = i_phdrp + phindex;
        if (p->p_filesz)
        if (p->p_filesz)
          {
          {
            bfd_size_type current = p->p_offset + p->p_filesz;
            bfd_size_type current = p->p_offset + p->p_filesz;
            if (high < current)
            if (high < current)
              high = current;
              high = current;
          }
          }
      }
      }
    if (bfd_stat (abfd, &statbuf) == 0)
    if (bfd_stat (abfd, &statbuf) == 0)
      {
      {
        if ((bfd_size_type) statbuf.st_size < high)
        if ((bfd_size_type) statbuf.st_size < high)
          {
          {
            (*_bfd_error_handler)
            (*_bfd_error_handler)
              (_("Warning: %B is truncated: expected core file "
              (_("Warning: %B is truncated: expected core file "
                 "size >= %lu, found: %lu."),
                 "size >= %lu, found: %lu."),
               abfd, (unsigned long) high, (unsigned long) statbuf.st_size);
               abfd, (unsigned long) high, (unsigned long) statbuf.st_size);
          }
          }
      }
      }
  }
  }
 
 
  /* Save the entry point from the ELF header.  */
  /* Save the entry point from the ELF header.  */
  bfd_get_start_address (abfd) = i_ehdrp->e_entry;
  bfd_get_start_address (abfd) = i_ehdrp->e_entry;
 
 
  bfd_preserve_finish (abfd, &preserve);
  bfd_preserve_finish (abfd, &preserve);
  return abfd->xvec;
  return abfd->xvec;
 
 
wrong:
wrong:
  /* There is way too much undoing of half-known state here.  The caller,
  /* There is way too much undoing of half-known state here.  The caller,
     bfd_check_format_matches, really shouldn't iterate on live bfd's to
     bfd_check_format_matches, really shouldn't iterate on live bfd's to
     check match/no-match like it does.  We have to rely on that a call to
     check match/no-match like it does.  We have to rely on that a call to
     bfd_default_set_arch_mach with the previously known mach, undoes what
     bfd_default_set_arch_mach with the previously known mach, undoes what
     was done by the first bfd_default_set_arch_mach (with mach 0) here.
     was done by the first bfd_default_set_arch_mach (with mach 0) here.
     For this to work, only elf-data and the mach may be changed by the
     For this to work, only elf-data and the mach may be changed by the
     target-specific elf_backend_object_p function.  Note that saving the
     target-specific elf_backend_object_p function.  Note that saving the
     whole bfd here and restoring it would be even worse; the first thing
     whole bfd here and restoring it would be even worse; the first thing
     you notice is that the cached bfd file position gets out of sync.  */
     you notice is that the cached bfd file position gets out of sync.  */
  bfd_set_error (bfd_error_wrong_format);
  bfd_set_error (bfd_error_wrong_format);
 
 
fail:
fail:
  if (preserve.marker != NULL)
  if (preserve.marker != NULL)
    bfd_preserve_restore (abfd, &preserve);
    bfd_preserve_restore (abfd, &preserve);
  return NULL;
  return NULL;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.