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