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