libdwfl: Reject very short or really large build-ids.
[platform/upstream/elfutils.git] / libdwfl / link_map.c
1 /* Report modules by examining dynamic linker data structures.
2    Copyright (C) 2008-2014 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 "libdwflP.h"
31 #include "../libdw/memory-access.h"
32 #include "system.h"
33
34 #include <byteswap.h>
35 #include <endian.h>
36 #include <fcntl.h>
37
38 /* This element is always provided and always has a constant value.
39    This makes it an easy thing to scan for to discern the format.  */
40 #define PROBE_TYPE      AT_PHENT
41 #define PROBE_VAL32     sizeof (Elf32_Phdr)
42 #define PROBE_VAL64     sizeof (Elf64_Phdr)
43
44
45 /* Examine an auxv data block and determine its format.
46    Return true iff we figured it out.  */
47 static bool
48 auxv_format_probe (const void *auxv, size_t size,
49                    uint_fast8_t *elfclass, uint_fast8_t *elfdata)
50 {
51   const union
52   {
53     char buf[size];
54     Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
55     Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
56   } *u = auxv;
57
58   inline bool check64 (size_t i)
59   {
60     /* The AUXV pointer might not even be naturally aligned for 64-bit
61        data, because note payloads in a core file are not aligned.
62        But we assume the data is 32-bit aligned.  */
63
64     uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type);
65     uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val);
66
67     if (type == BE64 (PROBE_TYPE)
68         && val == BE64 (PROBE_VAL64))
69       {
70         *elfdata = ELFDATA2MSB;
71         return true;
72       }
73
74     if (type == LE64 (PROBE_TYPE)
75         && val == LE64 (PROBE_VAL64))
76       {
77         *elfdata = ELFDATA2LSB;
78         return true;
79       }
80
81     return false;
82   }
83
84   inline bool check32 (size_t i)
85   {
86     if (u->a32[i].a_type == BE32 (PROBE_TYPE)
87         && u->a32[i].a_un.a_val == BE32 (PROBE_VAL32))
88       {
89         *elfdata = ELFDATA2MSB;
90         return true;
91       }
92
93     if (u->a32[i].a_type == LE32 (PROBE_TYPE)
94         && u->a32[i].a_un.a_val == LE32 (PROBE_VAL32))
95       {
96         *elfdata = ELFDATA2LSB;
97         return true;
98       }
99
100     return false;
101   }
102
103   for (size_t i = 0; i < size / sizeof (Elf64_auxv_t); ++i)
104     {
105       if (check64 (i))
106         {
107           *elfclass = ELFCLASS64;
108           return true;
109         }
110
111       if (check32 (i * 2) || check32 (i * 2 + 1))
112         {
113           *elfclass = ELFCLASS32;
114           return true;
115         }
116     }
117
118   return false;
119 }
120 \f
121 /* This is a Dwfl_Memory_Callback that wraps another memory callback.
122    If the underlying callback cannot fill the data, then this will
123    fall back to fetching data from module files.  */
124
125 struct integrated_memory_callback
126 {
127   Dwfl_Memory_Callback *memory_callback;
128   void *memory_callback_arg;
129   void *buffer;
130 };
131
132 static bool
133 integrated_memory_callback (Dwfl *dwfl, int ndx,
134                                void **buffer, size_t *buffer_available,
135                                GElf_Addr vaddr,
136                                size_t minread,
137                                void *arg)
138 {
139   struct integrated_memory_callback *info = arg;
140
141   if (ndx == -1)
142     {
143       /* Called for cleanup.  */
144       if (info->buffer != NULL)
145         {
146           /* The last probe buffer came from the underlying callback.
147              Let it do its cleanup.  */
148           assert (*buffer == info->buffer); /* XXX */
149           *buffer = info->buffer;
150           info->buffer = NULL;
151           return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available,
152                                            vaddr, minread,
153                                            info->memory_callback_arg);
154         }
155       *buffer = NULL;
156       *buffer_available = 0;
157       return false;
158     }
159
160   if (*buffer != NULL)
161     /* For a final-read request, we only use the underlying callback.  */
162     return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available,
163                                      vaddr, minread, info->memory_callback_arg);
164
165   /* Let the underlying callback try to fill this request.  */
166   if ((*info->memory_callback) (dwfl, ndx, &info->buffer, buffer_available,
167                                 vaddr, minread, info->memory_callback_arg))
168     {
169       *buffer = info->buffer;
170       return true;
171     }
172
173   /* Now look for module text covering this address.  */
174
175   Dwfl_Module *mod;
176   (void) INTUSE(dwfl_addrsegment) (dwfl, vaddr, &mod);
177   if (mod == NULL)
178     return false;
179
180   Dwarf_Addr bias;
181   Elf_Scn *scn = INTUSE(dwfl_module_address_section) (mod, &vaddr, &bias);
182   if (unlikely (scn == NULL))
183     {
184 #if 0 // XXX would have to handle ndx=-1 cleanup calls passed down.
185       /* If we have no sections we can try to fill it from the module file
186          based on its phdr mappings.  */
187       if (likely (mod->e_type != ET_REL) && mod->main.elf != NULL)
188         return INTUSE(dwfl_elf_phdr_memory_callback)
189           (dwfl, 0, buffer, buffer_available,
190            vaddr - mod->main.bias, minread, mod->main.elf);
191 #endif
192       return false;
193     }
194
195   Elf_Data *data = elf_rawdata (scn, NULL);
196   if (unlikely (data == NULL))
197     // XXX throw error?
198     return false;
199
200   if (unlikely (data->d_size < vaddr))
201     return false;
202
203   /* Provide as much data as we have.  */
204   void *contents = data->d_buf + vaddr;
205   size_t avail = data->d_size - vaddr;
206   if (unlikely (avail < minread))
207     return false;
208
209   /* If probing for a string, make sure it's terminated.  */
210   if (minread == 0 && unlikely (memchr (contents, '\0', avail) == NULL))
211     return false;
212
213   /* We have it! */
214   *buffer = contents;
215   *buffer_available = avail;
216   return true;
217 }
218 \f
219 static size_t
220 addrsize (uint_fast8_t elfclass)
221 {
222   return elfclass * 4;
223 }
224
225 /* Report a module for each struct link_map in the linked list at r_map
226    in the struct r_debug at R_DEBUG_VADDR.  For r_debug_info description
227    see dwfl_link_map_report in libdwflP.h.  If R_DEBUG_INFO is not NULL then no
228    modules get added to DWFL, caller has to add them from filled in
229    R_DEBUG_INFO.
230
231    For each link_map entry, if an existing module resides at its address,
232    this just modifies that module's name and suggested file name.  If
233    no such module exists, this calls dwfl_report_elf on the l_name string.
234
235    Returns the number of modules found, or -1 for errors.  */
236
237 static int
238 report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
239                 Dwfl *dwfl, GElf_Addr r_debug_vaddr,
240                 Dwfl_Memory_Callback *memory_callback,
241                 void *memory_callback_arg,
242                 struct r_debug_info *r_debug_info)
243 {
244   /* Skip r_version, to aligned r_map field.  */
245   GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass);
246
247   void *buffer = NULL;
248   size_t buffer_available = 0;
249   inline int release_buffer (int result)
250   {
251     if (buffer != NULL)
252       (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
253                                  memory_callback_arg);
254     return result;
255   }
256
257   GElf_Addr addrs[4];
258   inline bool read_addrs (GElf_Addr vaddr, size_t n)
259   {
260     size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read.  */
261
262     /* Read a new buffer if the old one doesn't cover these words.  */
263     if (buffer == NULL
264         || vaddr < read_vaddr
265         || vaddr - read_vaddr + nb > buffer_available)
266       {
267         release_buffer (0);
268
269         read_vaddr = vaddr;
270         int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL);
271         if (unlikely (segndx < 0)
272             || unlikely (! (*memory_callback) (dwfl, segndx,
273                                                &buffer, &buffer_available,
274                                                vaddr, nb, memory_callback_arg)))
275           return true;
276       }
277
278     const union
279     {
280       Elf32_Addr a32[n];
281       Elf64_Addr a64[n];
282     } *in = vaddr - read_vaddr + buffer;
283
284     if (elfclass == ELFCLASS32)
285       {
286         if (elfdata == ELFDATA2MSB)
287           for (size_t i = 0; i < n; ++i)
288             addrs[i] = BE32 (in->a32[i]);
289         else
290           for (size_t i = 0; i < n; ++i)
291             addrs[i] = LE32 (in->a32[i]);
292       }
293     else
294       {
295         if (elfdata == ELFDATA2MSB)
296           for (size_t i = 0; i < n; ++i)
297             addrs[i] = BE64 (in->a64[i]);
298         else
299           for (size_t i = 0; i < n; ++i)
300             addrs[i] = LE64 (in->a64[i]);
301       }
302
303     return false;
304   }
305
306   if (unlikely (read_addrs (read_vaddr, 1)))
307     return release_buffer (-1);
308
309   GElf_Addr next = addrs[0];
310
311   Dwfl_Module **lastmodp = &dwfl->modulelist;
312   int result = 0;
313
314   /* There can't be more elements in the link_map list than there are
315      segments.  DWFL->lookup_elts is probably twice that number, so it
316      is certainly above the upper bound.  If we iterate too many times,
317      there must be a loop in the pointers due to link_map clobberation.  */
318   size_t iterations = 0;
319   while (next != 0 && ++iterations < dwfl->lookup_elts)
320     {
321       if (read_addrs (next, 4))
322         return release_buffer (-1);
323
324       /* Unused: l_addr is the difference between the address in memory
325          and the ELF file when the core was created. We need to
326          recalculate the difference below because the ELF file we use
327          might be differently pre-linked.  */
328       // GElf_Addr l_addr = addrs[0];
329       GElf_Addr l_name = addrs[1];
330       GElf_Addr l_ld = addrs[2];
331       next = addrs[3];
332
333       /* If a clobbered or truncated memory image has no useful pointer,
334          just skip this element.  */
335       if (l_ld == 0)
336         continue;
337
338       /* Fetch the string at the l_name address.  */
339       const char *name = NULL;
340       if (buffer != NULL
341           && read_vaddr <= l_name
342           && l_name + 1 - read_vaddr < buffer_available
343           && memchr (l_name - read_vaddr + buffer, '\0',
344                      buffer_available - (l_name - read_vaddr)) != NULL)
345         name = l_name - read_vaddr + buffer;
346       else
347         {
348           release_buffer (0);
349           read_vaddr = l_name;
350           int segndx = INTUSE(dwfl_addrsegment) (dwfl, l_name, NULL);
351           if (likely (segndx >= 0)
352               && (*memory_callback) (dwfl, segndx,
353                                      &buffer, &buffer_available,
354                                      l_name, 0, memory_callback_arg))
355             name = buffer;
356         }
357
358       if (name != NULL && name[0] == '\0')
359         name = NULL;
360
361       if (iterations == 1 && dwfl->executable_for_core != NULL)
362         name = dwfl->executable_for_core;
363
364       struct r_debug_info_module *r_debug_info_module = NULL;
365       if (r_debug_info != NULL)
366         {
367           /* Save link map information about valid shared library (or
368              executable) which has not been found on disk.  */
369           const char *name1 = name == NULL ? "" : name;
370           r_debug_info_module = malloc (sizeof (*r_debug_info_module)
371                                         + strlen (name1) + 1);
372           if (r_debug_info_module == NULL)
373             return release_buffer (result);
374           r_debug_info_module->fd = -1;
375           r_debug_info_module->elf = NULL;
376           r_debug_info_module->l_ld = l_ld;
377           r_debug_info_module->start = 0;
378           r_debug_info_module->end = 0;
379           r_debug_info_module->disk_file_has_build_id = false;
380           strcpy (r_debug_info_module->name, name1);
381           r_debug_info_module->next = r_debug_info->module;
382           r_debug_info->module = r_debug_info_module;
383         }
384
385       Dwfl_Module *mod = NULL;
386       if (name != NULL)
387         {
388           /* This code is mostly inlined dwfl_report_elf.  */
389           // XXX hook for sysroot
390           int fd = open64 (name, O_RDONLY);
391           if (fd >= 0)
392             {
393               Elf *elf;
394               Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
395               GElf_Addr elf_dynamic_vaddr;
396               if (error == DWFL_E_NOERROR
397                   && __libdwfl_dynamic_vaddr_get (elf, &elf_dynamic_vaddr))
398                 {
399                   const void *build_id_bits;
400                   GElf_Addr build_id_elfaddr;
401                   int build_id_len;
402                   bool valid = true;
403
404                   if (__libdwfl_find_elf_build_id (NULL, elf, &build_id_bits,
405                                                    &build_id_elfaddr,
406                                                    &build_id_len) > 0
407                       && build_id_elfaddr != 0)
408                     {
409                       if (r_debug_info_module != NULL)
410                         r_debug_info_module->disk_file_has_build_id = true;
411                       GElf_Addr build_id_vaddr = (build_id_elfaddr
412                                                   - elf_dynamic_vaddr + l_ld);
413
414                       release_buffer (0);
415                       int segndx = INTUSE(dwfl_addrsegment) (dwfl,
416                                                              build_id_vaddr,
417                                                              NULL);
418                       if (! (*memory_callback) (dwfl, segndx,
419                                                 &buffer, &buffer_available,
420                                                 build_id_vaddr, build_id_len,
421                                                 memory_callback_arg))
422                         {
423                           /* File has valid build-id which cannot be read from
424                              memory.  This happens for core files without bit 4
425                              (0x10) set in Linux /proc/PID/coredump_filter.  */
426                         }
427                       else
428                         {
429                           if (memcmp (build_id_bits, buffer, build_id_len) != 0)
430                             /* File has valid build-id which does not match
431                                the one in memory.  */
432                             valid = false;
433                           release_buffer (0);
434                         }
435                     }
436
437                   if (valid)
438                     {
439                       // It is like l_addr but it handles differently prelinked
440                       // files at core dumping vs. core loading time.
441                       GElf_Addr base = l_ld - elf_dynamic_vaddr;
442                       if (r_debug_info_module == NULL)
443                         {
444                           // XXX hook for sysroot
445                           mod = __libdwfl_report_elf (dwfl, basename (name),
446                                                       name, fd, elf, base,
447                                                       true, true);
448                           if (mod != NULL)
449                             {
450                               elf = NULL;
451                               fd = -1;
452                             }
453                         }
454                       else if (__libdwfl_elf_address_range (elf, base, true,
455                                                             true, NULL, NULL,
456                                                     &r_debug_info_module->start,
457                                                     &r_debug_info_module->end,
458                                                             NULL, NULL))
459                         {
460                           r_debug_info_module->elf = elf;
461                           r_debug_info_module->fd = fd;
462                           elf = NULL;
463                           fd = -1;
464                         }
465                     }
466                   if (elf != NULL)
467                     elf_end (elf);
468                   if (fd != -1)
469                     close (fd);
470                 }
471             }
472         }
473
474       if (mod != NULL)
475         {
476           ++result;
477
478           /* Move this module to the end of the list, so that we end
479              up with a list in the same order as the link_map chain.  */
480           if (mod->next != NULL)
481             {
482               if (*lastmodp != mod)
483                 {
484                   lastmodp = &dwfl->modulelist;
485                   while (*lastmodp != mod)
486                     lastmodp = &(*lastmodp)->next;
487                 }
488               *lastmodp = mod->next;
489               mod->next = NULL;
490               while (*lastmodp != NULL)
491                 lastmodp = &(*lastmodp)->next;
492               *lastmodp = mod;
493             }
494
495           lastmodp = &mod->next;
496         }
497     }
498
499   return release_buffer (result);
500 }
501 \f
502 static GElf_Addr
503 consider_executable (Dwfl_Module *mod, GElf_Addr at_phdr, GElf_Addr at_entry,
504                      uint_fast8_t *elfclass, uint_fast8_t *elfdata,
505                      Dwfl_Memory_Callback *memory_callback,
506                      void *memory_callback_arg)
507 {
508   GElf_Ehdr ehdr;
509   if (unlikely (gelf_getehdr (mod->main.elf, &ehdr) == NULL))
510     return 0;
511
512   if (at_entry != 0)
513     {
514       /* If we have an AT_ENTRY value, reject this executable if
515          its entry point address could not have supplied that.  */
516
517       if (ehdr.e_entry == 0)
518         return 0;
519
520       if (mod->e_type == ET_EXEC)
521         {
522           if (ehdr.e_entry != at_entry)
523             return 0;
524         }
525       else
526         {
527           /* It could be a PIE.  */
528         }
529     }
530
531   // XXX this could be saved in the file cache: phdr vaddr, DT_DEBUG d_val vaddr
532   /* Find the vaddr of the DT_DEBUG's d_ptr.  This is the memory
533      address where &r_debug was written at runtime.  */
534   GElf_Xword align = mod->dwfl->segment_align;
535   GElf_Addr d_val_vaddr = 0;
536   size_t phnum;
537   if (elf_getphdrnum (mod->main.elf, &phnum) != 0)
538     return 0;
539
540   for (size_t i = 0; i < phnum; ++i)
541     {
542       GElf_Phdr phdr_mem;
543       GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
544       if (phdr == NULL)
545         break;
546
547       if (phdr->p_align > 1 && (align == 0 || phdr->p_align < align))
548         align = phdr->p_align;
549
550       if (at_phdr != 0
551           && phdr->p_type == PT_LOAD
552           && (phdr->p_offset & -align) == (ehdr.e_phoff & -align))
553         {
554           /* This is the segment that would map the phdrs.
555              If we have an AT_PHDR value, reject this executable
556              if its phdr mapping could not have supplied that.  */
557           if (mod->e_type == ET_EXEC)
558             {
559               if (ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr != at_phdr)
560                 return 0;
561             }
562           else
563             {
564               /* It could be a PIE.  If the AT_PHDR value and our
565                  phdr address don't match modulo ALIGN, then this
566                  could not have been the right PIE.  */
567               if (((ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr) & -align)
568                   != (at_phdr & -align))
569                 return 0;
570
571               /* Calculate the bias applied to the PIE's p_vaddr values.  */
572               GElf_Addr bias = (at_phdr - (ehdr.e_phoff - phdr->p_offset
573                                            + phdr->p_vaddr));
574
575               /* Final sanity check: if we have an AT_ENTRY value,
576                  reject this PIE unless its biased e_entry matches.  */
577               if (at_entry != 0 && at_entry != ehdr.e_entry + bias)
578                 return 0;
579
580               /* If we're changing the module's address range,
581                  we've just invalidated the module lookup table.  */
582               GElf_Addr mod_bias = dwfl_adjusted_address (mod, 0);
583               if (bias != mod_bias)
584                 {
585                   mod->low_addr -= mod_bias;
586                   mod->high_addr -= mod_bias;
587                   mod->low_addr += bias;
588                   mod->high_addr += bias;
589
590                   free (mod->dwfl->lookup_module);
591                   mod->dwfl->lookup_module = NULL;
592                 }
593             }
594         }
595
596       if (phdr->p_type == PT_DYNAMIC)
597         {
598           Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, phdr->p_offset,
599                                                  phdr->p_filesz, ELF_T_DYN);
600           if (data == NULL)
601             continue;
602           const size_t entsize = gelf_fsize (mod->main.elf,
603                                              ELF_T_DYN, 1, EV_CURRENT);
604           const size_t n = data->d_size / entsize;
605           for (size_t j = 0; j < n; ++j)
606             {
607               GElf_Dyn dyn_mem;
608               GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
609               if (dyn != NULL && dyn->d_tag == DT_DEBUG)
610                 {
611                   d_val_vaddr = phdr->p_vaddr + entsize * j + entsize / 2;
612                   break;
613                 }
614             }
615         }
616     }
617
618   if (d_val_vaddr != 0)
619     {
620       /* Now we have the final address from which to read &r_debug.  */
621       d_val_vaddr = dwfl_adjusted_address (mod, d_val_vaddr);
622
623       void *buffer = NULL;
624       size_t buffer_available = addrsize (ehdr.e_ident[EI_CLASS]);
625
626       int segndx = INTUSE(dwfl_addrsegment) (mod->dwfl, d_val_vaddr, NULL);
627
628       if ((*memory_callback) (mod->dwfl, segndx,
629                               &buffer, &buffer_available,
630                               d_val_vaddr, buffer_available,
631                               memory_callback_arg))
632         {
633           const union
634           {
635             Elf32_Addr a32;
636             Elf64_Addr a64;
637           } *u = buffer;
638
639           GElf_Addr vaddr;
640           if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
641             vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
642                      ? BE32 (u->a32) : LE32 (u->a32));
643           else
644             vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
645                      ? BE64 (u->a64) : LE64 (u->a64));
646
647           (*memory_callback) (mod->dwfl, -1, &buffer, &buffer_available, 0, 0,
648                               memory_callback_arg);
649
650           if (*elfclass == ELFCLASSNONE)
651             *elfclass = ehdr.e_ident[EI_CLASS];
652           else if (*elfclass != ehdr.e_ident[EI_CLASS])
653             return 0;
654
655           if (*elfdata == ELFDATANONE)
656             *elfdata = ehdr.e_ident[EI_DATA];
657           else if (*elfdata != ehdr.e_ident[EI_DATA])
658             return 0;
659
660           return vaddr;
661         }
662     }
663
664   return 0;
665 }
666
667 /* Try to find an existing executable module with a DT_DEBUG.  */
668 static GElf_Addr
669 find_executable (Dwfl *dwfl, GElf_Addr at_phdr, GElf_Addr at_entry,
670                  uint_fast8_t *elfclass, uint_fast8_t *elfdata,
671                  Dwfl_Memory_Callback *memory_callback,
672                  void *memory_callback_arg)
673 {
674   for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
675     if (mod->main.elf != NULL)
676       {
677         GElf_Addr r_debug_vaddr = consider_executable (mod, at_phdr, at_entry,
678                                                        elfclass, elfdata,
679                                                        memory_callback,
680                                                        memory_callback_arg);
681         if (r_debug_vaddr != 0)
682           return r_debug_vaddr;
683       }
684
685   return 0;
686 }
687 \f
688
689 int
690 dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
691                       Dwfl_Memory_Callback *memory_callback,
692                       void *memory_callback_arg,
693                       struct r_debug_info *r_debug_info)
694 {
695   GElf_Addr r_debug_vaddr = 0;
696
697   uint_fast8_t elfclass = ELFCLASSNONE;
698   uint_fast8_t elfdata = ELFDATANONE;
699   if (likely (auxv != NULL)
700       && likely (auxv_format_probe (auxv, auxv_size, &elfclass, &elfdata)))
701     {
702       GElf_Addr entry = 0;
703       GElf_Addr phdr = 0;
704       GElf_Xword phent = 0;
705       GElf_Xword phnum = 0;
706
707 #define READ_AUXV32(ptr)        read_4ubyte_unaligned_noncvt (ptr)
708 #define READ_AUXV64(ptr)        read_8ubyte_unaligned_noncvt (ptr)
709 #define AUXV_SCAN(NN, BL) do                                            \
710         {                                                               \
711           const Elf##NN##_auxv_t *av = auxv;                            \
712           for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i)         \
713             {                                                           \
714               uint##NN##_t type = READ_AUXV##NN (&av[i].a_type);        \
715               uint##NN##_t val = BL##NN (READ_AUXV##NN (&av[i].a_un.a_val)); \
716               if (type == BL##NN (AT_ENTRY))                            \
717                 entry = val;                                            \
718               else if (type == BL##NN (AT_PHDR))                        \
719                 phdr = val;                                             \
720               else if (type == BL##NN (AT_PHNUM))                       \
721                 phnum = val;                                            \
722               else if (type == BL##NN (AT_PHENT))                       \
723                 phent = val;                                            \
724               else if (type == BL##NN (AT_PAGESZ))                      \
725                 {                                                       \
726                   if (val > 1                                           \
727                       && (dwfl->segment_align == 0                      \
728                           || val < dwfl->segment_align))                \
729                     dwfl->segment_align = val;                          \
730                 }                                                       \
731             }                                                           \
732         }                                                               \
733       while (0)
734
735       if (elfclass == ELFCLASS32)
736         {
737           if (elfdata == ELFDATA2MSB)
738             AUXV_SCAN (32, BE);
739           else
740             AUXV_SCAN (32, LE);
741         }
742       else
743         {
744           if (elfdata == ELFDATA2MSB)
745             AUXV_SCAN (64, BE);
746           else
747             AUXV_SCAN (64, LE);
748         }
749
750       /* If we found the phdr dimensions, search phdrs for PT_DYNAMIC.  */
751       GElf_Addr dyn_vaddr = 0;
752       GElf_Xword dyn_filesz = 0;
753       GElf_Addr dyn_bias = (GElf_Addr) -1;
754
755       inline bool consider_phdr (GElf_Word type,
756                                  GElf_Addr vaddr, GElf_Xword filesz)
757       {
758         switch (type)
759           {
760           case PT_PHDR:
761             if (dyn_bias == (GElf_Addr) -1
762                 /* Do a sanity check on the putative address.  */
763                 && ((vaddr & (dwfl->segment_align - 1))
764                     == (phdr & (dwfl->segment_align - 1))))
765               {
766                 dyn_bias = phdr - vaddr;
767                 return dyn_vaddr != 0;
768               }
769             break;
770
771           case PT_DYNAMIC:
772             dyn_vaddr = vaddr;
773             dyn_filesz = filesz;
774             return dyn_bias != (GElf_Addr) -1;
775           }
776
777         return false;
778       }
779
780       if (phdr != 0 && phnum != 0)
781         {
782           Dwfl_Module *phdr_mod;
783           int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod);
784           Elf_Data in =
785             {
786               .d_type = ELF_T_PHDR,
787               .d_version = EV_CURRENT,
788               .d_size = phnum * phent,
789               .d_buf = NULL
790             };
791           bool in_ok = (*memory_callback) (dwfl, phdr_segndx, &in.d_buf,
792                                            &in.d_size, phdr, phnum * phent,
793                                            memory_callback_arg);
794           if (! in_ok && dwfl->executable_for_core != NULL)
795             {
796               /* AUXV -> PHDR -> DYNAMIC
797                  Both AUXV and DYNAMIC should be always present in a core file.
798                  PHDR may be missing in core file, try to read it from
799                  EXECUTABLE_FOR_CORE to find where DYNAMIC is located in the
800                  core file.  */
801
802               int fd = open (dwfl->executable_for_core, O_RDONLY);
803               Elf *elf;
804               Dwfl_Error error = DWFL_E_ERRNO;
805               if (fd != -1)
806                 error = __libdw_open_file (&fd, &elf, true, false);
807               if (error != DWFL_E_NOERROR)
808                 {
809                   __libdwfl_seterrno (error);
810                   return false;
811                 }
812               GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
813               if (ehdr == NULL)
814                 {
815                   elf_end (elf);
816                   close (fd);
817                   __libdwfl_seterrno (DWFL_E_LIBELF);
818                   return false;
819                 }
820               size_t e_phnum;
821               if (elf_getphdrnum (elf, &e_phnum) != 0)
822                 {
823                   elf_end (elf);
824                   close (fd);
825                   __libdwfl_seterrno (DWFL_E_LIBELF);
826                   return false;
827                 }
828               if (e_phnum != phnum || ehdr->e_phentsize != phent)
829                 {
830                   elf_end (elf);
831                   close (fd);
832                   __libdwfl_seterrno (DWFL_E_BADELF);
833                   return false;
834                 }
835               off_t off = ehdr->e_phoff;
836               assert (in.d_buf == NULL);
837               assert (in.d_size == phnum * phent);
838               in.d_buf = malloc (in.d_size);
839               if (unlikely (in.d_buf == NULL))
840                 {
841                   elf_end (elf);
842                   close (fd);
843                   __libdwfl_seterrno (DWFL_E_NOMEM);
844                   return false;
845                 }
846               ssize_t nread = pread_retry (fd, in.d_buf, in.d_size, off);
847               elf_end (elf);
848               close (fd);
849               if (nread != (ssize_t) in.d_size)
850                 {
851                   free (in.d_buf);
852                   __libdwfl_seterrno (DWFL_E_ERRNO);
853                   return false;
854                 }
855               in_ok = true;
856             }
857           if (in_ok)
858             {
859               union
860               {
861                 Elf32_Phdr p32;
862                 Elf64_Phdr p64;
863                 char data[phnum * phent];
864               } buf;
865               Elf_Data out =
866                 {
867                   .d_type = ELF_T_PHDR,
868                   .d_version = EV_CURRENT,
869                   .d_size = phnum * phent,
870                   .d_buf = &buf
871                 };
872               in.d_size = out.d_size;
873               if (likely ((elfclass == ELFCLASS32
874                            ? elf32_xlatetom : elf64_xlatetom)
875                           (&out, &in, elfdata) != NULL))
876                 {
877                   /* We are looking for PT_DYNAMIC.  */
878                   const union
879                   {
880                     Elf32_Phdr p32[phnum];
881                     Elf64_Phdr p64[phnum];
882                   } *u = (void *) &buf;
883                   if (elfclass == ELFCLASS32)
884                     {
885                       for (size_t i = 0; i < phnum; ++i)
886                         if (consider_phdr (u->p32[i].p_type,
887                                            u->p32[i].p_vaddr,
888                                            u->p32[i].p_filesz))
889                           break;
890                     }
891                   else
892                     {
893                       for (size_t i = 0; i < phnum; ++i)
894                         if (consider_phdr (u->p64[i].p_type,
895                                            u->p64[i].p_vaddr,
896                                            u->p64[i].p_filesz))
897                           break;
898                     }
899                 }
900
901               (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
902                                   memory_callback_arg);
903             }
904           else
905             /* We could not read the executable's phdrs from the
906                memory image.  If we have a presupplied executable,
907                we can still use the AT_PHDR and AT_ENTRY values to
908                verify it, and to adjust its bias if it's a PIE.
909
910                If there was an ET_EXEC module presupplied that contains
911                the AT_PHDR address, then we only consider that one.
912                We'll either accept it if its phdr location and e_entry
913                make sense or reject it if they don't.  If there is no
914                presupplied ET_EXEC, then look for a presupplied module,
915                which might be a PIE (ET_DYN) that needs its bias adjusted.  */
916             r_debug_vaddr = ((phdr_mod == NULL
917                               || phdr_mod->main.elf == NULL
918                               || phdr_mod->e_type != ET_EXEC)
919                              ? find_executable (dwfl, phdr, entry,
920                                                 &elfclass, &elfdata,
921                                                 memory_callback,
922                                                 memory_callback_arg)
923                              : consider_executable (phdr_mod, phdr, entry,
924                                                     &elfclass, &elfdata,
925                                                     memory_callback,
926                                                     memory_callback_arg));
927         }
928
929       /* If we found PT_DYNAMIC, search it for DT_DEBUG.  */
930       if (dyn_filesz != 0)
931         {
932           if (dyn_bias != (GElf_Addr) -1)
933             dyn_vaddr += dyn_bias;
934
935           Elf_Data in =
936             {
937               .d_type = ELF_T_DYN,
938               .d_version = EV_CURRENT,
939               .d_size = dyn_filesz,
940               .d_buf = NULL
941             };
942           int dyn_segndx = dwfl_addrsegment (dwfl, dyn_vaddr, NULL);
943           if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size,
944                                   dyn_vaddr, dyn_filesz, memory_callback_arg))
945             {
946               union
947               {
948                 Elf32_Dyn d32;
949                 Elf64_Dyn d64;
950                 char data[dyn_filesz];
951               } buf;
952               Elf_Data out =
953                 {
954                   .d_type = ELF_T_DYN,
955                   .d_version = EV_CURRENT,
956                   .d_size = dyn_filesz,
957                   .d_buf = &buf
958                 };
959               in.d_size = out.d_size;
960               if (likely ((elfclass == ELFCLASS32
961                            ? elf32_xlatetom : elf64_xlatetom)
962                           (&out, &in, elfdata) != NULL))
963                 {
964                   /* We are looking for DT_DEBUG.  */
965                   const union
966                   {
967                     Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
968                     Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
969                   } *u = (void *) &buf;
970                   if (elfclass == ELFCLASS32)
971                     {
972                       size_t n = dyn_filesz / sizeof (Elf32_Dyn);
973                       for (size_t i = 0; i < n; ++i)
974                         if (u->d32[i].d_tag == DT_DEBUG)
975                           {
976                             r_debug_vaddr = u->d32[i].d_un.d_val;
977                             break;
978                           }
979                     }
980                   else
981                     {
982                       size_t n = dyn_filesz / sizeof (Elf64_Dyn);
983                       for (size_t i = 0; i < n; ++i)
984                         if (u->d64[i].d_tag == DT_DEBUG)
985                           {
986                             r_debug_vaddr = u->d64[i].d_un.d_val;
987                             break;
988                           }
989                     }
990                 }
991
992               (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
993                                   memory_callback_arg);
994             }
995         }
996     }
997   else
998     /* We have to look for a presupplied executable file to determine
999        the vaddr of its dynamic section and DT_DEBUG therein.  */
1000     r_debug_vaddr = find_executable (dwfl, 0, 0, &elfclass, &elfdata,
1001                                      memory_callback, memory_callback_arg);
1002
1003   if (r_debug_vaddr == 0)
1004     return 0;
1005
1006   /* For following pointers from struct link_map, we will use an
1007      integrated memory access callback that can consult module text
1008      elided from the core file.  This is necessary when the l_name
1009      pointer for the dynamic linker's own entry is a pointer into the
1010      executable's .interp section.  */
1011   struct integrated_memory_callback mcb =
1012     {
1013       .memory_callback = memory_callback,
1014       .memory_callback_arg = memory_callback_arg
1015     };
1016
1017   /* Now we can follow the dynamic linker's library list.  */
1018   return report_r_debug (elfclass, elfdata, dwfl, r_debug_vaddr,
1019                          &integrated_memory_callback, &mcb, r_debug_info);
1020 }
1021 INTDEF (dwfl_link_map_report)