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