Back to index

cell-binutils  2.17cvs20070401
elfcore.h
Go to the documentation of this file.
00001 /* ELF core file support for BFD.
00002    Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 char*
00022 elf_core_file_failing_command (bfd *abfd)
00023 {
00024   return elf_tdata (abfd)->core_command;
00025 }
00026 
00027 int
00028 elf_core_file_failing_signal (bfd *abfd)
00029 {
00030   return elf_tdata (abfd)->core_signal;
00031 }
00032 
00033 bfd_boolean
00034 elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
00035 {
00036   char* corename;
00037 
00038   /* xvecs must match if both are ELF files for the same target.  */
00039 
00040   if (core_bfd->xvec != exec_bfd->xvec)
00041     {
00042       bfd_set_error (bfd_error_system_call);
00043       return FALSE;
00044     }
00045 
00046   /* See if the name in the corefile matches the executable name.  */
00047   corename = elf_tdata (core_bfd)->core_program;
00048   if (corename != NULL)
00049     {
00050       const char* execname = strrchr (exec_bfd->filename, '/');
00051 
00052       execname = execname ? execname + 1 : exec_bfd->filename;
00053 
00054       if (strcmp (execname, corename) != 0)
00055        return FALSE;
00056     }
00057 
00058   return TRUE;
00059 }
00060 
00061 /*  Core files are simply standard ELF formatted files that partition
00062     the file using the execution view of the file (program header table)
00063     rather than the linking view.  In fact, there is no section header
00064     table in a core file.
00065 
00066     The process status information (including the contents of the general
00067     register set) and the floating point register set are stored in a
00068     segment of type PT_NOTE.  We handcraft a couple of extra bfd sections
00069     that allow standard bfd access to the general registers (.reg) and the
00070     floating point registers (.reg2).  */
00071 
00072 const bfd_target *
00073 elf_core_file_p (bfd *abfd)
00074 {
00075   Elf_External_Ehdr x_ehdr; /* Elf file header, external form.  */
00076   Elf_Internal_Ehdr *i_ehdrp;      /* Elf file header, internal form.  */
00077   Elf_Internal_Phdr *i_phdrp;      /* Elf program header, internal form.  */
00078   unsigned int phindex;
00079   const struct elf_backend_data *ebd;
00080   struct bfd_preserve preserve;
00081   bfd_size_type amt;
00082 
00083   preserve.marker = NULL;
00084 
00085   /* Read in the ELF header in external format.  */
00086   if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
00087     {
00088       if (bfd_get_error () != bfd_error_system_call)
00089        goto wrong;
00090       else
00091        goto fail;
00092     }
00093 
00094   /* Check the magic number.  */
00095   if (! elf_file_p (&x_ehdr))
00096     goto wrong;
00097 
00098   /* FIXME: Check EI_VERSION here !  */
00099 
00100   /* Check the address size ("class").  */
00101   if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
00102     goto wrong;
00103 
00104   /* Check the byteorder.  */
00105   switch (x_ehdr.e_ident[EI_DATA])
00106     {
00107     case ELFDATA2MSB:              /* Big-endian.  */
00108       if (! bfd_big_endian (abfd))
00109        goto wrong;
00110       break;
00111     case ELFDATA2LSB:              /* Little-endian.  */
00112       if (! bfd_little_endian (abfd))
00113        goto wrong;
00114       break;
00115     default:
00116       goto wrong;
00117     }
00118 
00119   if (!bfd_preserve_save (abfd, &preserve))
00120     goto fail;
00121 
00122   /* Give abfd an elf_obj_tdata.  */
00123   if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
00124     goto fail;
00125   preserve.marker = elf_tdata (abfd);
00126 
00127   /* Swap in the rest of the header, now that we have the byte order.  */
00128   i_ehdrp = elf_elfheader (abfd);
00129   elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
00130 
00131 #if DEBUG & 1
00132   elf_debug_file (i_ehdrp);
00133 #endif
00134 
00135   ebd = get_elf_backend_data (abfd);
00136 
00137   /* Check that the ELF e_machine field matches what this particular
00138      BFD format expects.  */
00139 
00140   if (ebd->elf_machine_code != i_ehdrp->e_machine
00141       && (ebd->elf_machine_alt1 == 0
00142          || i_ehdrp->e_machine != ebd->elf_machine_alt1)
00143       && (ebd->elf_machine_alt2 == 0
00144          || i_ehdrp->e_machine != ebd->elf_machine_alt2))
00145     {
00146       const bfd_target * const *target_ptr;
00147 
00148       if (ebd->elf_machine_code != EM_NONE)
00149        goto wrong;
00150 
00151       /* This is the generic ELF target.  Let it match any ELF target
00152         for which we do not have a specific backend.  */
00153 
00154       for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
00155        {
00156          const struct elf_backend_data *back;
00157 
00158          if ((*target_ptr)->flavour != bfd_target_elf_flavour)
00159            continue;
00160          back = (const struct elf_backend_data *) (*target_ptr)->backend_data;
00161          if (back->elf_machine_code == i_ehdrp->e_machine
00162              || (back->elf_machine_alt1 != 0
00163                  && i_ehdrp->e_machine == back->elf_machine_alt1)
00164              || (back->elf_machine_alt2 != 0
00165                  && i_ehdrp->e_machine == back->elf_machine_alt2))
00166            {
00167              /* target_ptr is an ELF backend which matches this
00168                object file, so reject the generic ELF target.  */
00169              goto wrong;
00170            }
00171        }
00172     }
00173 
00174   /* If there is no program header, or the type is not a core file, then
00175      we are hosed.  */
00176   if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
00177     goto wrong;
00178 
00179   /* Does BFD's idea of the phdr size match the size
00180      recorded in the file? */
00181   if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
00182     goto wrong;
00183 
00184   /* Move to the start of the program headers.  */
00185   if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
00186     goto wrong;
00187 
00188   /* Allocate space for the program headers.  */
00189   amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
00190   i_phdrp = bfd_alloc (abfd, amt);
00191   if (!i_phdrp)
00192     goto fail;
00193 
00194   elf_tdata (abfd)->phdr = i_phdrp;
00195 
00196   /* Read and convert to internal form.  */
00197   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
00198     {
00199       Elf_External_Phdr x_phdr;
00200 
00201       if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
00202        goto fail;
00203 
00204       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
00205     }
00206 
00207   /* Set the machine architecture.  Do this before processing the
00208      program headers since we need to know the architecture type
00209      when processing the notes of some systems' core files.  */
00210   if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
00211       /* It's OK if this fails for the generic target.  */
00212       && ebd->elf_machine_code != EM_NONE)
00213     goto fail;
00214 
00215   /* Let the backend double check the format and override global
00216      information.  We do this before processing the program headers
00217      to allow the correct machine (as opposed to just the default
00218      machine) to be set, making it possible for grok_prstatus and
00219      grok_psinfo to rely on the mach setting.  */
00220   if (ebd->elf_backend_object_p != NULL
00221       && ! ebd->elf_backend_object_p (abfd))
00222     goto wrong;
00223 
00224   /* Process each program header.  */
00225   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
00226     if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
00227       goto fail;
00228 
00229   /* Save the entry point from the ELF header.  */
00230   bfd_get_start_address (abfd) = i_ehdrp->e_entry;
00231 
00232   bfd_preserve_finish (abfd, &preserve);
00233   return abfd->xvec;
00234 
00235 wrong:
00236   /* There is way too much undoing of half-known state here.  The caller,
00237      bfd_check_format_matches, really shouldn't iterate on live bfd's to
00238      check match/no-match like it does.  We have to rely on that a call to
00239      bfd_default_set_arch_mach with the previously known mach, undoes what
00240      was done by the first bfd_default_set_arch_mach (with mach 0) here.
00241      For this to work, only elf-data and the mach may be changed by the
00242      target-specific elf_backend_object_p function.  Note that saving the
00243      whole bfd here and restoring it would be even worse; the first thing
00244      you notice is that the cached bfd file position gets out of sync.  */
00245   bfd_set_error (bfd_error_wrong_format);
00246 
00247 fail:
00248   if (preserve.marker != NULL)
00249     bfd_preserve_restore (abfd, &preserve);
00250   return NULL;
00251 }