comparison libunwind/src/AddressSpace.hpp @ 236:c4bab56944e8 llvm-original

LLVM 16
author kono
date Wed, 09 Nov 2022 17:45:10 +0900
parents 79ff65ed7e25
children 1f2b6ac9f198
comparison
equal deleted inserted replaced
232:70dce7da266c 236:c4bab56944e8
1 //===------------------------- AddressSpace.hpp ---------------------------===// 1 //===----------------------------------------------------------------------===//
2 // 2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information. 4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // 6 //
22 #include "dwarf2.h" 22 #include "dwarf2.h"
23 #include "EHHeaderParser.hpp" 23 #include "EHHeaderParser.hpp"
24 #include "Registers.hpp" 24 #include "Registers.hpp"
25 25
26 #ifndef _LIBUNWIND_USE_DLADDR 26 #ifndef _LIBUNWIND_USE_DLADDR
27 #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) 27 #if !(defined(_LIBUNWIND_IS_BAREMETAL) || defined(_WIN32) || defined(_AIX))
28 #define _LIBUNWIND_USE_DLADDR 1 28 #define _LIBUNWIND_USE_DLADDR 1
29 #else 29 #else
30 #define _LIBUNWIND_USE_DLADDR 0 30 #define _LIBUNWIND_USE_DLADDR 0
31 #endif 31 #endif
32 #endif 32 #endif
41 #if defined(_LIBUNWIND_ARM_EHABI) 41 #if defined(_LIBUNWIND_ARM_EHABI)
42 struct EHABIIndexEntry { 42 struct EHABIIndexEntry {
43 uint32_t functionOffset; 43 uint32_t functionOffset;
44 uint32_t data; 44 uint32_t data;
45 }; 45 };
46 #endif
47
48 #if defined(_AIX)
49 namespace libunwind {
50 char *getFuncNameFromTBTable(uintptr_t pc, uint16_t &NameLen,
51 unw_word_t *offset);
52 }
46 #endif 53 #endif
47 54
48 #ifdef __APPLE__ 55 #ifdef __APPLE__
49 56
50 struct dyld_unwind_sections 57 struct dyld_unwind_sections
119 defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) 126 defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
120 // No dso_base for SEH. 127 // No dso_base for SEH.
121 uintptr_t dso_base; 128 uintptr_t dso_base;
122 #endif 129 #endif
123 #if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) 130 #if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
124 uintptr_t text_segment_length; 131 size_t text_segment_length;
125 #endif 132 #endif
126 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) 133 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
127 uintptr_t dwarf_section; 134 uintptr_t dwarf_section;
128 uintptr_t dwarf_section_length; 135 size_t dwarf_section_length;
129 #endif 136 #endif
130 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) 137 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
131 uintptr_t dwarf_index_section; 138 uintptr_t dwarf_index_section;
132 uintptr_t dwarf_index_section_length; 139 size_t dwarf_index_section_length;
133 #endif 140 #endif
134 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) 141 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
135 uintptr_t compact_unwind_section; 142 uintptr_t compact_unwind_section;
136 uintptr_t compact_unwind_section_length; 143 size_t compact_unwind_section_length;
137 #endif 144 #endif
138 #if defined(_LIBUNWIND_ARM_EHABI) 145 #if defined(_LIBUNWIND_ARM_EHABI)
139 uintptr_t arm_section; 146 uintptr_t arm_section;
140 uintptr_t arm_section_length; 147 size_t arm_section_length;
141 #endif 148 #endif
142 }; 149 };
143 150
144 151
145 /// LocalAddressSpace is used as a template parameter to UnwindCursor when 152 /// LocalAddressSpace is used as a template parameter to UnwindCursor when
364 #endif 371 #endif
365 #if !defined(Elf_Addr) 372 #if !defined(Elf_Addr)
366 typedef ElfW(Addr) Elf_Addr; 373 typedef ElfW(Addr) Elf_Addr;
367 #endif 374 #endif
368 375
369 static Elf_Addr calculateImageBase(struct dl_phdr_info *pinfo) {
370 Elf_Addr image_base = pinfo->dlpi_addr;
371 #if defined(__ANDROID__) && __ANDROID_API__ < 18
372 if (image_base == 0) {
373 // Normally, an image base of 0 indicates a non-PIE executable. On
374 // versions of Android prior to API 18, the dynamic linker reported a
375 // dlpi_addr of 0 for PIE executables. Compute the true image base
376 // using the PT_PHDR segment.
377 // See https://github.com/android/ndk/issues/505.
378 for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
379 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
380 if (phdr->p_type == PT_PHDR) {
381 image_base = reinterpret_cast<Elf_Addr>(pinfo->dlpi_phdr) -
382 phdr->p_vaddr;
383 break;
384 }
385 }
386 }
387 #endif
388 return image_base;
389 }
390
391 struct _LIBUNWIND_HIDDEN dl_iterate_cb_data { 376 struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {
392 LocalAddressSpace *addressSpace; 377 LocalAddressSpace *addressSpace;
393 UnwindInfoSections *sects; 378 UnwindInfoSections *sects;
394 uintptr_t targetAddr; 379 uintptr_t targetAddr;
395 }; 380 };
428 *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, 413 *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
429 hdrInfo)) { 414 hdrInfo)) {
430 // .eh_frame_hdr records the start of .eh_frame, but not its size. 415 // .eh_frame_hdr records the start of .eh_frame, but not its size.
431 // Rely on a zero terminator to find the end of the section. 416 // Rely on a zero terminator to find the end of the section.
432 cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; 417 cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
433 cbdata->sects->dwarf_section_length = UINTPTR_MAX; 418 cbdata->sects->dwarf_section_length = SIZE_MAX;
434 return true; 419 return true;
435 } 420 }
436 } 421 }
437 return false; 422 return false;
438 #elif defined(_LIBUNWIND_ARM_EHABI) 423 #elif defined(_LIBUNWIND_ARM_EHABI)
459 #else 444 #else
460 // Avoid warning about unused variable. 445 // Avoid warning about unused variable.
461 (void)pinfo_size; 446 (void)pinfo_size;
462 #endif 447 #endif
463 448
464 Elf_Addr image_base = calculateImageBase(pinfo); 449 Elf_Addr image_base = pinfo->dlpi_addr;
465 450
466 // Most shared objects seen in this callback function likely don't contain the 451 // Most shared objects seen in this callback function likely don't contain the
467 // target address, so optimize for that. Scan for a matching PT_LOAD segment 452 // target address, so optimize for that. Scan for a matching PT_LOAD segment
468 // first and bail when it isn't found. 453 // first and bail when it isn't found.
469 bool found_text = false; 454 bool found_text = false;
504 dyld_unwind_sections dyldInfo; 489 dyld_unwind_sections dyldInfo;
505 if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) { 490 if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
506 info.dso_base = (uintptr_t)dyldInfo.mh; 491 info.dso_base = (uintptr_t)dyldInfo.mh;
507 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) 492 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
508 info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section; 493 info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section;
509 info.dwarf_section_length = dyldInfo.dwarf_section_length; 494 info.dwarf_section_length = (size_t)dyldInfo.dwarf_section_length;
510 #endif 495 #endif
511 info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_section; 496 info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_section;
512 info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; 497 info.compact_unwind_section_length = (size_t)dyldInfo.compact_unwind_section_length;
513 return true; 498 return true;
514 } 499 }
515 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL) 500 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
516 info.dso_base = 0; 501 info.dso_base = 0;
517 // Bare metal is statically linked, so no need to ask the dynamic loader 502 // Bare metal is statically linked, so no need to ask the dynamic loader
518 info.dwarf_section_length = (uintptr_t)(&__eh_frame_end - &__eh_frame_start); 503 info.dwarf_section_length = (size_t)(&__eh_frame_end - &__eh_frame_start);
519 info.dwarf_section = (uintptr_t)(&__eh_frame_start); 504 info.dwarf_section = (uintptr_t)(&__eh_frame_start);
520 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", 505 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p",
521 (void *)info.dwarf_section, (void *)info.dwarf_section_length); 506 (void *)info.dwarf_section, (void *)info.dwarf_section_length);
522 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) 507 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
523 info.dwarf_index_section = (uintptr_t)(&__eh_frame_hdr_start); 508 info.dwarf_index_section = (uintptr_t)(&__eh_frame_hdr_start);
524 info.dwarf_index_section_length = (uintptr_t)(&__eh_frame_hdr_end - &__eh_frame_hdr_start); 509 info.dwarf_index_section_length = (size_t)(&__eh_frame_hdr_end - &__eh_frame_hdr_start);
525 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %p length %p", 510 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: index section %p length %p",
526 (void *)info.dwarf_index_section, (void *)info.dwarf_index_section_length); 511 (void *)info.dwarf_index_section, (void *)info.dwarf_index_section_length);
527 #endif 512 #endif
528 if (info.dwarf_section_length) 513 if (info.dwarf_section_length)
529 return true; 514 return true;
530 #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL) 515 #elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL)
531 // Bare metal is statically linked, so no need to ask the dynamic loader 516 // Bare metal is statically linked, so no need to ask the dynamic loader
532 info.arm_section = (uintptr_t)(&__exidx_start); 517 info.arm_section = (uintptr_t)(&__exidx_start);
533 info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start); 518 info.arm_section_length = (size_t)(&__exidx_end - &__exidx_start);
534 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p", 519 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %p length %p",
535 (void *)info.arm_section, (void *)info.arm_section_length); 520 (void *)info.arm_section, (void *)info.arm_section_length);
536 if (info.arm_section && info.arm_section_length) 521 if (info.arm_section && info.arm_section_length)
537 return true; 522 return true;
538 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32) 523 #elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32)
542 527
543 if (!EnumProcessModules(process, mods, sizeof(mods), &needed)) { 528 if (!EnumProcessModules(process, mods, sizeof(mods), &needed)) {
544 DWORD err = GetLastError(); 529 DWORD err = GetLastError();
545 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: EnumProcessModules failed, " 530 _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: EnumProcessModules failed, "
546 "returned error %d", (int)err); 531 "returned error %d", (int)err);
532 (void)err;
547 return false; 533 return false;
548 } 534 }
549 535
550 for (unsigned i = 0; i < (needed / sizeof(HMODULE)); i++) { 536 for (unsigned i = 0; i < (needed / sizeof(HMODULE)); i++) {
551 PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mods[i]; 537 PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mods[i];
578 // Don't even bother, since Windows has functions that do all this stuff 564 // Don't even bother, since Windows has functions that do all this stuff
579 // for us. 565 // for us.
580 (void)targetAddr; 566 (void)targetAddr;
581 (void)info; 567 (void)info;
582 return true; 568 return true;
569 #elif defined(_LIBUNWIND_SUPPORT_TBTAB_UNWIND)
570 // The traceback table is used for unwinding.
571 (void)targetAddr;
572 (void)info;
573 return true;
583 #elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX) 574 #elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX)
584 int length = 0; 575 int length = 0;
585 info.arm_section = 576 info.arm_section =
586 (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length); 577 (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length);
587 info.arm_section_length = (uintptr_t)length * sizeof(EHABIIndexEntry); 578 info.arm_section_length = (size_t)length * sizeof(EHABIIndexEntry);
588 if (info.arm_section && info.arm_section_length) 579 if (info.arm_section && info.arm_section_length)
589 return true; 580 return true;
590 #elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) 581 #elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
582 // Use DLFO_STRUCT_HAS_EH_DBASE to determine the existence of
583 // `_dl_find_object`. Use _LIBUNWIND_SUPPORT_DWARF_INDEX, because libunwind
584 // support for _dl_find_object on other unwind formats is not implemented,
585 // yet.
586 #if defined(DLFO_STRUCT_HAS_EH_DBASE) & defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
587 // We expect `_dl_find_object` to return PT_GNU_EH_FRAME.
588 #if DLFO_EH_SEGMENT_TYPE != PT_GNU_EH_FRAME
589 #error _dl_find_object retrieves an unexpected section type
590 #endif
591 // We look-up `dl_find_object` dynamically at runtime to ensure backwards
592 // compatibility with earlier version of glibc not yet providing it. On older
593 // systems, we gracefully fallback to `dl_iterate_phdr`. Cache the pointer
594 // so we only look it up once. Do manual lock to avoid _cxa_guard_acquire.
595 static decltype(_dl_find_object) *dlFindObject;
596 static bool dlFindObjectChecked = false;
597 if (!dlFindObjectChecked) {
598 dlFindObject = reinterpret_cast<decltype(_dl_find_object) *>(
599 dlsym(RTLD_DEFAULT, "_dl_find_object"));
600 dlFindObjectChecked = true;
601 }
602 // Try to find the unwind info using `dl_find_object`
603 dl_find_object findResult;
604 if (dlFindObject && dlFindObject((void *)targetAddr, &findResult) == 0) {
605 if (findResult.dlfo_eh_frame == nullptr) {
606 // Found an entry for `targetAddr`, but there is no unwind info.
607 return false;
608 }
609 info.dso_base = reinterpret_cast<uintptr_t>(findResult.dlfo_map_start);
610 info.text_segment_length = static_cast<size_t>(
611 (char *)findResult.dlfo_map_end - (char *)findResult.dlfo_map_start);
612
613 // Record the start of PT_GNU_EH_FRAME.
614 info.dwarf_index_section =
615 reinterpret_cast<uintptr_t>(findResult.dlfo_eh_frame);
616 // `_dl_find_object` does not give us the size of PT_GNU_EH_FRAME.
617 // Setting length to `SIZE_MAX` effectively disables all range checks.
618 info.dwarf_index_section_length = SIZE_MAX;
619 EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
620 if (!EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
621 *this, info.dwarf_index_section, info.dwarf_index_section_length,
622 hdrInfo)) {
623 return false;
624 }
625 // Record the start of the FDE and use SIZE_MAX to indicate that we do
626 // not know the end address.
627 info.dwarf_section = hdrInfo.eh_frame_ptr;
628 info.dwarf_section_length = SIZE_MAX;
629 return true;
630 }
631 #endif
591 dl_iterate_cb_data cb_data = {this, &info, targetAddr}; 632 dl_iterate_cb_data cb_data = {this, &info, targetAddr};
592 int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data); 633 int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
593 return static_cast<bool>(found); 634 return static_cast<bool>(found);
594 #endif 635 #endif
595 636
596 return false; 637 return false;
597 } 638 }
598
599 639
600 inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { 640 inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
601 // TO DO: if OS has way to dynamically register FDEs, check that. 641 // TO DO: if OS has way to dynamically register FDEs, check that.
602 (void)targetAddr; 642 (void)targetAddr;
603 (void)fde; 643 (void)fde;
614 snprintf(buf, bufLen, "%s", dyldInfo.dli_sname); 654 snprintf(buf, bufLen, "%s", dyldInfo.dli_sname);
615 *offset = (addr - (pint_t) dyldInfo.dli_saddr); 655 *offset = (addr - (pint_t) dyldInfo.dli_saddr);
616 return true; 656 return true;
617 } 657 }
618 } 658 }
659 #elif defined(_AIX)
660 uint16_t nameLen;
661 char *funcName = getFuncNameFromTBTable(addr, nameLen, offset);
662 if (funcName != NULL) {
663 snprintf(buf, bufLen, "%.*s", nameLen, funcName);
664 return true;
665 }
619 #else 666 #else
620 (void)addr; 667 (void)addr;
621 (void)buf; 668 (void)buf;
622 (void)bufLen; 669 (void)bufLen;
623 (void)offset; 670 (void)offset;