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