1 /* Sniff out modules from ELF headers visible in memory segments.
2 Copyright (C) 2008-2012, 2014, 2015, 2018 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 "../libelf/libelfP.h" /* For NOTE_ALIGN4 and NOTE_ALIGN8. */
31 #undef _
32 #include "libdwflP.h"
33 #include "common.h"
34
35 #include <elf.h>
36 #include <gelf.h>
37 #include <inttypes.h>
38 #include <endian.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41
42 #include <system.h>
43
44
45 /* A good size for the initial read from memory, if it's not too costly.
46 This more than covers the phdrs and note segment in the average 64-bit
47 binary. */
48
49 #define INITIAL_READ 1024
50
51 #if __BYTE_ORDER == __LITTLE_ENDIAN
52 # define MY_ELFDATA ELFDATA2LSB
53 #else
54 # define MY_ELFDATA ELFDATA2MSB
55 #endif
56
57 struct elf_build_id
58 {
59 void *memory;
60 size_t len;
61 GElf_Addr vaddr;
62 };
63
64 struct read_state
65 {
66 Dwfl *dwfl;
67 Dwfl_Memory_Callback *memory_callback;
68 void *memory_callback_arg;
69 void **buffer;
70 size_t *buffer_available;
71 };
72
73 /* Return user segment index closest to ADDR but not above it.
74 If NEXT, return the closest to ADDR but not below it. */
75 static int
addr_segndx(Dwfl * dwfl,size_t segment,GElf_Addr addr,bool next)76 addr_segndx (Dwfl *dwfl, size_t segment, GElf_Addr addr, bool next)
77 {
78 int ndx = -1;
79 do
80 {
81 if (dwfl->lookup_segndx[segment] >= 0)
82 ndx = dwfl->lookup_segndx[segment];
83 if (++segment >= dwfl->lookup_elts - 1)
84 return next ? ndx + 1 : ndx;
85 }
86 while (dwfl->lookup_addr[segment] < addr);
87
88 if (next)
89 {
90 while (dwfl->lookup_segndx[segment] < 0)
91 if (++segment >= dwfl->lookup_elts - 1)
92 return ndx + 1;
93 ndx = dwfl->lookup_segndx[segment];
94 }
95
96 return ndx;
97 }
98
99 /* Return whether there is SZ bytes available at PTR till END. */
100
101 static bool
buf_has_data(const void * ptr,const void * end,size_t sz)102 buf_has_data (const void *ptr, const void *end, size_t sz)
103 {
104 return ptr < end && (size_t) (end - ptr) >= sz;
105 }
106
107 /* Read SZ bytes into *RETP from *PTRP (limited by END) in format EI_DATA.
108 Function comes from src/readelf.c . */
109
110 static bool
buf_read_ulong(unsigned char ei_data,size_t sz,const void ** ptrp,const void * end,uint64_t * retp)111 buf_read_ulong (unsigned char ei_data, size_t sz,
112 const void **ptrp, const void *end, uint64_t *retp)
113 {
114 if (! buf_has_data (*ptrp, end, sz))
115 return false;
116
117 union
118 {
119 uint64_t u64;
120 uint32_t u32;
121 } u;
122
123 memcpy (&u, *ptrp, sz);
124 (*ptrp) += sz;
125
126 if (retp == NULL)
127 return true;
128
129 if (MY_ELFDATA != ei_data)
130 {
131 if (sz == 4)
132 CONVERT (u.u32);
133 else
134 CONVERT (u.u64);
135 }
136 if (sz == 4)
137 *retp = u.u32;
138 else
139 *retp = u.u64;
140 return true;
141 }
142
143 /* Try to find matching entry for module from address MODULE_START to
144 MODULE_END in NT_FILE note located at NOTE_FILE of NOTE_FILE_SIZE
145 bytes in format EI_CLASS and EI_DATA. */
146
147 static const char *
handle_file_note(GElf_Addr module_start,GElf_Addr module_end,unsigned char ei_class,unsigned char ei_data,const void * note_file,size_t note_file_size)148 handle_file_note (GElf_Addr module_start, GElf_Addr module_end,
149 unsigned char ei_class, unsigned char ei_data,
150 const void *note_file, size_t note_file_size)
151 {
152 if (note_file == NULL)
153 return NULL;
154
155 size_t sz;
156 switch (ei_class)
157 {
158 case ELFCLASS32:
159 sz = 4;
160 break;
161 case ELFCLASS64:
162 sz = 8;
163 break;
164 default:
165 return NULL;
166 }
167
168 const void *ptr = note_file;
169 const void *end = note_file + note_file_size;
170 uint64_t count;
171 if (! buf_read_ulong (ei_data, sz, &ptr, end, &count))
172 return NULL;
173 if (! buf_read_ulong (ei_data, sz, &ptr, end, NULL)) // page_size
174 return NULL;
175
176 uint64_t maxcount = (size_t) (end - ptr) / (3 * sz);
177 if (count > maxcount)
178 return NULL;
179
180 /* Where file names are stored. */
181 const char *fptr = ptr + 3 * count * sz;
182
183 ssize_t firstix = -1;
184 ssize_t lastix = -1;
185 for (size_t mix = 0; mix < count; mix++)
186 {
187 uint64_t mstart, mend, moffset;
188 if (! buf_read_ulong (ei_data, sz, &ptr, fptr, &mstart)
189 || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &mend)
190 || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &moffset))
191 return NULL;
192 if (mstart == module_start && moffset == 0)
193 firstix = lastix = mix;
194 if (firstix != -1 && mstart < module_end)
195 lastix = mix;
196 if (mend >= module_end)
197 break;
198 }
199 if (firstix == -1)
200 return NULL;
201
202 const char *retval = NULL;
203 for (ssize_t mix = 0; mix <= lastix; mix++)
204 {
205 const char *fnext = memchr (fptr, 0, (const char *) end - fptr);
206 if (fnext == NULL)
207 return NULL;
208 if (mix == firstix)
209 retval = fptr;
210 if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0)
211 return NULL;
212 fptr = fnext + 1;
213 }
214 return retval;
215 }
216
217 /* Return true iff we are certain ELF cannot match BUILD_ID of
218 BUILD_ID_LEN bytes. Pass DISK_FILE_HAS_BUILD_ID as false if it is
219 certain ELF does not contain build-id (it is only a performance hit
220 to pass it always as true). */
221
222 static bool
invalid_elf(Elf * elf,bool disk_file_has_build_id,struct elf_build_id * build_id)223 invalid_elf (Elf *elf, bool disk_file_has_build_id,
224 struct elf_build_id *build_id)
225 {
226 if (! disk_file_has_build_id && build_id->len > 0)
227 {
228 /* Module found in segments with build-id is more reliable
229 than a module found via DT_DEBUG on disk without any
230 build-id. */
231 return true;
232 }
233 if (disk_file_has_build_id && build_id->len > 0)
234 {
235 const void *elf_build_id;
236 ssize_t elf_build_id_len;
237
238 /* If there is a build id in the elf file, check it. */
239 elf_build_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id);
240 if (elf_build_id_len > 0)
241 {
242 if (build_id->len != (size_t) elf_build_id_len
243 || memcmp (build_id->memory, elf_build_id, build_id->len) != 0)
244 return true;
245 }
246 }
247 return false;
248 }
249
250 static void
finish_portion(struct read_state * read_state,void ** data,size_t * data_size)251 finish_portion (struct read_state *read_state,
252 void **data, size_t *data_size)
253 {
254 if (*data_size != 0 && *data != NULL)
255 (*read_state->memory_callback) (read_state->dwfl, -1, data, data_size,
256 0, 0, read_state->memory_callback_arg);
257 }
258
259 static inline bool
read_portion(struct read_state * read_state,void ** data,size_t * data_size,GElf_Addr start,size_t segment,GElf_Addr vaddr,size_t filesz)260 read_portion (struct read_state *read_state,
261 void **data, size_t *data_size,
262 GElf_Addr start, size_t segment,
263 GElf_Addr vaddr, size_t filesz)
264 {
265 /* Check whether we will have to read the segment data, or if it
266 can be returned from the existing buffer. */
267 if (filesz > *read_state->buffer_available
268 || vaddr - start > *read_state->buffer_available - filesz
269 /* If we're in string mode, then don't consider the buffer we have
270 sufficient unless it contains the terminator of the string. */
271 || (filesz == 0 && memchr (vaddr - start + *read_state->buffer, '\0',
272 (*read_state->buffer_available
273 - (vaddr - start))) == NULL))
274 {
275 *data = NULL;
276 *data_size = filesz;
277 return !(*read_state->memory_callback) (read_state->dwfl,
278 addr_segndx (read_state->dwfl,
279 segment, vaddr,
280 false),
281 data, data_size, vaddr, filesz,
282 read_state->memory_callback_arg);
283 }
284
285 /* We already have this whole note segment from our initial read. */
286 *data = vaddr - start + (*read_state->buffer);
287 *data_size = 0;
288 return false;
289 }
290
291 int
dwfl_segment_report_module(Dwfl * dwfl,int ndx,const char * name,Dwfl_Memory_Callback * memory_callback,void * memory_callback_arg,Dwfl_Module_Callback * read_eagerly,void * read_eagerly_arg,const void * note_file,size_t note_file_size,const struct r_debug_info * r_debug_info)292 dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
293 Dwfl_Memory_Callback *memory_callback,
294 void *memory_callback_arg,
295 Dwfl_Module_Callback *read_eagerly,
296 void *read_eagerly_arg,
297 const void *note_file, size_t note_file_size,
298 const struct r_debug_info *r_debug_info)
299 {
300 size_t segment = ndx;
301 struct read_state read_state;
302
303 if (segment >= dwfl->lookup_elts)
304 segment = dwfl->lookup_elts - 1;
305
306 while (segment > 0
307 && (dwfl->lookup_segndx[segment] > ndx
308 || dwfl->lookup_segndx[segment] == -1))
309 --segment;
310
311 while (dwfl->lookup_segndx[segment] < ndx)
312 if (++segment == dwfl->lookup_elts)
313 return 0;
314
315 GElf_Addr start = dwfl->lookup_addr[segment];
316
317 /* First read in the file header and check its sanity. */
318
319 void *buffer = NULL;
320 size_t buffer_available = INITIAL_READ;
321 Elf *elf = NULL;
322 int fd = -1;
323
324 read_state.dwfl = dwfl;
325 read_state.memory_callback = memory_callback;
326 read_state.memory_callback_arg = memory_callback_arg;
327 read_state.buffer = &buffer;
328 read_state.buffer_available = &buffer_available;
329
330 /* We might have to reserve some memory for the phdrs. Set to NULL
331 here so we can always safely free it. */
332 void *phdrsp = NULL;
333
334 if (! (*memory_callback) (dwfl, ndx, &buffer, &buffer_available,
335 start, sizeof (Elf64_Ehdr), memory_callback_arg)
336 || memcmp (buffer, ELFMAG, SELFMAG) != 0)
337 goto out;
338
339 /* Extract the information we need from the file header. */
340 const unsigned char *e_ident;
341 unsigned char ei_class;
342 unsigned char ei_data;
343 uint16_t e_type;
344 union
345 {
346 Elf32_Ehdr e32;
347 Elf64_Ehdr e64;
348 } ehdr;
349 GElf_Off phoff;
350 uint_fast16_t phnum;
351 uint_fast16_t phentsize;
352 GElf_Off shdrs_end;
353 Elf_Data xlatefrom =
354 {
355 .d_type = ELF_T_EHDR,
356 .d_buf = (void *) buffer,
357 .d_version = EV_CURRENT,
358 };
359 Elf_Data xlateto =
360 {
361 .d_type = ELF_T_EHDR,
362 .d_buf = &ehdr,
363 .d_size = sizeof ehdr,
364 .d_version = EV_CURRENT,
365 };
366 e_ident = ((const unsigned char *) buffer);
367 ei_class = e_ident[EI_CLASS];
368 ei_data = e_ident[EI_DATA];
369 switch (ei_class)
370 {
371 case ELFCLASS32:
372 xlatefrom.d_size = sizeof (Elf32_Ehdr);
373 if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
374 goto out;
375 e_type = ehdr.e32.e_type;
376 phoff = ehdr.e32.e_phoff;
377 phnum = ehdr.e32.e_phnum;
378 phentsize = ehdr.e32.e_phentsize;
379 if (phentsize != sizeof (Elf32_Phdr))
380 goto out;
381 /* NOTE if the number of sections is > 0xff00 then e_shnum
382 is zero and the actual number would come from the section
383 zero sh_size field. We ignore this here because getting shdrs
384 is just a nice bonus (see below in the type == PT_LOAD case
385 where we trim the last segment). */
386 shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
387 break;
388
389 case ELFCLASS64:
390 xlatefrom.d_size = sizeof (Elf64_Ehdr);
391 if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
392 goto out;
393 e_type = ehdr.e64.e_type;
394 phoff = ehdr.e64.e_phoff;
395 phnum = ehdr.e64.e_phnum;
396 phentsize = ehdr.e64.e_phentsize;
397 if (phentsize != sizeof (Elf64_Phdr))
398 goto out;
399 /* See the NOTE above for shdrs_end and ehdr.e32.e_shnum. */
400 shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
401 break;
402
403 default:
404 goto out;
405 }
406
407 /* The file header tells where to find the program headers.
408 These are what we need to find the boundaries of the module.
409 Without them, we don't have a module to report. */
410
411 if (phnum == 0)
412 goto out;
413
414 xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
415 xlatefrom.d_size = phnum * phentsize;
416
417 void *ph_buffer = NULL;
418 size_t ph_buffer_size = 0;
419 if (read_portion (&read_state, &ph_buffer, &ph_buffer_size,
420 start, segment,
421 start + phoff, xlatefrom.d_size))
422 goto out;
423
424 /* ph_buffer_size will be zero if we got everything from the initial
425 buffer, otherwise it will be the size of the new buffer that
426 could be read. */
427 if (ph_buffer_size != 0)
428 xlatefrom.d_size = ph_buffer_size;
429
430 xlatefrom.d_buf = ph_buffer;
431
432 bool class32 = ei_class == ELFCLASS32;
433 size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
434 if (unlikely (phnum > SIZE_MAX / phdr_size))
435 goto out;
436 const size_t phdrsp_bytes = phnum * phdr_size;
437 phdrsp = malloc (phdrsp_bytes);
438 if (unlikely (phdrsp == NULL))
439 goto out;
440
441 xlateto.d_buf = phdrsp;
442 xlateto.d_size = phdrsp_bytes;
443
444 /* Track the bounds of the file visible in memory. */
445 GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
446 GElf_Off file_end = 0; /* Rounded up to effective page size. */
447 GElf_Off contiguous = 0; /* Visible as contiguous file from START. */
448 GElf_Off total_filesz = 0; /* Total size of data to read. */
449
450 /* Collect the bias between START and the containing PT_LOAD's p_vaddr. */
451 GElf_Addr bias = 0;
452 bool found_bias = false;
453
454 /* Collect the unbiased bounds of the module here. */
455 GElf_Addr module_start = -1l;
456 GElf_Addr module_end = 0;
457 GElf_Addr module_address_sync = 0;
458
459 /* If we see PT_DYNAMIC, record it here. */
460 GElf_Addr dyn_vaddr = 0;
461 GElf_Xword dyn_filesz = 0;
462
463 /* Collect the build ID bits here. */
464 struct elf_build_id build_id;
465 build_id.memory = NULL;
466 build_id.len = 0;
467 build_id.vaddr =0;
468
469 Elf32_Phdr *p32 = phdrsp;
470 Elf64_Phdr *p64 = phdrsp;
471 if ((ei_class == ELFCLASS32
472 && elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
473 || (ei_class == ELFCLASS64
474 && elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL))
475 {
476 found_bias = false; /* Trigger error check */
477 }
478 else
479 {
480 /* Consider each of the program headers we've read from the image. */
481 for (uint_fast16_t i = 0; i < phnum; ++i)
482 {
483 bool is32 = (ei_class == ELFCLASS32);
484 GElf_Word type = is32 ? p32[i].p_type : p64[i].p_type;
485 GElf_Addr vaddr = is32 ? p32[i].p_vaddr : p64[i].p_vaddr;
486 GElf_Xword memsz = is32 ? p32[i].p_memsz : p64[i].p_memsz;
487 GElf_Off offset = is32 ? p32[i].p_offset : p64[i].p_offset;
488 GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz;
489 GElf_Xword align = is32 ? p32[i].p_align : p64[i].p_align;
490
491 if (type == PT_DYNAMIC)
492 {
493 dyn_vaddr = vaddr;
494 dyn_filesz = filesz;
495 }
496 else if (type == PT_NOTE)
497 {
498 /* If we have already seen a build ID, we don't care any more. */
499 if (build_id.memory != NULL || filesz == 0)
500 continue; /* Next header */
501
502 /* We calculate from the p_offset of the note segment,
503 because we don't yet know the bias for its p_vaddr. */
504 const GElf_Addr note_vaddr = start + offset;
505 void *data;
506 size_t data_size;
507 if (read_portion (&read_state, &data, &data_size,
508 start, segment, note_vaddr, filesz))
509 continue; /* Next header */
510
511 /* data_size will be zero if we got everything from the initial
512 buffer, otherwise it will be the size of the new buffer that
513 could be read. */
514 if (data_size != 0)
515 filesz = data_size;
516
517 assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
518
519 void *notes;
520 if (ei_data == MY_ELFDATA)
521 notes = data;
522 else
523 {
524 const unsigned int xencoding = ehdr.e32.e_ident[EI_DATA];
525
526 notes = malloc (filesz);
527 if (unlikely (notes == NULL))
528 continue; /* Next header */
529 xlatefrom.d_type = xlateto.d_type = (align == 8
530 ? ELF_T_NHDR8
531 : ELF_T_NHDR);
532 xlatefrom.d_buf = (void *) data;
533 xlatefrom.d_size = filesz;
534 xlateto.d_buf = notes;
535 xlateto.d_size = filesz;
536 if (elf32_xlatetom (&xlateto, &xlatefrom, xencoding) == NULL)
537 {
538 free (notes);
539 finish_portion (&read_state, &data, &data_size);
540 continue;
541 }
542 }
543
544 const GElf_Nhdr *nh = notes;
545 size_t len = 0;
546 while (filesz > len + sizeof (*nh))
547 {
548 const void *note_name;
549 const void *note_desc;
550
551 len += sizeof (*nh);
552 note_name = notes + len;
553
554 len += nh->n_namesz;
555 len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len);
556 note_desc = notes + len;
557
558 if (unlikely (filesz < len + nh->n_descsz))
559 break;
560
561 if (nh->n_type == NT_GNU_BUILD_ID
562 && nh->n_descsz > 0
563 && nh->n_namesz == sizeof "GNU"
564 && !memcmp (note_name, "GNU", sizeof "GNU"))
565 {
566 build_id.vaddr = (note_desc
567 - (const void *) notes
568 + note_vaddr);
569 build_id.len = nh->n_descsz;
570 build_id.memory = malloc (build_id.len);
571 if (likely (build_id.memory != NULL))
572 memcpy (build_id.memory, note_desc, build_id.len);
573 break;
574 }
575
576 len += nh->n_descsz;
577 len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len);
578 nh = (void *) notes + len;
579 }
580
581 if (notes != data)
582 free (notes);
583 finish_portion (&read_state, &data, &data_size);
584 }
585 else if (type == PT_LOAD)
586 {
587 align = (dwfl->segment_align > 1
588 ? dwfl->segment_align : (align ?: 1));
589
590 GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align;
591 GElf_Addr filesz_vaddr = (filesz < memsz
592 ? vaddr + filesz : vaddr_end);
593 GElf_Off filesz_offset = filesz_vaddr - vaddr + offset;
594
595 if (file_trimmed_end < offset + filesz)
596 {
597 file_trimmed_end = offset + filesz;
598
599 /* Trim the last segment so we don't bother with zeros
600 in the last page that are off the end of the file.
601 However, if the extra bit in that page includes the
602 section headers, keep them. */
603 if (shdrs_end <= filesz_offset
604 && shdrs_end > file_trimmed_end)
605 {
606 filesz += shdrs_end - file_trimmed_end;
607 file_trimmed_end = shdrs_end;
608 }
609 }
610
611 total_filesz += filesz;
612
613 if (file_end < filesz_offset)
614 {
615 file_end = filesz_offset;
616 if (filesz_vaddr - start == filesz_offset)
617 contiguous = file_end;
618 }
619
620 if (!found_bias && (offset & -align) == 0
621 && likely (filesz_offset >= phoff + phnum * phentsize))
622 {
623 bias = start - vaddr;
624 found_bias = true;
625 }
626
627 if ((vaddr & -align) < module_start)
628 {
629 module_start = vaddr & -align;
630 module_address_sync = vaddr + memsz;
631 }
632
633 if (module_end < vaddr_end)
634 module_end = vaddr_end;
635 }
636 }
637 }
638
639 finish_portion (&read_state, &ph_buffer, &ph_buffer_size);
640
641 /* We must have seen the segment covering offset 0, or else the ELF
642 header we read at START was not produced by these program headers. */
643 if (unlikely (!found_bias))
644 {
645 free (build_id.memory);
646 goto out;
647 }
648
649 /* Now we know enough to report a module for sure: its bounds. */
650 module_start += bias;
651 module_end += bias;
652
653 dyn_vaddr += bias;
654
655 /* NAME found from link map has precedence over DT_SONAME possibly read
656 below. */
657 bool name_is_final = false;
658
659 /* Try to match up DYN_VADDR against L_LD as found in link map.
660 Segments sniffing may guess invalid address as the first read-only memory
661 mapping may not be dumped to the core file (if ELF headers are not dumped)
662 and the ELF header is dumped first with the read/write mapping of the same
663 file at higher addresses. */
664 if (r_debug_info != NULL)
665 for (const struct r_debug_info_module *module = r_debug_info->module;
666 module != NULL; module = module->next)
667 if (module_start <= module->l_ld && module->l_ld < module_end)
668 {
669 /* L_LD read from link map must be right while DYN_VADDR is unsafe.
670 Therefore subtract DYN_VADDR and add L_LD to get a possibly
671 corrective displacement for all addresses computed so far. */
672 GElf_Addr fixup = module->l_ld - dyn_vaddr;
673 if ((fixup & (dwfl->segment_align - 1)) == 0
674 && module_start + fixup <= module->l_ld
675 && module->l_ld < module_end + fixup)
676 {
677 module_start += fixup;
678 module_end += fixup;
679 dyn_vaddr += fixup;
680 bias += fixup;
681 if (module->name[0] != '\0')
682 {
683 name = basename (module->name);
684 name_is_final = true;
685 }
686 break;
687 }
688 }
689
690 if (r_debug_info != NULL)
691 {
692 bool skip_this_module = false;
693 for (struct r_debug_info_module *module = r_debug_info->module;
694 module != NULL; module = module->next)
695 if ((module_end > module->start && module_start < module->end)
696 || dyn_vaddr == module->l_ld)
697 {
698 if (module->elf != NULL
699 && invalid_elf (module->elf, module->disk_file_has_build_id,
700 &build_id))
701 {
702 elf_end (module->elf);
703 close (module->fd);
704 module->elf = NULL;
705 module->fd = -1;
706 }
707 if (module->elf != NULL)
708 {
709 /* Ignore this found module if it would conflict in address
710 space with any already existing module of DWFL. */
711 skip_this_module = true;
712 }
713 }
714 if (skip_this_module)
715 {
716 free (build_id.memory);
717 goto out;
718 }
719 }
720
721 const char *file_note_name = handle_file_note (module_start, module_end,
722 ei_class, ei_data,
723 note_file, note_file_size);
724 if (file_note_name)
725 {
726 name = file_note_name;
727 name_is_final = true;
728 bool invalid = false;
729 fd = open (name, O_RDONLY);
730 if (fd >= 0)
731 {
732 Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
733 if (error == DWFL_E_NOERROR)
734 invalid = invalid_elf (elf, true /* disk_file_has_build_id */,
735 &build_id);
736 }
737 if (invalid)
738 {
739 /* The file was there, but the build_id didn't match. We
740 still want to report the module, but need to get the ELF
741 some other way if possible. */
742 close (fd);
743 fd = -1;
744 elf_end (elf);
745 elf = NULL;
746 }
747 }
748
749 /* Our return value now says to skip the segments contained
750 within the module. */
751 ndx = addr_segndx (dwfl, segment, module_end, true);
752
753 /* Examine its .dynamic section to get more interesting details.
754 If it has DT_SONAME, we'll use that as the module name.
755 If it has a DT_DEBUG, then it's actually a PIE rather than a DSO.
756 We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME,
757 and they also tell us the essential portion of the file
758 for fetching symbols. */
759 GElf_Addr soname_stroff = 0;
760 GElf_Addr dynstr_vaddr = 0;
761 GElf_Xword dynstrsz = 0;
762 bool execlike = false;
763 const size_t dyn_entsize = (ei_class == ELFCLASS32
764 ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
765 void *dyn_data = NULL;
766 size_t dyn_data_size = 0;
767 if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
768 && ! read_portion (&read_state, &dyn_data, &dyn_data_size,
769 start, segment, dyn_vaddr, dyn_filesz))
770 {
771 /* dyn_data_size will be zero if we got everything from the initial
772 buffer, otherwise it will be the size of the new buffer that
773 could be read. */
774 if (dyn_data_size != 0)
775 dyn_filesz = dyn_data_size;
776
777 void *dyns = malloc (dyn_filesz);
778 Elf32_Dyn *d32 = dyns;
779 Elf64_Dyn *d64 = dyns;
780 if (unlikely (dyns == NULL))
781 goto out;
782
783 xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
784 xlatefrom.d_buf = (void *) dyn_data;
785 xlatefrom.d_size = dyn_filesz;
786 xlateto.d_buf = dyns;
787 xlateto.d_size = dyn_filesz;
788
789 bool is32 = (ei_class == ELFCLASS32);
790 if ((is32 && elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
791 || (!is32 && elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL))
792 {
793 size_t n = (is32
794 ? (dyn_filesz / sizeof (Elf32_Dyn))
795 : (dyn_filesz / sizeof (Elf64_Dyn)));
796 for (size_t i = 0; i < n; ++i)
797 {
798 GElf_Sxword tag = is32 ? d32[i].d_tag : d64[i].d_tag;
799 GElf_Xword val = is32 ? d32[i].d_un.d_val : d64[i].d_un.d_val;
800
801 if (tag == DT_DEBUG)
802 execlike = true;
803 else if (tag == DT_SONAME)
804 soname_stroff = val;
805 else if (tag == DT_STRTAB)
806 dynstr_vaddr = val;
807 else if (tag == DT_STRSZ)
808 dynstrsz = val;
809 else
810 continue;
811
812 if (soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0)
813 break;
814 }
815 }
816 free (dyns);
817 }
818 finish_portion (&read_state, &dyn_data, &dyn_data_size);
819
820 /* We'll use the name passed in or a stupid default if not DT_SONAME. */
821 if (name == NULL)
822 name = e_type == ET_EXEC ? "[exe]" : execlike ? "[pie]" : "[dso]";
823
824 void *soname = NULL;
825 size_t soname_size = 0;
826 if (! name_is_final && dynstrsz != 0 && dynstr_vaddr != 0)
827 {
828 /* We know the bounds of the .dynstr section.
829
830 The DYNSTR_VADDR pointer comes from the .dynamic section
831 (DT_STRTAB, detected above). Ordinarily the dynamic linker
832 will have adjusted this pointer in place so it's now an
833 absolute address. But sometimes .dynamic is read-only (in
834 vDSOs and odd architectures), and sometimes the adjustment
835 just hasn't happened yet in the memory image we looked at.
836 So treat DYNSTR_VADDR as an absolute address if it falls
837 within the module bounds, or try applying the phdr bias
838 when that adjusts it to fall within the module bounds. */
839
840 if ((dynstr_vaddr < module_start || dynstr_vaddr >= module_end)
841 && dynstr_vaddr + bias >= module_start
842 && dynstr_vaddr + bias < module_end)
843 dynstr_vaddr += bias;
844
845 if (unlikely (dynstr_vaddr + dynstrsz > module_end))
846 dynstrsz = 0;
847
848 /* Try to get the DT_SONAME string. */
849 if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz
850 && ! read_portion (&read_state, &soname, &soname_size,
851 start, segment,
852 dynstr_vaddr + soname_stroff, 0))
853 name = soname;
854 }
855
856 /* Now that we have chosen the module's name and bounds, report it.
857 If we found a build ID, report that too. */
858
859 Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, name,
860 module_start, module_end);
861
862 // !execlike && ET_EXEC is PIE.
863 // execlike && !ET_EXEC is a static executable.
864 if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC))
865 mod->is_executable = true;
866
867 if (likely (mod != NULL) && build_id.memory != NULL
868 && unlikely (INTUSE(dwfl_module_report_build_id) (mod,
869 build_id.memory,
870 build_id.len,
871 build_id.vaddr)))
872 {
873 mod->gc = true;
874 mod = NULL;
875 }
876
877 /* At this point we do not need BUILD_ID or NAME any more.
878 They have been copied. */
879 free (build_id.memory);
880 finish_portion (&read_state, &soname, &soname_size);
881
882 if (unlikely (mod == NULL))
883 {
884 ndx = -1;
885 goto out;
886 }
887
888 /* We have reported the module. Now let the caller decide whether we
889 should read the whole thing in right now. */
890
891 const GElf_Off cost = (contiguous < file_trimmed_end ? total_filesz
892 : buffer_available >= contiguous ? 0
893 : contiguous - buffer_available);
894 const GElf_Off worthwhile = ((dynstr_vaddr == 0 || dynstrsz == 0) ? 0
895 : dynstr_vaddr + dynstrsz - start);
896 const GElf_Off whole = MAX (file_trimmed_end, shdrs_end);
897
898 if (elf == NULL
899 && (*read_eagerly) (MODCB_ARGS (mod), &buffer, &buffer_available,
900 cost, worthwhile, whole, contiguous,
901 read_eagerly_arg, &elf)
902 && elf == NULL)
903 {
904 /* The caller wants to read the whole file in right now, but hasn't
905 done it for us. Fill in a local image of the virtual file. */
906
907 void *contents = calloc (1, file_trimmed_end);
908 if (unlikely (contents == NULL))
909 goto out;
910
911 if (contiguous < file_trimmed_end)
912 {
913 /* We can't use the memory image verbatim as the file image.
914 So we'll be reading into a local image of the virtual file. */
915 for (uint_fast16_t i = 0; i < phnum; ++i)
916 {
917 bool is32 = (ei_class == ELFCLASS32);
918 GElf_Word type = is32 ? p32[i].p_type : p64[i].p_type;
919
920 if (type != PT_LOAD)
921 continue;
922
923 GElf_Addr vaddr = is32 ? p32[i].p_vaddr : p64[i].p_vaddr;
924 GElf_Off offset = is32 ? p32[i].p_offset : p64[i].p_offset;
925 GElf_Xword filesz = is32 ? p32[i].p_filesz : p64[i].p_filesz;
926
927 void *into = contents + offset;
928 size_t read_size = filesz;
929 (*memory_callback) (dwfl, addr_segndx (dwfl, segment,
930 vaddr + bias, false),
931 &into, &read_size, vaddr + bias, read_size,
932 memory_callback_arg);
933 }
934 }
935 else
936 {
937 /* The whole file sits contiguous in memory,
938 but the caller didn't want to just do it. */
939
940 const size_t have = MIN (buffer_available, file_trimmed_end);
941 memcpy (contents, buffer, have);
942
943 if (have < file_trimmed_end)
944 {
945 void *into = contents + have;
946 size_t read_size = file_trimmed_end - have;
947 (*memory_callback) (dwfl,
948 addr_segndx (dwfl, segment,
949 start + have, false),
950 &into, &read_size, start + have,
951 read_size, memory_callback_arg);
952 }
953 }
954
955 elf = elf_memory (contents, file_trimmed_end);
956 if (unlikely (elf == NULL))
957 free (contents);
958 else
959 elf->flags |= ELF_F_MALLOCED;
960 }
961
962 if (elf != NULL)
963 {
964 /* Install the file in the module. */
965 mod->main.elf = elf;
966 mod->main.fd = fd;
967 elf = NULL;
968 fd = -1;
969 mod->main.vaddr = module_start - bias;
970 mod->main.address_sync = module_address_sync;
971 mod->main_bias = bias;
972 }
973
974 out:
975 free (phdrsp);
976 if (buffer != NULL)
977 (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
978 memory_callback_arg);
979
980 if (elf != NULL)
981 elf_end (elf);
982 if (fd != -1)
983 close (fd);
984 return ndx;
985 }
986