1 /* Core file handling. 2 Copyright (C) 2008-2010, 2013, 2015 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_ALIGN. */ 31 #undef _ 32 #include "libdwflP.h" 33 #include <gelf.h> 34 35 #include <unistd.h> 36 #include <endian.h> 37 #include <byteswap.h> 38 #include "system.h" 39 40 41 /* On failure return, we update *NEXT to point back at OFFSET. */ 42 static inline Elf * 43 do_fail (int error, off_t *next, off_t offset) 44 { 45 if (next != NULL) 46 *next = offset; 47 //__libelf_seterrno (error); 48 __libdwfl_seterrno (DWFL_E (LIBELF, error)); 49 return NULL; 50 } 51 52 #define fail(error) do_fail (error, next, offset) 53 54 /* This is a prototype of what a new libelf interface might be. 55 This implementation is pessimal for non-mmap cases and should 56 be replaced by more diddling inside libelf internals. */ 57 static Elf * 58 elf_begin_rand (Elf *parent, off_t offset, off_t size, off_t *next) 59 { 60 if (parent == NULL) 61 return NULL; 62 63 off_t min = (parent->kind == ELF_K_ELF ? 64 (parent->class == ELFCLASS32 65 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)) 66 : parent->kind == ELF_K_AR ? SARMAG 67 : 0); 68 69 if (unlikely (offset < min) 70 || unlikely (offset >= (off_t) parent->maximum_size)) 71 return fail (ELF_E_RANGE); 72 73 /* For an archive, fetch just the size field 74 from the archive header to override SIZE. */ 75 if (parent->kind == ELF_K_AR) 76 { 77 struct ar_hdr h = { .ar_size = "" }; 78 79 if (unlikely (parent->maximum_size - offset < sizeof h)) 80 return fail (ELF_E_RANGE); 81 82 if (parent->map_address != NULL) 83 memcpy (h.ar_size, parent->map_address + parent->start_offset + offset, 84 sizeof h.ar_size); 85 else if (unlikely (pread_retry (parent->fildes, 86 h.ar_size, sizeof (h.ar_size), 87 parent->start_offset + offset 88 + offsetof (struct ar_hdr, ar_size)) 89 != sizeof (h.ar_size))) 90 return fail (ELF_E_READ_ERROR); 91 92 offset += sizeof h; 93 94 char *endp; 95 size = strtoll (h.ar_size, &endp, 10); 96 if (unlikely (endp == h.ar_size) 97 || unlikely ((off_t) parent->maximum_size - offset < size)) 98 return fail (ELF_E_INVALID_ARCHIVE); 99 } 100 101 if (unlikely ((off_t) parent->maximum_size - offset < size)) 102 return fail (ELF_E_RANGE); 103 104 /* Even if we fail at this point, update *NEXT to point past the file. */ 105 if (next != NULL) 106 *next = offset + size; 107 108 if (unlikely (offset == 0) 109 && unlikely (size == (off_t) parent->maximum_size)) 110 return elf_clone (parent, parent->cmd); 111 112 /* Note the image is guaranteed live only as long as PARENT 113 lives. Using elf_memory is quite suboptimal if the whole 114 file is not mmap'd. We really should have something like 115 a generalization of the archive support. */ 116 Elf_Data *data = elf_getdata_rawchunk (parent, offset, size, ELF_T_BYTE); 117 if (data == NULL) 118 return NULL; 119 assert ((off_t) data->d_size == size); 120 return elf_memory (data->d_buf, size); 121 } 122 123 124 int 125 dwfl_report_core_segments (Dwfl *dwfl, Elf *elf, size_t phnum, GElf_Phdr *notes) 126 { 127 if (unlikely (dwfl == NULL)) 128 return -1; 129 130 int result = 0; 131 132 if (notes != NULL) 133 notes->p_type = PT_NULL; 134 135 for (size_t ndx = 0; result >= 0 && ndx < phnum; ++ndx) 136 { 137 GElf_Phdr phdr_mem; 138 GElf_Phdr *phdr = gelf_getphdr (elf, ndx, &phdr_mem); 139 if (unlikely (phdr == NULL)) 140 { 141 __libdwfl_seterrno (DWFL_E_LIBELF); 142 return -1; 143 } 144 switch (phdr->p_type) 145 { 146 case PT_LOAD: 147 result = dwfl_report_segment (dwfl, ndx, phdr, 0, NULL); 148 break; 149 150 case PT_NOTE: 151 if (notes != NULL) 152 { 153 *notes = *phdr; 154 notes = NULL; 155 } 156 break; 157 } 158 } 159 160 return result; 161 } 162 163 /* Never read more than this much without mmap. */ 164 #define MAX_EAGER_COST 8192 165 166 /* Dwfl_Module_Callback passed to and called by dwfl_segment_report_module 167 to read in a segment as ELF image directly if possible or indicate an 168 attempt must be made to read in the while segment right now. */ 169 static bool 170 core_file_read_eagerly (Dwfl_Module *mod, 171 void **userdata __attribute__ ((unused)), 172 const char *name __attribute__ ((unused)), 173 Dwarf_Addr start __attribute__ ((unused)), 174 void **buffer, size_t *buffer_available, 175 GElf_Off cost, GElf_Off worthwhile, 176 GElf_Off whole, 177 GElf_Off contiguous __attribute__ ((unused)), 178 void *arg, Elf **elfp) 179 { 180 Elf *core = arg; 181 182 /* The available buffer is often the whole segment when the core file 183 was mmap'd if used together with the dwfl_elf_phdr_memory_callback. 184 Which means that if it is complete we can just construct the whole 185 ELF image right now without having to read in anything more. */ 186 if (whole <= *buffer_available) 187 { 188 /* All there ever was, we already have on hand. */ 189 190 if (core->map_address == NULL) 191 { 192 /* We already malloc'd the buffer. */ 193 *elfp = elf_memory (*buffer, whole); 194 if (unlikely (*elfp == NULL)) 195 return false; 196 197 (*elfp)->flags |= ELF_F_MALLOCED; 198 *buffer = NULL; 199 *buffer_available = 0; 200 return true; 201 } 202 203 /* We can use the image inside the core file directly. */ 204 *elfp = elf_begin_rand (core, *buffer - core->map_address, whole, NULL); 205 *buffer = NULL; 206 *buffer_available = 0; 207 return *elfp != NULL; 208 } 209 210 /* We don't have the whole file. Which either means the core file 211 wasn't mmap'd, but needs to still be read in, or that the segment 212 is truncated. Figure out if this is better than nothing. */ 213 214 if (worthwhile == 0) 215 /* Caller doesn't think so. */ 216 return false; 217 218 /* 219 XXX would like to fall back to partial file via memory 220 when build id find_elf fails 221 also, link_map name may give file name from disk better than partial here 222 requires find_elf hook re-doing the magic to fall back if no file found 223 */ 224 225 if (whole > MAX_EAGER_COST && mod->build_id_len > 0) 226 /* We can't cheaply read the whole file here, so we'd 227 be using a partial file. But there is a build ID that could 228 help us find the whole file, which might be more useful than 229 what we have. We'll just rely on that. */ 230 return false; 231 232 /* The file is either small (most likely the vdso) or big and incomplete, 233 but we don't have a build-id. */ 234 235 if (core->map_address != NULL) 236 /* It's cheap to get, so get it. */ 237 return true; 238 239 /* Only use it if there isn't too much to be read. */ 240 return cost <= MAX_EAGER_COST; 241 } 242 243 static inline void 244 update_end (GElf_Phdr *pphdr, const GElf_Off align, 245 GElf_Off *pend, GElf_Addr *pend_vaddr) 246 { 247 *pend = (pphdr->p_offset + pphdr->p_filesz + align - 1) & -align; 248 *pend_vaddr = (pphdr->p_vaddr + pphdr->p_memsz + align - 1) & -align; 249 } 250 251 /* Use following contiguous segments to get towards SIZE. */ 252 static inline bool 253 do_more (size_t size, GElf_Phdr *pphdr, const GElf_Off align, 254 Elf *elf, GElf_Off start, int *pndx, 255 GElf_Off *pend, GElf_Addr *pend_vaddr) 256 { 257 while (*pend <= start || *pend - start < size) 258 { 259 if (pphdr->p_filesz < pphdr->p_memsz) 260 /* This segment is truncated, so no following one helps us. */ 261 return false; 262 263 if (unlikely (gelf_getphdr (elf, (*pndx)++, pphdr) == NULL)) 264 return false; 265 266 if (pphdr->p_type == PT_LOAD) 267 { 268 if (pphdr->p_offset > *pend 269 || pphdr->p_vaddr > *pend_vaddr) 270 /* It's discontiguous! */ 271 return false; 272 273 update_end (pphdr, align, pend, pend_vaddr); 274 } 275 } 276 return true; 277 } 278 279 #define more(size) do_more (size, &phdr, align, elf, start, &ndx, &end, &end_vaddr) 280 281 bool 282 dwfl_elf_phdr_memory_callback (Dwfl *dwfl, int ndx, 283 void **buffer, size_t *buffer_available, 284 GElf_Addr vaddr, 285 size_t minread, 286 void *arg) 287 { 288 Elf *elf = arg; 289 290 if (ndx == -1) 291 { 292 /* Called for cleanup. */ 293 if (elf->map_address == NULL) 294 free (*buffer); 295 *buffer = NULL; 296 *buffer_available = 0; 297 return false; 298 } 299 300 const GElf_Off align = dwfl->segment_align ?: 1; 301 GElf_Phdr phdr; 302 303 do 304 if (unlikely (gelf_getphdr (elf, ndx++, &phdr) == NULL)) 305 return false; 306 while (phdr.p_type != PT_LOAD 307 || ((phdr.p_vaddr + phdr.p_memsz + align - 1) & -align) <= vaddr); 308 309 GElf_Off start = vaddr - phdr.p_vaddr + phdr.p_offset; 310 GElf_Off end; 311 GElf_Addr end_vaddr; 312 313 update_end (&phdr, align, &end, &end_vaddr); 314 315 /* We need at least this much. */ 316 if (! more (minread)) 317 return false; 318 319 /* See how much more we can get of what the caller wants. */ 320 (void) more (*buffer_available); 321 322 /* If it's already on hand anyway, use as much as there is. */ 323 if (elf->map_address != NULL) 324 (void) more (elf->maximum_size - start); 325 326 /* Make sure we don't look past the end of the actual file, 327 even if the headers tell us to. */ 328 if (unlikely (end > elf->maximum_size)) 329 end = elf->maximum_size; 330 331 /* If the file is too small, there is nothing at all to get. */ 332 if (unlikely (start >= end)) 333 return false; 334 335 if (elf->map_address != NULL) 336 { 337 void *contents = elf->map_address + elf->start_offset + start; 338 size_t size = end - start; 339 340 if (minread == 0) /* String mode. */ 341 { 342 const void *eos = memchr (contents, '\0', size); 343 if (unlikely (eos == NULL) || unlikely (eos == contents)) 344 return false; 345 size = eos + 1 - contents; 346 } 347 348 if (*buffer == NULL) 349 { 350 *buffer = contents; 351 *buffer_available = size; 352 } 353 else 354 { 355 *buffer_available = MIN (size, *buffer_available); 356 memcpy (*buffer, contents, *buffer_available); 357 } 358 } 359 else 360 { 361 void *into = *buffer; 362 if (*buffer == NULL) 363 { 364 *buffer_available = MIN (minread ?: 512, 365 MAX (4096, MIN (end - start, 366 *buffer_available))); 367 into = malloc (*buffer_available); 368 if (unlikely (into == NULL)) 369 { 370 __libdwfl_seterrno (DWFL_E_NOMEM); 371 return false; 372 } 373 } 374 375 ssize_t nread = pread_retry (elf->fildes, into, *buffer_available, start); 376 if (nread < (ssize_t) minread) 377 { 378 if (into != *buffer) 379 free (into); 380 if (nread < 0) 381 __libdwfl_seterrno (DWFL_E_ERRNO); 382 return false; 383 } 384 385 if (minread == 0) /* String mode. */ 386 { 387 const void *eos = memchr (into, '\0', nread); 388 if (unlikely (eos == NULL) || unlikely (eos == into)) 389 { 390 if (*buffer == NULL) 391 free (into); 392 return false; 393 } 394 nread = eos + 1 - into; 395 } 396 397 if (*buffer == NULL) 398 *buffer = into; 399 *buffer_available = nread; 400 } 401 402 return true; 403 } 404 405 /* Free the contents of R_DEBUG_INFO without the R_DEBUG_INFO memory itself. */ 406 407 static void 408 clear_r_debug_info (struct r_debug_info *r_debug_info) 409 { 410 while (r_debug_info->module != NULL) 411 { 412 struct r_debug_info_module *module = r_debug_info->module; 413 r_debug_info->module = module->next; 414 elf_end (module->elf); 415 if (module->fd != -1) 416 close (module->fd); 417 free (module); 418 } 419 } 420 421 bool 422 internal_function 423 __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp) 424 { 425 size_t phnum; 426 if (unlikely (elf_getphdrnum (elf, &phnum) != 0)) 427 return false; 428 for (size_t i = 0; i < phnum; ++i) 429 { 430 GElf_Phdr phdr_mem; 431 GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); 432 if (unlikely (phdr == NULL)) 433 return false; 434 if (phdr->p_type == PT_DYNAMIC) 435 { 436 *vaddrp = phdr->p_vaddr; 437 return true; 438 } 439 } 440 return false; 441 } 442 443 int 444 dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable) 445 { 446 size_t phnum; 447 if (unlikely (elf_getphdrnum (elf, &phnum) != 0)) 448 { 449 __libdwfl_seterrno (DWFL_E_LIBELF); 450 return -1; 451 } 452 453 if (dwfl->user_core != NULL) 454 free (dwfl->user_core->executable_for_core); 455 if (executable == NULL) 456 { 457 if (dwfl->user_core != NULL) 458 dwfl->user_core->executable_for_core = NULL; 459 } 460 else 461 { 462 if (dwfl->user_core == NULL) 463 { 464 dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core)); 465 if (dwfl->user_core == NULL) 466 { 467 __libdwfl_seterrno (DWFL_E_NOMEM); 468 return -1; 469 } 470 dwfl->user_core->fd = -1; 471 } 472 dwfl->user_core->executable_for_core = strdup (executable); 473 if (dwfl->user_core->executable_for_core == NULL) 474 { 475 __libdwfl_seterrno (DWFL_E_NOMEM); 476 return -1; 477 } 478 } 479 480 /* First report each PT_LOAD segment. */ 481 GElf_Phdr notes_phdr; 482 int ndx = dwfl_report_core_segments (dwfl, elf, phnum, ¬es_phdr); 483 if (unlikely (ndx <= 0)) 484 return ndx; 485 486 /* Next, we should follow the chain from DT_DEBUG. */ 487 488 const void *auxv = NULL; 489 const void *note_file = NULL; 490 size_t auxv_size = 0; 491 size_t note_file_size = 0; 492 if (likely (notes_phdr.p_type == PT_NOTE)) 493 { 494 /* PT_NOTE -> NT_AUXV -> AT_PHDR -> PT_DYNAMIC -> DT_DEBUG */ 495 496 Elf_Data *notes = elf_getdata_rawchunk (elf, 497 notes_phdr.p_offset, 498 notes_phdr.p_filesz, 499 (notes_phdr.p_align == 8 500 ? ELF_T_NHDR8 501 : ELF_T_NHDR)); 502 if (likely (notes != NULL)) 503 { 504 size_t pos = 0; 505 GElf_Nhdr nhdr; 506 size_t name_pos; 507 size_t desc_pos; 508 while ((pos = gelf_getnote (notes, pos, &nhdr, 509 &name_pos, &desc_pos)) > 0) 510 if (nhdr.n_namesz == sizeof "CORE" 511 && !memcmp (notes->d_buf + name_pos, "CORE", sizeof "CORE")) 512 { 513 if (nhdr.n_type == NT_AUXV) 514 { 515 auxv = notes->d_buf + desc_pos; 516 auxv_size = nhdr.n_descsz; 517 } 518 if (nhdr.n_type == NT_FILE) 519 { 520 note_file = notes->d_buf + desc_pos; 521 note_file_size = nhdr.n_descsz; 522 } 523 } 524 } 525 } 526 527 /* Now we have NT_AUXV contents. From here on this processing could be 528 used for a live process with auxv read from /proc. */ 529 530 struct r_debug_info r_debug_info; 531 memset (&r_debug_info, 0, sizeof r_debug_info); 532 int retval = dwfl_link_map_report (dwfl, auxv, auxv_size, 533 dwfl_elf_phdr_memory_callback, elf, 534 &r_debug_info); 535 int listed = retval > 0 ? retval : 0; 536 537 /* Now sniff segment contents for modules hinted by information gathered 538 from DT_DEBUG. */ 539 540 ndx = 0; 541 do 542 { 543 int seg = dwfl_segment_report_module (dwfl, ndx, NULL, 544 &dwfl_elf_phdr_memory_callback, elf, 545 core_file_read_eagerly, elf, 546 note_file, note_file_size, 547 &r_debug_info); 548 if (unlikely (seg < 0)) 549 { 550 clear_r_debug_info (&r_debug_info); 551 return seg; 552 } 553 if (seg > ndx) 554 { 555 ndx = seg; 556 ++listed; 557 } 558 else 559 ++ndx; 560 } 561 while (ndx < (int) phnum); 562 563 /* Now report the modules from dwfl_link_map_report which were not filtered 564 out by dwfl_segment_report_module. */ 565 566 Dwfl_Module **lastmodp = &dwfl->modulelist; 567 while (*lastmodp != NULL) 568 lastmodp = &(*lastmodp)->next; 569 for (struct r_debug_info_module *module = r_debug_info.module; 570 module != NULL; module = module->next) 571 { 572 if (module->elf == NULL) 573 continue; 574 GElf_Addr file_dynamic_vaddr; 575 if (! __libdwfl_dynamic_vaddr_get (module->elf, &file_dynamic_vaddr)) 576 continue; 577 Dwfl_Module *mod; 578 mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name, 579 module->fd, module->elf, 580 module->l_ld - file_dynamic_vaddr, 581 true, true); 582 if (mod == NULL) 583 continue; 584 ++listed; 585 module->elf = NULL; 586 module->fd = -1; 587 /* Move this module to the end of the list, so that we end 588 up with a list in the same order as the link_map chain. */ 589 if (mod->next != NULL) 590 { 591 if (*lastmodp != mod) 592 { 593 lastmodp = &dwfl->modulelist; 594 while (*lastmodp != mod) 595 lastmodp = &(*lastmodp)->next; 596 } 597 *lastmodp = mod->next; 598 mod->next = NULL; 599 while (*lastmodp != NULL) 600 lastmodp = &(*lastmodp)->next; 601 *lastmodp = mod; 602 } 603 lastmodp = &mod->next; 604 } 605 606 clear_r_debug_info (&r_debug_info); 607 608 /* We return the number of modules we found if we found any. 609 If we found none, we return -1 instead of 0 if there was an 610 error rather than just nothing found. */ 611 return listed > 0 ? listed : retval; 612 } 613 INTDEF (dwfl_core_file_report) 614 NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158) 615 616 #ifdef SYMBOL_VERSIONING 617 int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf); 618 COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146, 619 without_executable) 620 621 int 622 _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf) 623 { 624 return dwfl_core_file_report (dwfl, elf, NULL); 625 } 626 #endif 627