272f89ba7f17285b6a0e5a8f9b081d2843f98142
[platform/upstream/elfutils.git] / libdwfl / link_map.c
1 /* Report modules by examining dynamic linker data structures.
2    Copyright (C) 2008-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 "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   for (uint_fast16_t i = 0; i < ehdr.e_phnum; ++i)
537     {
538       GElf_Phdr phdr_mem;
539       GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
540       if (phdr == NULL)
541         break;
542
543       if (phdr->p_align > 1 && (align == 0 || phdr->p_align < align))
544         align = phdr->p_align;
545
546       if (at_phdr != 0
547           && phdr->p_type == PT_LOAD
548           && (phdr->p_offset & -align) == (ehdr.e_phoff & -align))
549         {
550           /* This is the segment that would map the phdrs.
551              If we have an AT_PHDR value, reject this executable
552              if its phdr mapping could not have supplied that.  */
553           if (mod->e_type == ET_EXEC)
554             {
555               if (ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr != at_phdr)
556                 return 0;
557             }
558           else
559             {
560               /* It could be a PIE.  If the AT_PHDR value and our
561                  phdr address don't match modulo ALIGN, then this
562                  could not have been the right PIE.  */
563               if (((ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr) & -align)
564                   != (at_phdr & -align))
565                 return 0;
566
567               /* Calculate the bias applied to the PIE's p_vaddr values.  */
568               GElf_Addr bias = (at_phdr - (ehdr.e_phoff - phdr->p_offset
569                                            + phdr->p_vaddr));
570
571               /* Final sanity check: if we have an AT_ENTRY value,
572                  reject this PIE unless its biased e_entry matches.  */
573               if (at_entry != 0 && at_entry != ehdr.e_entry + bias)
574                 return 0;
575
576               /* If we're changing the module's address range,
577                  we've just invalidated the module lookup table.  */
578               GElf_Addr mod_bias = dwfl_adjusted_address (mod, 0);
579               if (bias != mod_bias)
580                 {
581                   mod->low_addr -= mod_bias;
582                   mod->high_addr -= mod_bias;
583                   mod->low_addr += bias;
584                   mod->high_addr += bias;
585
586                   free (mod->dwfl->lookup_module);
587                   mod->dwfl->lookup_module = NULL;
588                 }
589             }
590         }
591
592       if (phdr->p_type == PT_DYNAMIC)
593         {
594           Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, phdr->p_offset,
595                                                  phdr->p_filesz, ELF_T_DYN);
596           if (data == NULL)
597             continue;
598           const size_t entsize = gelf_fsize (mod->main.elf,
599                                              ELF_T_DYN, 1, EV_CURRENT);
600           const size_t n = data->d_size / entsize;
601           for (size_t j = 0; j < n; ++j)
602             {
603               GElf_Dyn dyn_mem;
604               GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
605               if (dyn != NULL && dyn->d_tag == DT_DEBUG)
606                 {
607                   d_val_vaddr = phdr->p_vaddr + entsize * j + entsize / 2;
608                   break;
609                 }
610             }
611         }
612     }
613
614   if (d_val_vaddr != 0)
615     {
616       /* Now we have the final address from which to read &r_debug.  */
617       d_val_vaddr = dwfl_adjusted_address (mod, d_val_vaddr);
618
619       void *buffer = NULL;
620       size_t buffer_available = addrsize (ehdr.e_ident[EI_CLASS]);
621
622       int segndx = INTUSE(dwfl_addrsegment) (mod->dwfl, d_val_vaddr, NULL);
623
624       if ((*memory_callback) (mod->dwfl, segndx,
625                               &buffer, &buffer_available,
626                               d_val_vaddr, buffer_available,
627                               memory_callback_arg))
628         {
629           const union
630           {
631             Elf32_Addr a32;
632             Elf64_Addr a64;
633           } *u = buffer;
634
635           GElf_Addr vaddr;
636           if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
637             vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
638                      ? BE32 (u->a32) : LE32 (u->a32));
639           else
640             vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
641                      ? BE64 (u->a64) : LE64 (u->a64));
642
643           (*memory_callback) (mod->dwfl, -1, &buffer, &buffer_available, 0, 0,
644                               memory_callback_arg);
645
646           if (*elfclass == ELFCLASSNONE)
647             *elfclass = ehdr.e_ident[EI_CLASS];
648           else if (*elfclass != ehdr.e_ident[EI_CLASS])
649             return 0;
650
651           if (*elfdata == ELFDATANONE)
652             *elfdata = ehdr.e_ident[EI_DATA];
653           else if (*elfdata != ehdr.e_ident[EI_DATA])
654             return 0;
655
656           return vaddr;
657         }
658     }
659
660   return 0;
661 }
662
663 /* Try to find an existing executable module with a DT_DEBUG.  */
664 static GElf_Addr
665 find_executable (Dwfl *dwfl, GElf_Addr at_phdr, GElf_Addr at_entry,
666                  uint_fast8_t *elfclass, uint_fast8_t *elfdata,
667                  Dwfl_Memory_Callback *memory_callback,
668                  void *memory_callback_arg)
669 {
670   for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
671     if (mod->main.elf != NULL)
672       {
673         GElf_Addr r_debug_vaddr = consider_executable (mod, at_phdr, at_entry,
674                                                        elfclass, elfdata,
675                                                        memory_callback,
676                                                        memory_callback_arg);
677         if (r_debug_vaddr != 0)
678           return r_debug_vaddr;
679       }
680
681   return 0;
682 }
683 \f
684
685 int
686 dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
687                       Dwfl_Memory_Callback *memory_callback,
688                       void *memory_callback_arg,
689                       struct r_debug_info *r_debug_info)
690 {
691   GElf_Addr r_debug_vaddr = 0;
692
693   uint_fast8_t elfclass = ELFCLASSNONE;
694   uint_fast8_t elfdata = ELFDATANONE;
695   if (likely (auxv != NULL)
696       && likely (auxv_format_probe (auxv, auxv_size, &elfclass, &elfdata)))
697     {
698       GElf_Addr entry = 0;
699       GElf_Addr phdr = 0;
700       GElf_Xword phent = 0;
701       GElf_Xword phnum = 0;
702
703 #define READ_AUXV32(ptr)        read_4ubyte_unaligned_noncvt (ptr)
704 #define READ_AUXV64(ptr)        read_8ubyte_unaligned_noncvt (ptr)
705 #define AUXV_SCAN(NN, BL) do                                            \
706         {                                                               \
707           const Elf##NN##_auxv_t *av = auxv;                            \
708           for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i)         \
709             {                                                           \
710               uint##NN##_t type = READ_AUXV##NN (&av[i].a_type);        \
711               uint##NN##_t val = BL##NN (READ_AUXV##NN (&av[i].a_un.a_val)); \
712               if (type == BL##NN (AT_ENTRY))                            \
713                 entry = val;                                            \
714               else if (type == BL##NN (AT_PHDR))                        \
715                 phdr = val;                                             \
716               else if (type == BL##NN (AT_PHNUM))                       \
717                 phnum = val;                                            \
718               else if (type == BL##NN (AT_PHENT))                       \
719                 phent = val;                                            \
720               else if (type == BL##NN (AT_PAGESZ))                      \
721                 {                                                       \
722                   if (val > 1                                           \
723                       && (dwfl->segment_align == 0                      \
724                           || val < dwfl->segment_align))                \
725                     dwfl->segment_align = val;                          \
726                 }                                                       \
727             }                                                           \
728         }                                                               \
729       while (0)
730
731       if (elfclass == ELFCLASS32)
732         {
733           if (elfdata == ELFDATA2MSB)
734             AUXV_SCAN (32, BE);
735           else
736             AUXV_SCAN (32, LE);
737         }
738       else
739         {
740           if (elfdata == ELFDATA2MSB)
741             AUXV_SCAN (64, BE);
742           else
743             AUXV_SCAN (64, LE);
744         }
745
746       /* If we found the phdr dimensions, search phdrs for PT_DYNAMIC.  */
747       GElf_Addr dyn_vaddr = 0;
748       GElf_Xword dyn_filesz = 0;
749       GElf_Addr dyn_bias = (GElf_Addr) -1;
750
751       inline bool consider_phdr (GElf_Word type,
752                                  GElf_Addr vaddr, GElf_Xword filesz)
753       {
754         switch (type)
755           {
756           case PT_PHDR:
757             if (dyn_bias == (GElf_Addr) -1
758                 /* Do a sanity check on the putative address.  */
759                 && ((vaddr & (dwfl->segment_align - 1))
760                     == (phdr & (dwfl->segment_align - 1))))
761               {
762                 dyn_bias = phdr - vaddr;
763                 return dyn_vaddr != 0;
764               }
765             break;
766
767           case PT_DYNAMIC:
768             dyn_vaddr = vaddr;
769             dyn_filesz = filesz;
770             return dyn_bias != (GElf_Addr) -1;
771           }
772
773         return false;
774       }
775
776       if (phdr != 0 && phnum != 0)
777         {
778           Dwfl_Module *phdr_mod;
779           int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod);
780           Elf_Data in =
781             {
782               .d_type = ELF_T_PHDR,
783               .d_version = EV_CURRENT,
784               .d_size = phnum * phent,
785               .d_buf = NULL
786             };
787           bool in_ok = (*memory_callback) (dwfl, phdr_segndx, &in.d_buf,
788                                            &in.d_size, phdr, phnum * phent,
789                                            memory_callback_arg);
790           if (! in_ok && dwfl->executable_for_core != NULL)
791             {
792               /* AUXV -> PHDR -> DYNAMIC
793                  Both AUXV and DYNAMIC should be always present in a core file.
794                  PHDR may be missing in core file, try to read it from
795                  EXECUTABLE_FOR_CORE to find where DYNAMIC is located in the
796                  core file.  */
797
798               int fd = open (dwfl->executable_for_core, O_RDONLY);
799               Elf *elf;
800               Dwfl_Error error = DWFL_E_ERRNO;
801               if (fd != -1)
802                 error = __libdw_open_file (&fd, &elf, true, false);
803               if (error != DWFL_E_NOERROR)
804                 {
805                   __libdwfl_seterrno (error);
806                   return false;
807                 }
808               GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
809               if (ehdr == NULL)
810                 {
811                   elf_end (elf);
812                   close (fd);
813                   __libdwfl_seterrno (DWFL_E_LIBELF);
814                   return false;
815                 }
816               if (ehdr->e_phnum != phnum || ehdr->e_phentsize != phent)
817                 {
818                   elf_end (elf);
819                   close (fd);
820                   __libdwfl_seterrno (DWFL_E_BADELF);
821                   return false;
822                 }
823               off_t off = ehdr->e_phoff;
824               assert (in.d_buf == NULL);
825               assert (in.d_size == phnum * phent);
826               in.d_buf = malloc (in.d_size);
827               if (unlikely (in.d_buf == NULL))
828                 {
829                   elf_end (elf);
830                   close (fd);
831                   __libdwfl_seterrno (DWFL_E_NOMEM);
832                   return false;
833                 }
834               ssize_t nread = pread_retry (fd, in.d_buf, in.d_size, off);
835               elf_end (elf);
836               close (fd);
837               if (nread != (ssize_t) in.d_size)
838                 {
839                   free (in.d_buf);
840                   __libdwfl_seterrno (DWFL_E_ERRNO);
841                   return false;
842                 }
843               in_ok = true;
844             }
845           if (in_ok)
846             {
847               union
848               {
849                 Elf32_Phdr p32;
850                 Elf64_Phdr p64;
851                 char data[phnum * phent];
852               } buf;
853               Elf_Data out =
854                 {
855                   .d_type = ELF_T_PHDR,
856                   .d_version = EV_CURRENT,
857                   .d_size = phnum * phent,
858                   .d_buf = &buf
859                 };
860               in.d_size = out.d_size;
861               if (likely ((elfclass == ELFCLASS32
862                            ? elf32_xlatetom : elf64_xlatetom)
863                           (&out, &in, elfdata) != NULL))
864                 {
865                   /* We are looking for PT_DYNAMIC.  */
866                   const union
867                   {
868                     Elf32_Phdr p32[phnum];
869                     Elf64_Phdr p64[phnum];
870                   } *u = (void *) &buf;
871                   if (elfclass == ELFCLASS32)
872                     {
873                       for (size_t i = 0; i < phnum; ++i)
874                         if (consider_phdr (u->p32[i].p_type,
875                                            u->p32[i].p_vaddr,
876                                            u->p32[i].p_filesz))
877                           break;
878                     }
879                   else
880                     {
881                       for (size_t i = 0; i < phnum; ++i)
882                         if (consider_phdr (u->p64[i].p_type,
883                                            u->p64[i].p_vaddr,
884                                            u->p64[i].p_filesz))
885                           break;
886                     }
887                 }
888
889               (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
890                                   memory_callback_arg);
891             }
892           else
893             /* We could not read the executable's phdrs from the
894                memory image.  If we have a presupplied executable,
895                we can still use the AT_PHDR and AT_ENTRY values to
896                verify it, and to adjust its bias if it's a PIE.
897
898                If there was an ET_EXEC module presupplied that contains
899                the AT_PHDR address, then we only consider that one.
900                We'll either accept it if its phdr location and e_entry
901                make sense or reject it if they don't.  If there is no
902                presupplied ET_EXEC, then look for a presupplied module,
903                which might be a PIE (ET_DYN) that needs its bias adjusted.  */
904             r_debug_vaddr = ((phdr_mod == NULL
905                               || phdr_mod->main.elf == NULL
906                               || phdr_mod->e_type != ET_EXEC)
907                              ? find_executable (dwfl, phdr, entry,
908                                                 &elfclass, &elfdata,
909                                                 memory_callback,
910                                                 memory_callback_arg)
911                              : consider_executable (phdr_mod, phdr, entry,
912                                                     &elfclass, &elfdata,
913                                                     memory_callback,
914                                                     memory_callback_arg));
915         }
916
917       /* If we found PT_DYNAMIC, search it for DT_DEBUG.  */
918       if (dyn_filesz != 0)
919         {
920           if (dyn_bias != (GElf_Addr) -1)
921             dyn_vaddr += dyn_bias;
922
923           Elf_Data in =
924             {
925               .d_type = ELF_T_DYN,
926               .d_version = EV_CURRENT,
927               .d_size = dyn_filesz,
928               .d_buf = NULL
929             };
930           int dyn_segndx = dwfl_addrsegment (dwfl, dyn_vaddr, NULL);
931           if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size,
932                                   dyn_vaddr, dyn_filesz, memory_callback_arg))
933             {
934               union
935               {
936                 Elf32_Dyn d32;
937                 Elf64_Dyn d64;
938                 char data[dyn_filesz];
939               } buf;
940               Elf_Data out =
941                 {
942                   .d_type = ELF_T_DYN,
943                   .d_version = EV_CURRENT,
944                   .d_size = dyn_filesz,
945                   .d_buf = &buf
946                 };
947               in.d_size = out.d_size;
948               if (likely ((elfclass == ELFCLASS32
949                            ? elf32_xlatetom : elf64_xlatetom)
950                           (&out, &in, elfdata) != NULL))
951                 {
952                   /* We are looking for DT_DEBUG.  */
953                   const union
954                   {
955                     Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
956                     Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
957                   } *u = (void *) &buf;
958                   if (elfclass == ELFCLASS32)
959                     {
960                       size_t n = dyn_filesz / sizeof (Elf32_Dyn);
961                       for (size_t i = 0; i < n; ++i)
962                         if (u->d32[i].d_tag == DT_DEBUG)
963                           {
964                             r_debug_vaddr = u->d32[i].d_un.d_val;
965                             break;
966                           }
967                     }
968                   else
969                     {
970                       size_t n = dyn_filesz / sizeof (Elf64_Dyn);
971                       for (size_t i = 0; i < n; ++i)
972                         if (u->d64[i].d_tag == DT_DEBUG)
973                           {
974                             r_debug_vaddr = u->d64[i].d_un.d_val;
975                             break;
976                           }
977                     }
978                 }
979
980               (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
981                                   memory_callback_arg);
982             }
983         }
984     }
985   else
986     /* We have to look for a presupplied executable file to determine
987        the vaddr of its dynamic section and DT_DEBUG therein.  */
988     r_debug_vaddr = find_executable (dwfl, 0, 0, &elfclass, &elfdata,
989                                      memory_callback, memory_callback_arg);
990
991   if (r_debug_vaddr == 0)
992     return 0;
993
994   /* For following pointers from struct link_map, we will use an
995      integrated memory access callback that can consult module text
996      elided from the core file.  This is necessary when the l_name
997      pointer for the dynamic linker's own entry is a pointer into the
998      executable's .interp section.  */
999   struct integrated_memory_callback mcb =
1000     {
1001       .memory_callback = memory_callback,
1002       .memory_callback_arg = memory_callback_arg
1003     };
1004
1005   /* Now we can follow the dynamic linker's library list.  */
1006   return report_r_debug (elfclass, elfdata, dwfl, r_debug_vaddr,
1007                          &integrated_memory_callback, &mcb, r_debug_info);
1008 }
1009 INTDEF (dwfl_link_map_report)