Home | History | Annotate | Line # | Download | only in bfd
      1 /* ELF core file support for BFD.
      2    Copyright (C) 1995-2025 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 char*
     22 elf_core_file_failing_command (bfd *abfd)
     23 {
     24   return elf_tdata (abfd)->core->command;
     25 }
     26 
     27 int
     28 elf_core_file_failing_signal (bfd *abfd)
     29 {
     30   return elf_tdata (abfd)->core->signal;
     31 }
     32 
     33 int
     34 elf_core_file_pid (bfd *abfd)
     35 {
     36   return elf_tdata (abfd)->core->pid;
     37 }
     38 
     39 bool
     40 elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
     41 {
     42   char* corename;
     43 
     44   /* xvecs must match if both are ELF files for the same target.  */
     45 
     46   if (core_bfd->xvec != exec_bfd->xvec)
     47     {
     48       bfd_set_error (bfd_error_system_call);
     49       return false;
     50     }
     51 
     52   /* If both BFDs have identical build-ids, then they match.  */
     53   if (core_bfd->build_id != NULL
     54       && exec_bfd->build_id != NULL
     55       && core_bfd->build_id->size == exec_bfd->build_id->size
     56       && memcmp (core_bfd->build_id->data, exec_bfd->build_id->data,
     57 		 core_bfd->build_id->size) == 0)
     58     return true;
     59 
     60   /* See if the name in the corefile matches the executable name.  */
     61   corename = elf_tdata (core_bfd)->core->program;
     62   if (corename != NULL)
     63     {
     64       const char* execname = strrchr (bfd_get_filename (exec_bfd), '/');
     65 
     66       execname = execname ? execname + 1 : bfd_get_filename (exec_bfd);
     67 
     68       if (strcmp (execname, corename) != 0)
     69 	return false;
     70     }
     71 
     72   return true;
     73 }
     74 
     75 /*  Core files are simply standard ELF formatted files that partition
     76     the file using the execution view of the file (program header table)
     77     rather than the linking view.  In fact, there is no section header
     78     table in a core file.
     79 
     80     The process status information (including the contents of the general
     81     register set) and the floating point register set are stored in a
     82     segment of type PT_NOTE.  We handcraft a couple of extra bfd sections
     83     that allow standard bfd access to the general registers (.reg) and the
     84     floating point registers (.reg2).  */
     85 
     86 bfd_cleanup
     87 elf_core_file_p (bfd *abfd)
     88 {
     89   Elf_External_Ehdr x_ehdr;	/* Elf file header, external form.  */
     90   Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form.  */
     91   Elf_Internal_Phdr *i_phdrp;	/* Elf program header, internal form.  */
     92   unsigned int phindex;
     93   const struct elf_backend_data *ebd;
     94   bfd_size_type amt;
     95   ufile_ptr filesize;
     96 
     97   /* Read in the ELF header in external format.  */
     98   if (bfd_read (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
     99     {
    100       if (bfd_get_error () != bfd_error_system_call)
    101 	goto wrong;
    102       else
    103 	goto fail;
    104     }
    105 
    106   /* Check the magic number.  */
    107   if (! elf_file_p (&x_ehdr))
    108     goto wrong;
    109 
    110   /* FIXME: Check EI_VERSION here !  */
    111 
    112   /* Check the address size ("class").  */
    113   if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
    114     goto wrong;
    115 
    116   /* Check the byteorder.  */
    117   switch (x_ehdr.e_ident[EI_DATA])
    118     {
    119     case ELFDATA2MSB:		/* Big-endian.  */
    120       if (! bfd_big_endian (abfd))
    121 	goto wrong;
    122       break;
    123     case ELFDATA2LSB:		/* Little-endian.  */
    124       if (! bfd_little_endian (abfd))
    125 	goto wrong;
    126       break;
    127     default:
    128       goto wrong;
    129     }
    130 
    131   /* Give abfd an elf_obj_tdata.  */
    132   if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
    133     goto fail;
    134 
    135   /* Swap in the rest of the header, now that we have the byte order.  */
    136   i_ehdrp = elf_elfheader (abfd);
    137   elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
    138 
    139 #if DEBUG & 1
    140   elf_debug_file (i_ehdrp);
    141 #endif
    142 
    143   ebd = get_elf_backend_data (abfd);
    144 
    145   /* Check that the ELF e_machine field matches what this particular
    146      BFD format expects.  */
    147 
    148   if (ebd->elf_machine_code != i_ehdrp->e_machine
    149       && (ebd->elf_machine_alt1 == 0
    150 	  || i_ehdrp->e_machine != ebd->elf_machine_alt1)
    151       && (ebd->elf_machine_alt2 == 0
    152 	  || i_ehdrp->e_machine != ebd->elf_machine_alt2)
    153       && ebd->elf_machine_code != EM_NONE)
    154     goto wrong;
    155 
    156   if (ebd->elf_machine_code != EM_NONE
    157       && i_ehdrp->e_ident[EI_OSABI] != ebd->elf_osabi
    158       && ebd->elf_osabi != ELFOSABI_NONE)
    159     goto wrong;
    160 
    161   /* If there is no program header, or the type is not a core file, then
    162      we are hosed.  */
    163   if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
    164     goto wrong;
    165 
    166   /* Does BFD's idea of the phdr size match the size
    167      recorded in the file? */
    168   if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
    169     goto wrong;
    170 
    171   /* If the program header count is PN_XNUM(0xffff), the actual
    172      count is in the first section header.  */
    173   if (i_ehdrp->e_shoff != 0 && i_ehdrp->e_phnum == PN_XNUM)
    174     {
    175       Elf_External_Shdr x_shdr;
    176       Elf_Internal_Shdr i_shdr;
    177       file_ptr where = (file_ptr) i_ehdrp->e_shoff;
    178 
    179       if (i_ehdrp->e_shoff < sizeof (x_ehdr))
    180 	goto wrong;
    181 
    182       /* Seek to the section header table in the file.  */
    183       if (bfd_seek (abfd, where, SEEK_SET) != 0)
    184 	goto fail;
    185 
    186       /* Read the first section header at index 0, and convert to internal
    187 	 form.  */
    188       if (bfd_read (&x_shdr, sizeof (x_shdr), abfd) != sizeof (x_shdr))
    189 	goto fail;
    190       elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
    191 
    192       if (i_shdr.sh_info != 0)
    193 	{
    194 	  i_ehdrp->e_phnum = i_shdr.sh_info;
    195 	  if (i_ehdrp->e_phnum != i_shdr.sh_info)
    196 	    goto wrong;
    197 	}
    198     }
    199 
    200   /* Sanity check that we can read all of the program headers.
    201      It ought to be good enough to just read the last one.  */
    202   if (i_ehdrp->e_phnum > 1)
    203     {
    204       Elf_External_Phdr x_phdr;
    205       Elf_Internal_Phdr i_phdr;
    206       file_ptr where;
    207 
    208       /* Check that we don't have a totally silly number of
    209 	 program headers.  */
    210       if (i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (x_phdr)
    211 	  || i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (i_phdr))
    212 	goto wrong;
    213 
    214       where = (file_ptr)(i_ehdrp->e_phoff + (i_ehdrp->e_phnum - 1) * sizeof (x_phdr));
    215       if ((bfd_size_type) where <= i_ehdrp->e_phoff)
    216 	goto wrong;
    217 
    218       if (bfd_seek (abfd, where, SEEK_SET) != 0)
    219 	goto fail;
    220       if (bfd_read (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
    221 	goto fail;
    222     }
    223 
    224   /* Move to the start of the program headers.  */
    225   if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0)
    226     goto wrong;
    227 
    228   /* Allocate space for the program headers.  */
    229   amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
    230   i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
    231   if (!i_phdrp)
    232     goto fail;
    233 
    234   elf_tdata (abfd)->phdr = i_phdrp;
    235 
    236   /* Read and convert to internal form.  */
    237   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
    238     {
    239       Elf_External_Phdr x_phdr;
    240 
    241       if (bfd_read (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
    242 	goto fail;
    243 
    244       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
    245     }
    246 
    247   /* Set the machine architecture.  Do this before processing the
    248      program headers since we need to know the architecture type
    249      when processing the notes of some systems' core files.  */
    250   if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
    251       /* It's OK if this fails for the generic target.  */
    252       && ebd->elf_machine_code != EM_NONE)
    253     goto fail;
    254 
    255   /* Let the backend double check the format and override global
    256      information.  We do this before processing the program headers
    257      to allow the correct machine (as opposed to just the default
    258      machine) to be set, making it possible for grok_prstatus and
    259      grok_psinfo to rely on the mach setting.  */
    260   if (ebd->elf_backend_object_p != NULL
    261       && ! ebd->elf_backend_object_p (abfd))
    262     goto wrong;
    263 
    264   /* Process each program header.  */
    265   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
    266     if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
    267       goto fail;
    268 
    269   /* Check for core truncation.  */
    270   filesize = bfd_get_file_size (abfd);
    271   if (filesize != 0)
    272     {
    273       for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
    274 	{
    275 	  Elf_Internal_Phdr *p = i_phdrp + phindex;
    276 	  if (p->p_filesz
    277 	      && (p->p_offset >= filesize
    278 		  || p->p_filesz > filesize - p->p_offset))
    279 	    {
    280 	      _bfd_error_handler (_("warning: %pB has a segment "
    281 				    "extending past end of file"), abfd);
    282 	      abfd->read_only = 1;
    283 	      break;
    284 	    }
    285       }
    286   }
    287 
    288   /* Save the entry point from the ELF header.  */
    289   abfd->start_address = i_ehdrp->e_entry;
    290   return _bfd_no_cleanup;
    291 
    292  wrong:
    293   bfd_set_error (bfd_error_wrong_format);
    294  fail:
    295   return NULL;
    296 }
    297 
    298 /* Attempt to find a build-id in a core file from the core file BFD.
    299    OFFSET is the file offset to a PT_LOAD segment that may contain
    300    the build-id note.  Returns TRUE upon success, FALSE otherwise.  */
    301 
    302 bool
    303 NAME(_bfd_elf, core_find_build_id)
    304   (bfd *abfd,
    305    bfd_vma offset)
    306 {
    307   Elf_External_Ehdr x_ehdr;	/* Elf file header, external form.   */
    308   Elf_Internal_Ehdr i_ehdr;	/* Elf file header, internal form.   */
    309   Elf_Internal_Phdr *i_phdr;
    310   unsigned int i;
    311   size_t amt;
    312 
    313   /* Seek to the position of the segment at OFFSET.  */
    314   if (bfd_seek (abfd, offset, SEEK_SET) != 0)
    315     goto fail;
    316 
    317   /* Read in the ELF header in external format.  */
    318   if (bfd_read (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
    319     {
    320       if (bfd_get_error () != bfd_error_system_call)
    321 	goto wrong;
    322       else
    323 	goto fail;
    324     }
    325 
    326   /* Now check to see if we have a valid ELF file, and one that BFD can
    327      make use of.  The magic number must match, the address size ('class')
    328      and byte-swapping must match our XVEC entry, and it must have a
    329      section header table (FIXME: See comments re sections at top of this
    330      file).  */
    331   if (! elf_file_p (&x_ehdr)
    332       || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
    333       || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
    334     goto wrong;
    335 
    336   /* Check that file's byte order matches xvec's.  */
    337   switch (x_ehdr.e_ident[EI_DATA])
    338     {
    339     case ELFDATA2MSB:		/* Big-endian.  */
    340       if (! bfd_header_big_endian (abfd))
    341 	goto wrong;
    342       break;
    343     case ELFDATA2LSB:		/* Little-endian.  */
    344       if (! bfd_header_little_endian (abfd))
    345 	goto wrong;
    346       break;
    347     case ELFDATANONE:		/* No data encoding specified.  */
    348     default:			/* Unknown data encoding specified . */
    349       goto wrong;
    350     }
    351 
    352   elf_swap_ehdr_in (abfd, &x_ehdr, &i_ehdr);
    353 #if DEBUG
    354   elf_debug_file (&i_ehdr);
    355 #endif
    356 
    357   if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
    358     goto fail;
    359 
    360   /* Read in program headers.  */
    361   if (_bfd_mul_overflow (i_ehdr.e_phnum, sizeof (*i_phdr), &amt))
    362     {
    363       bfd_set_error (bfd_error_file_too_big);
    364       goto fail;
    365     }
    366   i_phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
    367   if (i_phdr == NULL)
    368     goto fail;
    369 
    370   if (bfd_seek (abfd, offset + i_ehdr.e_phoff, SEEK_SET) != 0)
    371     goto fail;
    372 
    373   /* Read in program headers and parse notes.  */
    374   for (i = 0; i < i_ehdr.e_phnum; ++i, ++i_phdr)
    375     {
    376       Elf_External_Phdr x_phdr;
    377 
    378       if (bfd_read (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
    379 	goto fail;
    380       elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
    381 
    382       if (i_phdr->p_type == PT_NOTE && i_phdr->p_filesz > 0)
    383 	{
    384 	  elf_read_notes (abfd, offset + i_phdr->p_offset,
    385 			  i_phdr->p_filesz, i_phdr->p_align);
    386 
    387 	  /* Make sure ABFD returns to processing the program headers.  */
    388 	  if (bfd_seek (abfd,
    389 			offset + i_ehdr.e_phoff + (i + 1) * sizeof (x_phdr),
    390 			SEEK_SET) != 0)
    391 	    goto fail;
    392 
    393 	  if (abfd->build_id != NULL)
    394 	    return true;
    395 	}
    396     }
    397 
    398   /* Having gotten this far, we have a valid ELF section, but no
    399      build-id was found.  */
    400   goto fail;
    401 
    402  wrong:
    403   bfd_set_error (bfd_error_wrong_format);
    404  fail:
    405   return false;
    406 }
    407