Home | History | Annotate | Download | only in libdwfl
      1 /* Core file handling.
      2    Copyright (C) 2008-2010, 2013, 2015 Red Hat, Inc.
      3    This file is part of elfutils.
      4 
      5    This file is free software; you can redistribute it and/or modify
      6    it under the terms of either
      7 
      8      * the GNU Lesser General Public License as published by the Free
      9        Software Foundation; either version 3 of the License, or (at
     10        your option) any later version
     11 
     12    or
     13 
     14      * the GNU General Public License as published by the Free
     15        Software Foundation; either version 2 of the License, or (at
     16        your option) any later version
     17 
     18    or both in parallel, as here.
     19 
     20    elfutils is distributed in the hope that it will be useful, but
     21    WITHOUT ANY WARRANTY; without even the implied warranty of
     22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23    General Public License for more details.
     24 
     25    You should have received copies of the GNU General Public License and
     26    the GNU Lesser General Public License along with this program.  If
     27    not, see <http://www.gnu.org/licenses/>.  */
     28 
     29 #include <config.h>
     30 #include "../libelf/libelfP.h"	/* For NOTE_ALIGN.  */
     31 #undef	_
     32 #include "libdwflP.h"
     33 #include <gelf.h>
     34 
     35 #include <sys/param.h>
     36 #include <unistd.h>
     37 #include <endian.h>
     38 #include <byteswap.h>
     39 #include "system.h"
     40 
     41 
     42 /* On failure return, we update *NEXT to point back at OFFSET.  */
     43 static inline Elf *
     44 do_fail (int error, off_t *next, off_t offset)
     45 {
     46     if (next != NULL)
     47       *next = offset;
     48     //__libelf_seterrno (error);
     49     __libdwfl_seterrno (DWFL_E (LIBELF, error));
     50     return NULL;
     51 }
     52 
     53 #define fail(error) do_fail (error, next, offset)
     54 
     55 /* This is a prototype of what a new libelf interface might be.
     56    This implementation is pessimal for non-mmap cases and should
     57    be replaced by more diddling inside libelf internals.  */
     58 static Elf *
     59 elf_begin_rand (Elf *parent, off_t offset, off_t size, off_t *next)
     60 {
     61   if (parent == NULL)
     62     return NULL;
     63 
     64   off_t min = (parent->kind == ELF_K_ELF ?
     65 		(parent->class == ELFCLASS32
     66 		 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))
     67 		: parent->kind == ELF_K_AR ? SARMAG
     68 		: 0);
     69 
     70   if (unlikely (offset < min)
     71       || unlikely (offset >= (off_t) parent->maximum_size))
     72     return fail (ELF_E_RANGE);
     73 
     74   /* For an archive, fetch just the size field
     75      from the archive header to override SIZE.  */
     76   if (parent->kind == ELF_K_AR)
     77     {
     78       struct ar_hdr h = { .ar_size = "" };
     79 
     80       if (unlikely (parent->maximum_size - offset < sizeof h))
     81 	return fail (ELF_E_RANGE);
     82 
     83       if (parent->map_address != NULL)
     84 	memcpy (h.ar_size, parent->map_address + parent->start_offset + offset,
     85 		sizeof h.ar_size);
     86       else if (unlikely (pread_retry (parent->fildes,
     87 				      h.ar_size, sizeof (h.ar_size),
     88 				      parent->start_offset + offset
     89 				      + offsetof (struct ar_hdr, ar_size))
     90 			 != sizeof (h.ar_size)))
     91 	return fail (ELF_E_READ_ERROR);
     92 
     93       offset += sizeof h;
     94 
     95       char *endp;
     96       size = strtoll (h.ar_size, &endp, 10);
     97       if (unlikely (endp == h.ar_size)
     98 	  || unlikely ((off_t) parent->maximum_size - offset < size))
     99 	return fail (ELF_E_INVALID_ARCHIVE);
    100     }
    101 
    102   if (unlikely ((off_t) parent->maximum_size - offset < size))
    103     return fail (ELF_E_RANGE);
    104 
    105   /* Even if we fail at this point, update *NEXT to point past the file.  */
    106   if (next != NULL)
    107     *next = offset + size;
    108 
    109   if (unlikely (offset == 0)
    110       && unlikely (size == (off_t) parent->maximum_size))
    111     return elf_clone (parent, parent->cmd);
    112 
    113   /* Note the image is guaranteed live only as long as PARENT
    114      lives.  Using elf_memory is quite suboptimal if the whole
    115      file is not mmap'd.  We really should have something like
    116      a generalization of the archive support.  */
    117   Elf_Data *data = elf_getdata_rawchunk (parent, offset, size, ELF_T_BYTE);
    118   if (data == NULL)
    119     return NULL;
    120   assert ((off_t) data->d_size == size);
    121   return elf_memory (data->d_buf, size);
    122 }
    123 
    124 
    125 int
    126 dwfl_report_core_segments (Dwfl *dwfl, Elf *elf, size_t phnum, GElf_Phdr *notes)
    127 {
    128   if (unlikely (dwfl == NULL))
    129     return -1;
    130 
    131   int result = 0;
    132 
    133   if (notes != NULL)
    134     notes->p_type = PT_NULL;
    135 
    136   for (size_t ndx = 0; result >= 0 && ndx < phnum; ++ndx)
    137     {
    138       GElf_Phdr phdr_mem;
    139       GElf_Phdr *phdr = gelf_getphdr (elf, ndx, &phdr_mem);
    140       if (unlikely (phdr == NULL))
    141 	{
    142 	  __libdwfl_seterrno (DWFL_E_LIBELF);
    143 	  return -1;
    144 	}
    145       switch (phdr->p_type)
    146 	{
    147 	case PT_LOAD:
    148 	  result = dwfl_report_segment (dwfl, ndx, phdr, 0, NULL);
    149 	  break;
    150 
    151 	case PT_NOTE:
    152 	  if (notes != NULL)
    153 	    {
    154 	      *notes = *phdr;
    155 	      notes = NULL;
    156 	    }
    157 	  break;
    158 	}
    159     }
    160 
    161   return result;
    162 }
    163 
    164 /* Never read more than this much without mmap.  */
    165 #define MAX_EAGER_COST	8192
    166 
    167 /* Dwfl_Module_Callback passed to and called by dwfl_segment_report_module
    168    to read in a segment as ELF image directly if possible or indicate an
    169    attempt must be made to read in the while segment right now.  */
    170 static bool
    171 core_file_read_eagerly (Dwfl_Module *mod,
    172 			void **userdata __attribute__ ((unused)),
    173 			const char *name __attribute__ ((unused)),
    174 			Dwarf_Addr start __attribute__ ((unused)),
    175 			void **buffer, size_t *buffer_available,
    176 			GElf_Off cost, GElf_Off worthwhile,
    177 			GElf_Off whole,
    178 			GElf_Off contiguous __attribute__ ((unused)),
    179 			void *arg, Elf **elfp)
    180 {
    181   Elf *core = arg;
    182 
    183   /* The available buffer is often the whole segment when the core file
    184      was mmap'd if used together with the dwfl_elf_phdr_memory_callback.
    185      Which means that if it is complete we can just construct the whole
    186      ELF image right now without having to read in anything more.  */
    187   if (whole <= *buffer_available)
    188     {
    189       /* All there ever was, we already have on hand.  */
    190 
    191       if (core->map_address == NULL)
    192 	{
    193 	  /* We already malloc'd the buffer.  */
    194 	  *elfp = elf_memory (*buffer, whole);
    195 	  if (unlikely (*elfp == NULL))
    196 	    return false;
    197 
    198 	  (*elfp)->flags |= ELF_F_MALLOCED;
    199 	  *buffer = NULL;
    200 	  *buffer_available = 0;
    201 	  return true;
    202 	}
    203 
    204       /* We can use the image inside the core file directly.  */
    205       *elfp = elf_begin_rand (core, *buffer - core->map_address, whole, NULL);
    206       *buffer = NULL;
    207       *buffer_available = 0;
    208       return *elfp != NULL;
    209     }
    210 
    211   /* We don't have the whole file.  Which either means the core file
    212      wasn't mmap'd, but needs to still be read in, or that the segment
    213      is truncated.  Figure out if this is better than nothing.  */
    214 
    215   if (worthwhile == 0)
    216     /* Caller doesn't think so.  */
    217     return false;
    218 
    219   /*
    220     XXX would like to fall back to partial file via memory
    221     when build id find_elf fails
    222     also, link_map name may give file name from disk better than partial here
    223     requires find_elf hook re-doing the magic to fall back if no file found
    224   */
    225 
    226   if (whole > MAX_EAGER_COST && mod->build_id_len > 0)
    227     /* We can't cheaply read the whole file here, so we'd
    228        be using a partial file.  But there is a build ID that could
    229        help us find the whole file, which might be more useful than
    230        what we have.  We'll just rely on that.  */
    231     return false;
    232 
    233   /* The file is either small (most likely the vdso) or big and incomplete,
    234      but we don't have a build-id.  */
    235 
    236   if (core->map_address != NULL)
    237     /* It's cheap to get, so get it.  */
    238     return true;
    239 
    240   /* Only use it if there isn't too much to be read.  */
    241   return cost <= MAX_EAGER_COST;
    242 }
    243 
    244 static inline void
    245 update_end (GElf_Phdr *pphdr, const GElf_Off align,
    246             GElf_Off *pend, GElf_Addr *pend_vaddr)
    247 {
    248   *pend = (pphdr->p_offset + pphdr->p_filesz + align - 1) & -align;
    249   *pend_vaddr = (pphdr->p_vaddr + pphdr->p_memsz + align - 1) & -align;
    250 }
    251 
    252 /* Use following contiguous segments to get towards SIZE.  */
    253 static inline bool
    254 do_more (size_t size, GElf_Phdr *pphdr, const GElf_Off align,
    255          Elf *elf, GElf_Off start, int *pndx,
    256          GElf_Off *pend, GElf_Addr *pend_vaddr)
    257 {
    258   while (*pend <= start || *pend - start < size)
    259     {
    260       if (pphdr->p_filesz < pphdr->p_memsz)
    261 	/* This segment is truncated, so no following one helps us.  */
    262 	return false;
    263 
    264       if (unlikely (gelf_getphdr (elf, (*pndx)++, pphdr) == NULL))
    265 	return false;
    266 
    267       if (pphdr->p_type == PT_LOAD)
    268 	{
    269 	  if (pphdr->p_offset > *pend
    270 	      || pphdr->p_vaddr > *pend_vaddr)
    271 	    /* It's discontiguous!  */
    272 	    return false;
    273 
    274 	  update_end (pphdr, align, pend, pend_vaddr);
    275 	}
    276     }
    277   return true;
    278 }
    279 
    280 #define more(size) do_more (size, &phdr, align, elf, start, &ndx, &end, &end_vaddr)
    281 
    282 bool
    283 dwfl_elf_phdr_memory_callback (Dwfl *dwfl, int ndx,
    284 			       void **buffer, size_t *buffer_available,
    285 			       GElf_Addr vaddr,
    286 			       size_t minread,
    287 			       void *arg)
    288 {
    289   Elf *elf = arg;
    290 
    291   if (ndx == -1)
    292     {
    293       /* Called for cleanup.  */
    294       if (elf->map_address == NULL)
    295 	free (*buffer);
    296       *buffer = NULL;
    297       *buffer_available = 0;
    298       return false;
    299     }
    300 
    301   const GElf_Off align = dwfl->segment_align ?: 1;
    302   GElf_Phdr phdr;
    303 
    304   do
    305     if (unlikely (gelf_getphdr (elf, ndx++, &phdr) == NULL))
    306       return false;
    307   while (phdr.p_type != PT_LOAD
    308 	 || ((phdr.p_vaddr + phdr.p_memsz + align - 1) & -align) <= vaddr);
    309 
    310   GElf_Off start = vaddr - phdr.p_vaddr + phdr.p_offset;
    311   GElf_Off end;
    312   GElf_Addr end_vaddr;
    313 
    314   update_end (&phdr, align, &end, &end_vaddr);
    315 
    316   /* We need at least this much.  */
    317   if (! more (minread))
    318     return false;
    319 
    320   /* See how much more we can get of what the caller wants.  */
    321   (void) more (*buffer_available);
    322 
    323   /* If it's already on hand anyway, use as much as there is.  */
    324   if (elf->map_address != NULL)
    325     (void) more (elf->maximum_size - start);
    326 
    327   /* Make sure we don't look past the end of the actual file,
    328      even if the headers tell us to.  */
    329   if (unlikely (end > elf->maximum_size))
    330     end = elf->maximum_size;
    331 
    332   /* If the file is too small, there is nothing at all to get.  */
    333   if (unlikely (start >= end))
    334     return false;
    335 
    336   if (elf->map_address != NULL)
    337     {
    338       void *contents = elf->map_address + elf->start_offset + start;
    339       size_t size = end - start;
    340 
    341       if (minread == 0)		/* String mode.  */
    342 	{
    343 	  const void *eos = memchr (contents, '\0', size);
    344 	  if (unlikely (eos == NULL) || unlikely (eos == contents))
    345 	    return false;
    346 	  size = eos + 1 - contents;
    347 	}
    348 
    349       if (*buffer == NULL)
    350 	{
    351 	  *buffer = contents;
    352 	  *buffer_available = size;
    353 	}
    354       else
    355 	{
    356 	  *buffer_available = MIN (size, *buffer_available);
    357 	  memcpy (*buffer, contents, *buffer_available);
    358 	}
    359     }
    360   else
    361     {
    362       void *into = *buffer;
    363       if (*buffer == NULL)
    364 	{
    365 	  *buffer_available = MIN (minread ?: 512,
    366 				   MAX (4096, MIN (end - start,
    367 						   *buffer_available)));
    368 	  into = malloc (*buffer_available);
    369 	  if (unlikely (into == NULL))
    370 	    {
    371 	      __libdwfl_seterrno (DWFL_E_NOMEM);
    372 	      return false;
    373 	    }
    374 	}
    375 
    376       ssize_t nread = pread_retry (elf->fildes, into, *buffer_available, start);
    377       if (nread < (ssize_t) minread)
    378 	{
    379 	  if (into != *buffer)
    380 	    free (into);
    381 	  if (nread < 0)
    382 	    __libdwfl_seterrno (DWFL_E_ERRNO);
    383 	  return false;
    384 	}
    385 
    386       if (minread == 0)		/* String mode.  */
    387 	{
    388 	  const void *eos = memchr (into, '\0', nread);
    389 	  if (unlikely (eos == NULL) || unlikely (eos == into))
    390 	    {
    391 	      if (*buffer == NULL)
    392 		free (into);
    393 	      return false;
    394 	    }
    395 	  nread = eos + 1 - into;
    396 	}
    397 
    398       if (*buffer == NULL)
    399 	*buffer = into;
    400       *buffer_available = nread;
    401     }
    402 
    403   return true;
    404 }
    405 
    406 /* Free the contents of R_DEBUG_INFO without the R_DEBUG_INFO memory itself.  */
    407 
    408 static void
    409 clear_r_debug_info (struct r_debug_info *r_debug_info)
    410 {
    411   while (r_debug_info->module != NULL)
    412     {
    413       struct r_debug_info_module *module = r_debug_info->module;
    414       r_debug_info->module = module->next;
    415       elf_end (module->elf);
    416       if (module->fd != -1)
    417 	close (module->fd);
    418       free (module);
    419     }
    420 }
    421 
    422 bool
    423 internal_function
    424 __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
    425 {
    426   size_t phnum;
    427   if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
    428     return false;
    429   for (size_t i = 0; i < phnum; ++i)
    430     {
    431       GElf_Phdr phdr_mem;
    432       GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
    433       if (unlikely (phdr == NULL))
    434 	return false;
    435       if (phdr->p_type == PT_DYNAMIC)
    436 	{
    437 	  *vaddrp = phdr->p_vaddr;
    438 	  return true;
    439 	}
    440     }
    441   return false;
    442 }
    443 
    444 int
    445 dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
    446 {
    447   size_t phnum;
    448   if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
    449     {
    450       __libdwfl_seterrno (DWFL_E_LIBELF);
    451       return -1;
    452     }
    453 
    454   if (dwfl->user_core != NULL)
    455     free (dwfl->user_core->executable_for_core);
    456   if (executable == NULL)
    457     {
    458       if (dwfl->user_core != NULL)
    459 	dwfl->user_core->executable_for_core = NULL;
    460     }
    461   else
    462     {
    463       if (dwfl->user_core == NULL)
    464 	{
    465 	  dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core));
    466 	  if (dwfl->user_core == NULL)
    467 	    {
    468 	      __libdwfl_seterrno (DWFL_E_NOMEM);
    469 	      return -1;
    470 	    }
    471 	  dwfl->user_core->fd = -1;
    472 	}
    473       dwfl->user_core->executable_for_core = strdup (executable);
    474       if (dwfl->user_core->executable_for_core == NULL)
    475 	{
    476 	  __libdwfl_seterrno (DWFL_E_NOMEM);
    477 	  return -1;
    478 	}
    479     }
    480 
    481   /* First report each PT_LOAD segment.  */
    482   GElf_Phdr notes_phdr;
    483   int ndx = dwfl_report_core_segments (dwfl, elf, phnum, &notes_phdr);
    484   if (unlikely (ndx <= 0))
    485     return ndx;
    486 
    487   /* Next, we should follow the chain from DT_DEBUG.  */
    488 
    489   const void *auxv = NULL;
    490   const void *note_file = NULL;
    491   size_t auxv_size = 0;
    492   size_t note_file_size = 0;
    493   if (likely (notes_phdr.p_type == PT_NOTE))
    494     {
    495       /* PT_NOTE -> NT_AUXV -> AT_PHDR -> PT_DYNAMIC -> DT_DEBUG */
    496 
    497       Elf_Data *notes = elf_getdata_rawchunk (elf,
    498 					      notes_phdr.p_offset,
    499 					      notes_phdr.p_filesz,
    500 					      ELF_T_NHDR);
    501       if (likely (notes != NULL))
    502 	{
    503 	  size_t pos = 0;
    504 	  GElf_Nhdr nhdr;
    505 	  size_t name_pos;
    506 	  size_t desc_pos;
    507 	  while ((pos = gelf_getnote (notes, pos, &nhdr,
    508 				      &name_pos, &desc_pos)) > 0)
    509 	    if (nhdr.n_namesz == sizeof "CORE"
    510 		&& !memcmp (notes->d_buf + name_pos, "CORE", sizeof "CORE"))
    511 	      {
    512 		if (nhdr.n_type == NT_AUXV)
    513 		  {
    514 		    auxv = notes->d_buf + desc_pos;
    515 		    auxv_size = nhdr.n_descsz;
    516 		  }
    517 		if (nhdr.n_type == NT_FILE)
    518 		  {
    519 		    note_file = notes->d_buf + desc_pos;
    520 		    note_file_size = nhdr.n_descsz;
    521 		  }
    522 	      }
    523 	}
    524     }
    525 
    526   /* Now we have NT_AUXV contents.  From here on this processing could be
    527      used for a live process with auxv read from /proc.  */
    528 
    529   struct r_debug_info r_debug_info;
    530   memset (&r_debug_info, 0, sizeof r_debug_info);
    531   int retval = dwfl_link_map_report (dwfl, auxv, auxv_size,
    532 				     dwfl_elf_phdr_memory_callback, elf,
    533 				     &r_debug_info);
    534   int listed = retval > 0 ? retval : 0;
    535 
    536   /* Now sniff segment contents for modules hinted by information gathered
    537      from DT_DEBUG.  */
    538 
    539   ndx = 0;
    540   do
    541     {
    542       int seg = dwfl_segment_report_module (dwfl, ndx, NULL,
    543 					    &dwfl_elf_phdr_memory_callback, elf,
    544 					    core_file_read_eagerly, elf,
    545 					    note_file, note_file_size,
    546 					    &r_debug_info);
    547       if (unlikely (seg < 0))
    548 	{
    549 	  clear_r_debug_info (&r_debug_info);
    550 	  return seg;
    551 	}
    552       if (seg > ndx)
    553 	{
    554 	  ndx = seg;
    555 	  ++listed;
    556 	}
    557       else
    558 	++ndx;
    559     }
    560   while (ndx < (int) phnum);
    561 
    562   /* Now report the modules from dwfl_link_map_report which were not filtered
    563      out by dwfl_segment_report_module.  */
    564 
    565   Dwfl_Module **lastmodp = &dwfl->modulelist;
    566   while (*lastmodp != NULL)
    567     lastmodp = &(*lastmodp)->next;
    568   for (struct r_debug_info_module *module = r_debug_info.module;
    569        module != NULL; module = module->next)
    570     {
    571       if (module->elf == NULL)
    572 	continue;
    573       GElf_Addr file_dynamic_vaddr;
    574       if (! __libdwfl_dynamic_vaddr_get (module->elf, &file_dynamic_vaddr))
    575 	continue;
    576       Dwfl_Module *mod;
    577       mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name,
    578 				  module->fd, module->elf,
    579 				  module->l_ld - file_dynamic_vaddr,
    580 				  true, true);
    581       if (mod == NULL)
    582 	continue;
    583       ++listed;
    584       module->elf = NULL;
    585       module->fd = -1;
    586       /* Move this module to the end of the list, so that we end
    587 	 up with a list in the same order as the link_map chain.  */
    588       if (mod->next != NULL)
    589 	{
    590 	  if (*lastmodp != mod)
    591 	    {
    592 	      lastmodp = &dwfl->modulelist;
    593 	      while (*lastmodp != mod)
    594 		lastmodp = &(*lastmodp)->next;
    595 	    }
    596 	  *lastmodp = mod->next;
    597 	  mod->next = NULL;
    598 	  while (*lastmodp != NULL)
    599 	    lastmodp = &(*lastmodp)->next;
    600 	  *lastmodp = mod;
    601 	}
    602       lastmodp = &mod->next;
    603     }
    604 
    605   clear_r_debug_info (&r_debug_info);
    606 
    607   /* We return the number of modules we found if we found any.
    608      If we found none, we return -1 instead of 0 if there was an
    609      error rather than just nothing found.  */
    610   return listed > 0 ? listed : retval;
    611 }
    612 INTDEF (dwfl_core_file_report)
    613 NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
    614 
    615 #ifdef SYMBOL_VERSIONING
    616 int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
    617 COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146,
    618 			 without_executable)
    619 
    620 int
    621 _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf)
    622 {
    623   return dwfl_core_file_report (dwfl, elf, NULL);
    624 }
    625 #endif
    626