OSDN Git Service

bfd/
[pf3gnuchains/pf3gnuchains3x.git] / bfd / elfcore.h
index 865edcd..c51c575 100644 (file)
@@ -1,12 +1,12 @@
 /* ELF core file support for BFD.
-   Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
-   Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007,
+   2008 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 modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,7 +16,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 char*
 elf_core_file_failing_command (bfd *abfd)
@@ -76,7 +77,7 @@ elf_core_file_p (bfd *abfd)
   Elf_Internal_Ehdr *i_ehdrp;  /* Elf file header, internal form.  */
   Elf_Internal_Phdr *i_phdrp;  /* Elf program header, internal form.  */
   unsigned int phindex;
-  struct elf_backend_data *ebd;
+  const struct elf_backend_data *ebd;
   struct bfd_preserve preserve;
   bfd_size_type amt;
 
@@ -153,11 +154,13 @@ elf_core_file_p (bfd *abfd)
 
       for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
        {
-         struct elf_backend_data *back;
+         const struct elf_backend_data *back;
 
          if ((*target_ptr)->flavour != bfd_target_elf_flavour)
            continue;
-         back = (struct elf_backend_data *) (*target_ptr)->backend_data;
+         back = xvec_get_elf_backend_data (*target_ptr);
+         if (back->s->arch_size != ARCH_SIZE)
+           continue;
          if (back->elf_machine_code == i_ehdrp->e_machine
              || (back->elf_machine_alt1 != 0
                  && i_ehdrp->e_machine == back->elf_machine_alt1)
@@ -187,7 +190,7 @@ elf_core_file_p (bfd *abfd)
 
   /* Allocate space for the program headers.  */
   amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
-  i_phdrp = bfd_alloc (abfd, amt);
+  i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
   if (!i_phdrp)
     goto fail;
 
@@ -207,27 +210,54 @@ elf_core_file_p (bfd *abfd)
   /* Set the machine architecture.  Do this before processing the
      program headers since we need to know the architecture type
      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.  */
-      if (ebd->elf_machine_code != EM_NONE)
-       goto fail;
-    }
+      && ebd->elf_machine_code != EM_NONE)
+    goto fail;
+
+  /* Let the backend double check the format and override global
+     information.  We do this before processing the program headers
+     to allow the correct machine (as opposed to just the default
+     machine) to be set, making it possible for grok_prstatus and
+     grok_psinfo to rely on the mach setting.  */
+  if (ebd->elf_backend_object_p != NULL
+      && ! ebd->elf_backend_object_p (abfd))
+    goto wrong;
 
   /* Process each program header.  */
   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
     if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
       goto fail;
 
+  /* Check for core truncation.  */
+  {
+    bfd_size_type high = 0;
+    struct stat statbuf;
+    for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex) 
+      {
+       Elf_Internal_Phdr *p = i_phdrp + phindex;
+       if (p->p_filesz)
+         {
+           bfd_size_type current = p->p_offset + p->p_filesz;
+           if (high < current)
+             high = current;
+         }
+      }
+    if (bfd_stat (abfd, &statbuf) == 0)
+      {
+       if ((bfd_size_type) statbuf.st_size < high)
+         {
+           (*_bfd_error_handler)
+             (_("Warning: %B is truncated: expected core file "
+                "size >= %lu, found: %lu."),
+              abfd, (unsigned long) high, (unsigned long) statbuf.st_size);
+         }
+      }
+  }
+  
   /* Save the entry point from the ELF header.  */
   bfd_get_start_address (abfd) = i_ehdrp->e_entry;
 
-  /* Let the backend double check the format and override global
-     information.  */
-  if (ebd->elf_backend_object_p
-      && (! (*ebd->elf_backend_object_p) (abfd)))
-    goto wrong;
-
   bfd_preserve_finish (abfd, &preserve);
   return abfd->xvec;