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