authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-16 11:48:54+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-16 12:18:43+01:00
log1e66ac5755ebe8614b8b3a278eabcfca5f78c3c2
tree3a642c70e5cfc6e4c298a1e2c40653c7a0c2e72a
parent8612dac225a55e09293b767aab3c81a459609bb4

Update libunwind

llvm commit b2851aea80e5a8f0cfd6c3c5a56a6b00fb28c6b6

14 files changed, 667 insertions(+), 760 deletions(-)

lib/libunwind/include/libunwind.h+7-1
...@@ -43,6 +43,12 @@...@@ -43,6 +43,12 @@
43 #define LIBUNWIND_AVAIL43 #define LIBUNWIND_AVAIL
44#endif44#endif
4545
46#if defined(_WIN32) && defined(__SEH__)
47 #define LIBUNWIND_CURSOR_ALIGNMENT_ATTR __attribute__((__aligned__(16)))
48#else
49 #define LIBUNWIND_CURSOR_ALIGNMENT_ATTR
50#endif
51
46/* error codes */52/* error codes */
47enum {53enum {
48 UNW_ESUCCESS = 0, /* no error */54 UNW_ESUCCESS = 0, /* no error */
...@@ -68,7 +74,7 @@ typedef struct unw_context_t unw_context_t;...@@ -68,7 +74,7 @@ typedef struct unw_context_t unw_context_t;
6874
69struct unw_cursor_t {75struct unw_cursor_t {
70 uint64_t data[_LIBUNWIND_CURSOR_SIZE];76 uint64_t data[_LIBUNWIND_CURSOR_SIZE];
71};77} LIBUNWIND_CURSOR_ALIGNMENT_ATTR;
72typedef struct unw_cursor_t unw_cursor_t;78typedef struct unw_cursor_t unw_cursor_t;
7379
74typedef struct unw_addr_space *unw_addr_space_t;80typedef struct unw_addr_space *unw_addr_space_t;
lib/libunwind/src/AddressSpace.hpp+98-162
...@@ -17,6 +17,12 @@...@@ -17,6 +17,12 @@
17#include <stdlib.h>17#include <stdlib.h>
18#include <string.h>18#include <string.h>
1919
20#include "libunwind.h"
21#include "config.h"
22#include "dwarf2.h"
23#include "EHHeaderParser.hpp"
24#include "Registers.hpp"
25
20#ifndef _LIBUNWIND_USE_DLADDR26#ifndef _LIBUNWIND_USE_DLADDR
21 #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)27 #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
22 #define _LIBUNWIND_USE_DLADDR 128 #define _LIBUNWIND_USE_DLADDR 1
...@@ -39,19 +45,6 @@ struct EHABIIndexEntry {...@@ -39,19 +45,6 @@ struct EHABIIndexEntry {
39};45};
40#endif46#endif
4147
42#ifdef __APPLE__
43#include <mach-o/getsect.h>
44namespace libunwind {
45 bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde);
46}
47#endif
48
49#include "libunwind.h"
50#include "config.h"
51#include "dwarf2.h"
52#include "EHHeaderParser.hpp"
53#include "Registers.hpp"
54
55#ifdef __APPLE__48#ifdef __APPLE__
5649
57 struct dyld_unwind_sections50 struct dyld_unwind_sections
...@@ -62,43 +55,9 @@ namespace libunwind {...@@ -62,43 +55,9 @@ namespace libunwind {
62 const void* compact_unwind_section;55 const void* compact_unwind_section;
63 uintptr_t compact_unwind_section_length;56 uintptr_t compact_unwind_section_length;
64 };57 };
65 #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \
66 && (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) \
67 || defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
68 // In 10.7.0 or later, libSystem.dylib implements this function.
69 extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
70 #else
71 // In 10.6.x and earlier, we need to implement this functionality. Note
72 // that this requires a newer version of libmacho (from cctools) than is
73 // present in libSystem on 10.6.x (for getsectiondata).
74 static inline bool _dyld_find_unwind_sections(void* addr,
75 dyld_unwind_sections* info) {
76 // Find mach-o image containing address.
77 Dl_info dlinfo;
78 if (!dladdr(addr, &dlinfo))
79 return false;
80#if __LP64__
81 const struct mach_header_64 *mh = (const struct mach_header_64 *)dlinfo.dli_fbase;
82#else
83 const struct mach_header *mh = (const struct mach_header *)dlinfo.dli_fbase;
84#endif
8558
86 // Initialize the return struct59 // In 10.7.0 or later, libSystem.dylib implements this function.
87 info->mh = (const struct mach_header *)mh;60 extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
88 info->dwarf_section = getsectiondata(mh, "__TEXT", "__eh_frame", &info->dwarf_section_length);
89 info->compact_unwind_section = getsectiondata(mh, "__TEXT", "__unwind_info", &info->compact_unwind_section_length);
90
91 if (!info->dwarf_section) {
92 info->dwarf_section_length = 0;
93 }
94
95 if (!info->compact_unwind_section) {
96 info->compact_unwind_section_length = 0;
97 }
98
99 return true;
100 }
101 #endif
10261
103#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)62#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
10463
...@@ -139,22 +98,15 @@ extern char __eh_frame_hdr_end;...@@ -139,22 +98,15 @@ extern char __eh_frame_hdr_end;
139extern char __exidx_start;98extern char __exidx_start;
140extern char __exidx_end;99extern char __exidx_end;
141100
142#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)101#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32)
143102
144// ELF-based systems may use dl_iterate_phdr() to access sections
145// containing unwinding information. The ElfW() macro for pointer-size
146// independent ELF header traversal is not provided by <link.h> on some
147// systems (e.g., FreeBSD). On these systems the data structures are
148// just called Elf_XXX. Define ElfW() locally.
149#ifndef _WIN32
150#include <link.h>
151#else
152#include <windows.h>103#include <windows.h>
153#include <psapi.h>104#include <psapi.h>
154#endif105
155#if !defined(ElfW)106#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) || \
156#define ElfW(type) Elf_##type107 defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX)
157#endif108
109#include <link.h>
158110
159#endif111#endif
160112
...@@ -162,11 +114,15 @@ namespace libunwind {...@@ -162,11 +114,15 @@ namespace libunwind {
162114
163/// Used by findUnwindSections() to return info about needed sections.115/// Used by findUnwindSections() to return info about needed sections.
164struct UnwindInfoSections {116struct UnwindInfoSections {
165#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) || \117#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || \
166 defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)118 defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) || \
167 // No dso_base for SEH or ARM EHABI.119 defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
120 // No dso_base for SEH.
168 uintptr_t dso_base;121 uintptr_t dso_base;
169#endif122#endif
123#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
124 uintptr_t text_segment_length;
125#endif
170#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)126#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
171 uintptr_t dwarf_section;127 uintptr_t dwarf_section;
172 uintptr_t dwarf_section_length;128 uintptr_t dwarf_section_length;
...@@ -290,11 +246,11 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {...@@ -290,11 +246,11 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
290 if (p == pend)246 if (p == pend)
291 _LIBUNWIND_ABORT("truncated sleb128 expression");247 _LIBUNWIND_ABORT("truncated sleb128 expression");
292 byte = *p++;248 byte = *p++;
293 result |= ((byte & 0x7f) << bit);249 result |= (uint64_t)(byte & 0x7f) << bit;
294 bit += 7;250 bit += 7;
295 } while (byte & 0x80);251 } while (byte & 0x80);
296 // sign extend negative numbers252 // sign extend negative numbers
297 if ((byte & 0x40) != 0)253 if ((byte & 0x40) != 0 && bit < 64)
298 result |= (-1ULL) << bit;254 result |= (-1ULL) << bit;
299 addr = (pint_t) p;255 addr = (pint_t) p;
300 return result;256 return result;
...@@ -392,23 +348,14 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,...@@ -392,23 +348,14 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
392 return result;348 return result;
393}349}
394350
395#ifdef __APPLE__351#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
396#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
397#elif defined(_LIBUNWIND_ARM_EHABI) && defined(_LIBUNWIND_IS_BAREMETAL)
398#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_WIN32)
399#elif defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
400#elif defined(_LIBUNWIND_ARM_EHABI) && defined(__BIONIC__)
401// Code inside findUnwindSections handles all these cases.
402//
403// Although the above ifdef chain is ugly, there doesn't seem to be a cleaner
404// way to handle it. The generalized boolean expression is:
405//
406// A OR (B AND C) OR (D AND C) OR (B AND E) OR (F AND E) OR (D AND G)
407//
408// Running it through various boolean expression simplifiers gives expressions
409// that don't help at all.
410#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
411352
353// The ElfW() macro for pointer-size independent ELF header traversal is not
354// provided by <link.h> on some systems (e.g., FreeBSD). On these systems the
355// data structures are just called Elf_XXX. Define ElfW() locally.
356#if !defined(ElfW)
357 #define ElfW(type) Elf_##type
358#endif
412#if !defined(Elf_Half)359#if !defined(Elf_Half)
413 typedef ElfW(Half) Elf_Half;360 typedef ElfW(Half) Elf_Half;
414#endif361#endif
...@@ -447,16 +394,12 @@ struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {...@@ -447,16 +394,12 @@ struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {
447 uintptr_t targetAddr;394 uintptr_t targetAddr;
448};395};
449396
450#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
451 #if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
452 #error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform."
453 #endif
454
455#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)397#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
456#include "FrameHeaderCache.hpp"398#include "FrameHeaderCache.hpp"
457399
458// There should be just one of these per process.400// Typically there is one cache per process, but when libunwind is built as a
459static FrameHeaderCache ProcessFrameHeaderCache;401// hermetic static library, then each shared object may have its own cache.
402static FrameHeaderCache TheFrameHeaderCache;
460#endif403#endif
461404
462static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base,405static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base,
...@@ -466,95 +409,93 @@ static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base,...@@ -466,95 +409,93 @@ static bool checkAddrInSegment(const Elf_Phdr *phdr, size_t image_base,
466 uintptr_t end = begin + phdr->p_memsz;409 uintptr_t end = begin + phdr->p_memsz;
467 if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {410 if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
468 cbdata->sects->dso_base = begin;411 cbdata->sects->dso_base = begin;
469 cbdata->sects->dwarf_section_length = phdr->p_memsz;412 cbdata->sects->text_segment_length = phdr->p_memsz;
470 return true;413 return true;
471 }414 }
472 }415 }
473 return false;416 return false;
474}417}
475418
419static bool checkForUnwindInfoSegment(const Elf_Phdr *phdr, size_t image_base,
420 dl_iterate_cb_data *cbdata) {
421#if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
422 if (phdr->p_type == PT_GNU_EH_FRAME) {
423 EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
424 uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr;
425 cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
426 cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
427 if (EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
428 *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
429 hdrInfo)) {
430 // .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.
432 cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
433 cbdata->sects->dwarf_section_length = UINTPTR_MAX;
434 return true;
435 }
436 }
437 return false;
438#elif defined(_LIBUNWIND_ARM_EHABI)
439 if (phdr->p_type == PT_ARM_EXIDX) {
440 uintptr_t exidx_start = image_base + phdr->p_vaddr;
441 cbdata->sects->arm_section = exidx_start;
442 cbdata->sects->arm_section_length = phdr->p_memsz;
443 return true;
444 }
445 return false;
446#else
447#error Need one of _LIBUNWIND_SUPPORT_DWARF_INDEX or _LIBUNWIND_ARM_EHABI
448#endif
449}
450
476static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo,451static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo,
477 size_t pinfo_size, void *data) {452 size_t pinfo_size, void *data) {
478 auto cbdata = static_cast<dl_iterate_cb_data *>(data);453 auto cbdata = static_cast<dl_iterate_cb_data *>(data);
479 if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr)454 if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr)
480 return 0;455 return 0;
481#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)456#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
482 if (ProcessFrameHeaderCache.find(pinfo, pinfo_size, data))457 if (TheFrameHeaderCache.find(pinfo, pinfo_size, data))
483 return 1;458 return 1;
459#else
460 // Avoid warning about unused variable.
461 (void)pinfo_size;
484#endif462#endif
485463
486 Elf_Addr image_base = calculateImageBase(pinfo);464 Elf_Addr image_base = calculateImageBase(pinfo);
487 bool found_obj = false;
488 bool found_hdr = false;
489465
490 // Third phdr is usually the executable phdr.466 // Most shared objects seen in this callback function likely don't contain the
491 if (pinfo->dlpi_phnum > 2)467 // target address, so optimize for that. Scan for a matching PT_LOAD segment
492 found_obj = checkAddrInSegment(&pinfo->dlpi_phdr[2], image_base, cbdata);468 // first and bail when it isn't found.
469 bool found_text = false;
470 for (Elf_Half i = 0; i < pinfo->dlpi_phnum; ++i) {
471 if (checkAddrInSegment(&pinfo->dlpi_phdr[i], image_base, cbdata)) {
472 found_text = true;
473 break;
474 }
475 }
476 if (!found_text)
477 return 0;
493478
494 // PT_GNU_EH_FRAME is usually near the end. Iterate backward. We already know479 // PT_GNU_EH_FRAME and PT_ARM_EXIDX are usually near the end. Iterate
495 // that there is one or more phdrs.480 // backward.
481 bool found_unwind = false;
496 for (Elf_Half i = pinfo->dlpi_phnum; i > 0; i--) {482 for (Elf_Half i = pinfo->dlpi_phnum; i > 0; i--) {
497 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i - 1];483 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i - 1];
498 if (!found_hdr && phdr->p_type == PT_GNU_EH_FRAME) {484 if (checkForUnwindInfoSegment(phdr, image_base, cbdata)) {
499 EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;485 found_unwind = true;
500 uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr;486 break;
501 cbdata->sects->dwarf_index_section = eh_frame_hdr_start;
502 cbdata->sects->dwarf_index_section_length = phdr->p_memsz;
503 found_hdr = EHHeaderParser<LocalAddressSpace>::decodeEHHdr(
504 *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz,
505 hdrInfo);
506 if (found_hdr)
507 cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr;
508 } else if (!found_obj) {
509 found_obj = checkAddrInSegment(phdr, image_base, cbdata);
510 }
511 if (found_obj && found_hdr) {
512#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
513 ProcessFrameHeaderCache.add(cbdata->sects);
514#endif
515 return 1;
516 }487 }
517 }488 }
518 cbdata->sects->dwarf_section_length = 0;489 if (!found_unwind)
519 return 0;
520}
521
522#else // defined(LIBUNWIND_SUPPORT_DWARF_UNWIND)
523// Given all the #ifdef's above, the code here is for
524// defined(LIBUNWIND_ARM_EHABI)
525
526static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo, size_t,
527 void *data) {
528 auto *cbdata = static_cast<dl_iterate_cb_data *>(data);
529 bool found_obj = false;
530 bool found_hdr = false;
531
532 assert(cbdata);
533 assert(cbdata->sects);
534
535 if (cbdata->targetAddr < pinfo->dlpi_addr)
536 return 0;490 return 0;
537491
538 Elf_Addr image_base = calculateImageBase(pinfo);492#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
539493 TheFrameHeaderCache.add(cbdata->sects);
540 for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {494#endif
541 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];495 return 1;
542 if (phdr->p_type == PT_LOAD) {
543 uintptr_t begin = image_base + phdr->p_vaddr;
544 uintptr_t end = begin + phdr->p_memsz;
545 if (cbdata->targetAddr >= begin && cbdata->targetAddr < end)
546 found_obj = true;
547 } else if (phdr->p_type == PT_ARM_EXIDX) {
548 uintptr_t exidx_start = image_base + phdr->p_vaddr;
549 cbdata->sects->arm_section = exidx_start;
550 cbdata->sects->arm_section_length = phdr->p_memsz;
551 found_hdr = true;
552 }
553 }
554 return found_obj && found_hdr;
555}496}
556#endif // defined(LIBUNWIND_SUPPORT_DWARF_UNWIND)497
557#endif // defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)498#endif // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
558499
559500
560inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,501inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
...@@ -572,6 +513,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,...@@ -572,6 +513,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
572 return true;513 return true;
573 }514 }
574#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)515#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
516 info.dso_base = 0;
575 // Bare metal is statically linked, so no need to ask the dynamic loader517 // Bare metal is statically linked, so no need to ask the dynamic loader
576 info.dwarf_section_length = (uintptr_t)(&__eh_frame_end - &__eh_frame_start);518 info.dwarf_section_length = (uintptr_t)(&__eh_frame_end - &__eh_frame_start);
577 info.dwarf_section = (uintptr_t)(&__eh_frame_start);519 info.dwarf_section = (uintptr_t)(&__eh_frame_start);
...@@ -638,16 +580,14 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,...@@ -638,16 +580,14 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
638 (void)targetAddr;580 (void)targetAddr;
639 (void)info;581 (void)info;
640 return true;582 return true;
641#elif defined(_LIBUNWIND_ARM_EHABI) && defined(__BIONIC__)583#elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX)
642 // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After
643 // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster.
644 int length = 0;584 int length = 0;
645 info.arm_section =585 info.arm_section =
646 (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length);586 (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length);
647 info.arm_section_length = (uintptr_t)length * sizeof(EHABIIndexEntry);587 info.arm_section_length = (uintptr_t)length * sizeof(EHABIIndexEntry);
648 if (info.arm_section && info.arm_section_length)588 if (info.arm_section && info.arm_section_length)
649 return true;589 return true;
650#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)590#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
651 dl_iterate_cb_data cb_data = {this, &info, targetAddr};591 dl_iterate_cb_data cb_data = {this, &info, targetAddr};
652 int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);592 int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
653 return static_cast<bool>(found);593 return static_cast<bool>(found);
...@@ -658,14 +598,10 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,...@@ -658,14 +598,10 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
658598
659599
660inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {600inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
661#ifdef __APPLE__
662 return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde));
663#else
664 // TO DO: if OS has way to dynamically register FDEs, check that.601 // TO DO: if OS has way to dynamically register FDEs, check that.
665 (void)targetAddr;602 (void)targetAddr;
666 (void)fde;603 (void)fde;
667 return false;604 return false;
668#endif
669}605}
670606
671inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,607inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
lib/libunwind/src/DwarfInstructions.hpp+8-1
...@@ -93,7 +93,8 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(...@@ -93,7 +93,8 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
9393
94 case CFI_Parser<A>::kRegisterInRegister:94 case CFI_Parser<A>::kRegisterInRegister:
95 return registers.getRegister((int)savedReg.value);95 return registers.getRegister((int)savedReg.value);
9696 case CFI_Parser<A>::kRegisterUndefined:
97 return 0;
97 case CFI_Parser<A>::kRegisterUnused:98 case CFI_Parser<A>::kRegisterUnused:
98 case CFI_Parser<A>::kRegisterOffsetFromCFA:99 case CFI_Parser<A>::kRegisterOffsetFromCFA:
99 // FIX ME100 // FIX ME
...@@ -117,6 +118,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister(...@@ -117,6 +118,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister(
117118
118 case CFI_Parser<A>::kRegisterIsExpression:119 case CFI_Parser<A>::kRegisterIsExpression:
119 case CFI_Parser<A>::kRegisterUnused:120 case CFI_Parser<A>::kRegisterUnused:
121 case CFI_Parser<A>::kRegisterUndefined:
120 case CFI_Parser<A>::kRegisterOffsetFromCFA:122 case CFI_Parser<A>::kRegisterOffsetFromCFA:
121 case CFI_Parser<A>::kRegisterInRegister:123 case CFI_Parser<A>::kRegisterInRegister:
122 // FIX ME124 // FIX ME
...@@ -140,6 +142,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(...@@ -140,6 +142,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
140142
141 case CFI_Parser<A>::kRegisterIsExpression:143 case CFI_Parser<A>::kRegisterIsExpression:
142 case CFI_Parser<A>::kRegisterUnused:144 case CFI_Parser<A>::kRegisterUnused:
145 case CFI_Parser<A>::kRegisterUndefined:
143 case CFI_Parser<A>::kRegisterOffsetFromCFA:146 case CFI_Parser<A>::kRegisterOffsetFromCFA:
144 case CFI_Parser<A>::kRegisterInRegister:147 case CFI_Parser<A>::kRegisterInRegister:
145 // FIX ME148 // FIX ME
...@@ -190,6 +193,10 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,...@@ -190,6 +193,10 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
190 prolog.savedRegisters[i]));193 prolog.savedRegisters[i]));
191 else194 else
192 return UNW_EBADREG;195 return UNW_EBADREG;
196 } else if (i == (int)cieInfo.returnAddressRegister) {
197 // Leaf function keeps the return address in register and there is no
198 // explicit intructions how to restore it.
199 returnAddress = registers.getRegister(cieInfo.returnAddressRegister);
193 }200 }
194 }201 }
195202
lib/libunwind/src/DwarfParser.hpp+407-404
...@@ -69,6 +69,7 @@ public:...@@ -69,6 +69,7 @@ public:
69 };69 };
70 enum RegisterSavedWhere {70 enum RegisterSavedWhere {
71 kRegisterUnused,71 kRegisterUnused,
72 kRegisterUndefined,
72 kRegisterInCFA,73 kRegisterInCFA,
73 kRegisterOffsetFromCFA,74 kRegisterOffsetFromCFA,
74 kRegisterInRegister,75 kRegisterInRegister,
...@@ -87,9 +88,6 @@ public:...@@ -87,9 +88,6 @@ public:
87 int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset88 int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
88 int64_t cfaExpression; // CFA = expression89 int64_t cfaExpression; // CFA = expression
89 uint32_t spExtraArgSize;90 uint32_t spExtraArgSize;
90 uint32_t codeOffsetAtStackDecrement;
91 bool registersInOtherRegisters;
92 bool sameValueUsed;
93 RegisterLocation savedRegisters[kMaxRegisterNumber + 1];91 RegisterLocation savedRegisters[kMaxRegisterNumber + 1];
94 enum class InitializeTime { kLazy, kNormal };92 enum class InitializeTime { kLazy, kNormal };
9593
...@@ -134,8 +132,26 @@ public:...@@ -134,8 +132,26 @@ public:
134 PrologInfo info;132 PrologInfo info;
135 };133 };
136134
135 struct RememberStack {
136 PrologInfoStackEntry *entry;
137 RememberStack() : entry(nullptr) {}
138 ~RememberStack() {
139#if defined(_LIBUNWIND_REMEMBER_CLEANUP_NEEDED)
140 // Clean up rememberStack. Even in the case where every
141 // DW_CFA_remember_state is paired with a DW_CFA_restore_state,
142 // parseInstructions can skip restore opcodes if it reaches the target PC
143 // and stops interpreting, so we have to make sure we don't leak memory.
144 while (entry) {
145 PrologInfoStackEntry *next = entry->next;
146 _LIBUNWIND_REMEMBER_FREE(entry);
147 entry = next;
148 }
149#endif
150 }
151 };
152
137 static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,153 static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
138 uint32_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo,154 uintptr_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo,
139 CIE_Info *cieInfo);155 CIE_Info *cieInfo);
140 static const char *decodeFDE(A &addressSpace, pint_t fdeStart,156 static const char *decodeFDE(A &addressSpace, pint_t fdeStart,
141 FDE_Info *fdeInfo, CIE_Info *cieInfo);157 FDE_Info *fdeInfo, CIE_Info *cieInfo);
...@@ -144,13 +160,6 @@ public:...@@ -144,13 +160,6 @@ public:
144 int arch, PrologInfo *results);160 int arch, PrologInfo *results);
145161
146 static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo);162 static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo);
147
148private:
149 static bool parseInstructions(A &addressSpace, pint_t instructions,
150 pint_t instructionsEnd, const CIE_Info &cieInfo,
151 pint_t pcoffset,
152 PrologInfoStackEntry *&rememberStack, int arch,
153 PrologInfo *results);
154};163};
155164
156/// Parse a FDE into a CIE_Info and an FDE_Info165/// Parse a FDE into a CIE_Info and an FDE_Info
...@@ -166,7 +175,7 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart,...@@ -166,7 +175,7 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart,
166 p += 8;175 p += 8;
167 }176 }
168 if (cfiLength == 0)177 if (cfiLength == 0)
169 return "FDE has zero length"; // end marker178 return "FDE has zero length"; // zero terminator
170 uint32_t ciePointer = addressSpace.get32(p);179 uint32_t ciePointer = addressSpace.get32(p);
171 if (ciePointer == 0)180 if (ciePointer == 0)
172 return "FDE is really a CIE"; // this is a CIE not an FDE181 return "FDE is really a CIE"; // this is a CIE not an FDE
...@@ -211,11 +220,13 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart,...@@ -211,11 +220,13 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart,
211/// Scan an eh_frame section to find an FDE for a pc220/// Scan an eh_frame section to find an FDE for a pc
212template <typename A>221template <typename A>
213bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,222bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
214 uint32_t sectionLength, pint_t fdeHint,223 uintptr_t sectionLength, pint_t fdeHint,
215 FDE_Info *fdeInfo, CIE_Info *cieInfo) {224 FDE_Info *fdeInfo, CIE_Info *cieInfo) {
216 //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);225 //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);
217 pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart;226 pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart;
218 const pint_t ehSectionEnd = p + sectionLength;227 const pint_t ehSectionEnd = (sectionLength == UINTPTR_MAX)
228 ? static_cast<pint_t>(-1)
229 : (ehSectionStart + sectionLength);
219 while (p < ehSectionEnd) {230 while (p < ehSectionEnd) {
220 pint_t currentCFI = p;231 pint_t currentCFI = p;
221 //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p);232 //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p);
...@@ -227,7 +238,7 @@ bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,...@@ -227,7 +238,7 @@ bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
227 p += 8;238 p += 8;
228 }239 }
229 if (cfiLength == 0)240 if (cfiLength == 0)
230 return false; // end marker241 return false; // zero terminator
231 uint32_t id = addressSpace.get32(p);242 uint32_t id = addressSpace.get32(p);
232 if (id == 0) {243 if (id == 0) {
233 // Skip over CIEs.244 // Skip over CIEs.
...@@ -336,7 +347,8 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,...@@ -336,7 +347,8 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
336 // parse data alignment factor347 // parse data alignment factor
337 cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);348 cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
338 // parse return address register349 // parse return address register
339 uint64_t raReg = addressSpace.getULEB128(p, cieContentEnd);350 uint64_t raReg = (version == 1) ? addressSpace.get8(p++)
351 : addressSpace.getULEB128(p, cieContentEnd);
340 assert(raReg < 255 && "return address register too large");352 assert(raReg < 255 && "return address register too large");
341 cieInfo->returnAddressRegister = (uint8_t)raReg;353 cieInfo->returnAddressRegister = (uint8_t)raReg;
342 // parse augmentation data based on augmentation string354 // parse augmentation data based on augmentation string
...@@ -390,418 +402,409 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,...@@ -390,418 +402,409 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
390 const FDE_Info &fdeInfo,402 const FDE_Info &fdeInfo,
391 const CIE_Info &cieInfo, pint_t upToPC,403 const CIE_Info &cieInfo, pint_t upToPC,
392 int arch, PrologInfo *results) {404 int arch, PrologInfo *results) {
393 PrologInfoStackEntry *rememberStack = NULL;405 // Alloca is used for the allocation of the rememberStack entries. It removes
394406 // the dependency on new/malloc but the below for loop can not be refactored
395 // parse CIE then FDE instructions407 // into functions. Entry could be saved during the processing of a CIE and
396 bool returnValue =408 // restored by an FDE.
397 parseInstructions(addressSpace, cieInfo.cieInstructions,409 RememberStack rememberStack;
398 cieInfo.cieStart + cieInfo.cieLength, cieInfo,410
399 (pint_t)(-1), rememberStack, arch, results) &&411 struct ParseInfo {
400 parseInstructions(addressSpace, fdeInfo.fdeInstructions,412 pint_t instructions;
401 fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo,413 pint_t instructionsEnd;
402 upToPC - fdeInfo.pcStart, rememberStack, arch, results);414 pint_t pcoffset;
403415 };
404#if !defined(_LIBUNWIND_NO_HEAP)
405 // Clean up rememberStack. Even in the case where every DW_CFA_remember_state
406 // is paired with a DW_CFA_restore_state, parseInstructions can skip restore
407 // opcodes if it reaches the target PC and stops interpreting, so we have to
408 // make sure we don't leak memory.
409 while (rememberStack) {
410 PrologInfoStackEntry *next = rememberStack->next;
411 free(rememberStack);
412 rememberStack = next;
413 }
414#endif
415
416 return returnValue;
417}
418416
419/// "run" the DWARF instructions417 ParseInfo parseInfoArray[] = {
420template <typename A>418 {cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength,
421bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,419 (pint_t)(-1)},
422 pint_t instructionsEnd,420 {fdeInfo.fdeInstructions, fdeInfo.fdeStart + fdeInfo.fdeLength,
423 const CIE_Info &cieInfo, pint_t pcoffset,421 upToPC - fdeInfo.pcStart}};
424 PrologInfoStackEntry *&rememberStack,422
425 int arch, PrologInfo *results) {423 for (const auto &info : parseInfoArray) {
426 pint_t p = instructions;424 pint_t p = info.instructions;
427 pint_t codeOffset = 0;425 pint_t instructionsEnd = info.instructionsEnd;
428 // initialState initialized as registers in results are modified. Use426 pint_t pcoffset = info.pcoffset;
429 // PrologInfo accessor functions to avoid reading uninitialized data.427 pint_t codeOffset = 0;
430 PrologInfo initialState(PrologInfo::InitializeTime::kLazy);428
431429 // initialState initialized as registers in results are modified. Use
432 _LIBUNWIND_TRACE_DWARF("parseInstructions(instructions=0x%0" PRIx64 ")\n",430 // PrologInfo accessor functions to avoid reading uninitialized data.
433 static_cast<uint64_t>(instructionsEnd));431 PrologInfo initialState(PrologInfo::InitializeTime::kLazy);
434432
435 // see DWARF Spec, section 6.4.2 for details on unwind opcodes433 _LIBUNWIND_TRACE_DWARF("parseFDEInstructions(instructions=0x%0" PRIx64
436 while ((p < instructionsEnd) && (codeOffset < pcoffset)) {434 ")\n",
437 uint64_t reg;435 static_cast<uint64_t>(instructionsEnd));
438 uint64_t reg2;436
439 int64_t offset;437 // see DWARF Spec, section 6.4.2 for details on unwind opcodes
440 uint64_t length;438 while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
441 uint8_t opcode = addressSpace.get8(p);439 uint64_t reg;
442 uint8_t operand;440 uint64_t reg2;
443#if !defined(_LIBUNWIND_NO_HEAP)441 int64_t offset;
444 PrologInfoStackEntry *entry;442 uint64_t length;
445#endif443 uint8_t opcode = addressSpace.get8(p);
446 ++p;444 uint8_t operand;
447 switch (opcode) {445
448 case DW_CFA_nop:446 ++p;
449 _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n");447 switch (opcode) {
450 break;448 case DW_CFA_nop:
451 case DW_CFA_set_loc:449 _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n");
452 codeOffset =450 break;
453 addressSpace.getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding);451 case DW_CFA_set_loc:
454 _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n");452 codeOffset = addressSpace.getEncodedP(p, instructionsEnd,
455 break;453 cieInfo.pointerEncoding);
456 case DW_CFA_advance_loc1:454 _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n");
457 codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);455 break;
458 p += 1;456 case DW_CFA_advance_loc1:
459 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",457 codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
460 static_cast<uint64_t>(codeOffset));458 p += 1;
461 break;459 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
462 case DW_CFA_advance_loc2:460 static_cast<uint64_t>(codeOffset));
463 codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);461 break;
464 p += 2;462 case DW_CFA_advance_loc2:
465 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",463 codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
466 static_cast<uint64_t>(codeOffset));464 p += 2;
467 break;465 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
468 case DW_CFA_advance_loc4:466 static_cast<uint64_t>(codeOffset));
469 codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);467 break;
470 p += 4;468 case DW_CFA_advance_loc4:
471 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",469 codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
472 static_cast<uint64_t>(codeOffset));470 p += 4;
473 break;471 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
474 case DW_CFA_offset_extended:472 static_cast<uint64_t>(codeOffset));
475 reg = addressSpace.getULEB128(p, instructionsEnd);473 break;
476 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)474 case DW_CFA_offset_extended:
477 * cieInfo.dataAlignFactor;475 reg = addressSpace.getULEB128(p, instructionsEnd);
478 if (reg > kMaxRegisterNumber) {476 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
479 _LIBUNWIND_LOG0(477 cieInfo.dataAlignFactor;
480 "malformed DW_CFA_offset_extended DWARF unwind, reg too big");478 if (reg > kMaxRegisterNumber) {
481 return false;479 _LIBUNWIND_LOG0(
482 }480 "malformed DW_CFA_offset_extended DWARF unwind, reg too big");
483 results->setRegister(reg, kRegisterInCFA, offset, initialState);481 return false;
484 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "482 }
485 "offset=%" PRId64 ")\n",483 results->setRegister(reg, kRegisterInCFA, offset, initialState);
486 reg, offset);484 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "
487 break;485 "offset=%" PRId64 ")\n",
488 case DW_CFA_restore_extended:486 reg, offset);
489 reg = addressSpace.getULEB128(p, instructionsEnd);487 break;
490 if (reg > kMaxRegisterNumber) {488 case DW_CFA_restore_extended:
491 _LIBUNWIND_LOG0(489 reg = addressSpace.getULEB128(p, instructionsEnd);
492 "malformed DW_CFA_restore_extended DWARF unwind, reg too big");490 if (reg > kMaxRegisterNumber) {
493 return false;491 _LIBUNWIND_LOG0(
494 }492 "malformed DW_CFA_restore_extended DWARF unwind, reg too big");
495 results->restoreRegisterToInitialState(reg, initialState);493 return false;
496 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg);494 }
497 break;495 results->restoreRegisterToInitialState(reg, initialState);
498 case DW_CFA_undefined:496 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n",
499 reg = addressSpace.getULEB128(p, instructionsEnd);497 reg);
500 if (reg > kMaxRegisterNumber) {498 break;
501 _LIBUNWIND_LOG0(499 case DW_CFA_undefined:
502 "malformed DW_CFA_undefined DWARF unwind, reg too big");500 reg = addressSpace.getULEB128(p, instructionsEnd);
503 return false;501 if (reg > kMaxRegisterNumber) {
504 }502 _LIBUNWIND_LOG0(
505 results->setRegisterLocation(reg, kRegisterUnused, initialState);503 "malformed DW_CFA_undefined DWARF unwind, reg too big");
506 _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);504 return false;
507 break;505 }
508 case DW_CFA_same_value:506 results->setRegisterLocation(reg, kRegisterUndefined, initialState);
509 reg = addressSpace.getULEB128(p, instructionsEnd);507 _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
510 if (reg > kMaxRegisterNumber) {508 break;
511 _LIBUNWIND_LOG0(509 case DW_CFA_same_value:
512 "malformed DW_CFA_same_value DWARF unwind, reg too big");510 reg = addressSpace.getULEB128(p, instructionsEnd);
513 return false;511 if (reg > kMaxRegisterNumber) {
514 }512 _LIBUNWIND_LOG0(
515 // <rdar://problem/8456377> DW_CFA_same_value unsupported513 "malformed DW_CFA_same_value DWARF unwind, reg too big");
516 // "same value" means register was stored in frame, but its current514 return false;
517 // value has not changed, so no need to restore from frame.515 }
518 // We model this as if the register was never saved.516 // <rdar://problem/8456377> DW_CFA_same_value unsupported
519 results->setRegisterLocation(reg, kRegisterUnused, initialState);517 // "same value" means register was stored in frame, but its current
520 // set flag to disable conversion to compact unwind518 // value has not changed, so no need to restore from frame.
521 results->sameValueUsed = true;519 // We model this as if the register was never saved.
522 _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);520 results->setRegisterLocation(reg, kRegisterUnused, initialState);
523 break;521 _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
524 case DW_CFA_register:522 break;
525 reg = addressSpace.getULEB128(p, instructionsEnd);523 case DW_CFA_register:
526 reg2 = addressSpace.getULEB128(p, instructionsEnd);524 reg = addressSpace.getULEB128(p, instructionsEnd);
527 if (reg > kMaxRegisterNumber) {525 reg2 = addressSpace.getULEB128(p, instructionsEnd);
528 _LIBUNWIND_LOG0(526 if (reg > kMaxRegisterNumber) {
529 "malformed DW_CFA_register DWARF unwind, reg too big");527 _LIBUNWIND_LOG0(
530 return false;528 "malformed DW_CFA_register DWARF unwind, reg too big");
531 }529 return false;
532 if (reg2 > kMaxRegisterNumber) {530 }
533 _LIBUNWIND_LOG0(531 if (reg2 > kMaxRegisterNumber) {
534 "malformed DW_CFA_register DWARF unwind, reg2 too big");532 _LIBUNWIND_LOG0(
535 return false;533 "malformed DW_CFA_register DWARF unwind, reg2 too big");
536 }534 return false;
537 results->setRegister(reg, kRegisterInRegister, (int64_t)reg2,535 }
538 initialState);536 results->setRegister(reg, kRegisterInRegister, (int64_t)reg2,
539 // set flag to disable conversion to compact unwind537 initialState);
540 results->registersInOtherRegisters = true;538 _LIBUNWIND_TRACE_DWARF(
541 _LIBUNWIND_TRACE_DWARF(539 "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2);
542 "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2);540 break;
543 break;541 case DW_CFA_remember_state: {
544#if !defined(_LIBUNWIND_NO_HEAP)542 // Avoid operator new because that would be an upward dependency.
545 case DW_CFA_remember_state:543 // Avoid malloc because it needs heap allocation.
546 // avoid operator new, because that would be an upward dependency544 PrologInfoStackEntry *entry =
547 entry = (PrologInfoStackEntry *)malloc(sizeof(PrologInfoStackEntry));545 (PrologInfoStackEntry *)_LIBUNWIND_REMEMBER_ALLOC(
548 if (entry != NULL) {546 sizeof(PrologInfoStackEntry));
549 entry->next = rememberStack;547 if (entry != NULL) {
550 entry->info = *results;548 entry->next = rememberStack.entry;
551 rememberStack = entry;549 entry->info = *results;
552 } else {550 rememberStack.entry = entry;
553 return false;551 } else {
554 }552 return false;
555 _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n");553 }
556 break;554 _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n");
557 case DW_CFA_restore_state:555 break;
558 if (rememberStack != NULL) {
559 PrologInfoStackEntry *top = rememberStack;
560 *results = top->info;
561 rememberStack = top->next;
562 free((char *)top);
563 } else {
564 return false;
565 }
566 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n");
567 break;
568#endif
569 case DW_CFA_def_cfa:
570 reg = addressSpace.getULEB128(p, instructionsEnd);
571 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd);
572 if (reg > kMaxRegisterNumber) {
573 _LIBUNWIND_LOG0("malformed DW_CFA_def_cfa DWARF unwind, reg too big");
574 return false;
575 }
576 results->cfaRegister = (uint32_t)reg;
577 results->cfaRegisterOffset = (int32_t)offset;
578 _LIBUNWIND_TRACE_DWARF(
579 "DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64 ")\n", reg, offset);
580 break;
581 case DW_CFA_def_cfa_register:
582 reg = addressSpace.getULEB128(p, instructionsEnd);
583 if (reg > kMaxRegisterNumber) {
584 _LIBUNWIND_LOG0(
585 "malformed DW_CFA_def_cfa_register DWARF unwind, reg too big");
586 return false;
587 }
588 results->cfaRegister = (uint32_t)reg;
589 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg);
590 break;
591 case DW_CFA_def_cfa_offset:
592 results->cfaRegisterOffset = (int32_t)
593 addressSpace.getULEB128(p, instructionsEnd);
594 results->codeOffsetAtStackDecrement = (uint32_t)codeOffset;
595 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n",
596 results->cfaRegisterOffset);
597 break;
598 case DW_CFA_def_cfa_expression:
599 results->cfaRegister = 0;
600 results->cfaExpression = (int64_t)p;
601 length = addressSpace.getULEB128(p, instructionsEnd);
602 assert(length < static_cast<pint_t>(~0) && "pointer overflow");
603 p += static_cast<pint_t>(length);
604 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64
605 ", length=%" PRIu64 ")\n",
606 results->cfaExpression, length);
607 break;
608 case DW_CFA_expression:
609 reg = addressSpace.getULEB128(p, instructionsEnd);
610 if (reg > kMaxRegisterNumber) {
611 _LIBUNWIND_LOG0(
612 "malformed DW_CFA_expression DWARF unwind, reg too big");
613 return false;
614 }
615 results->setRegister(reg, kRegisterAtExpression, (int64_t)p,
616 initialState);
617 length = addressSpace.getULEB128(p, instructionsEnd);
618 assert(length < static_cast<pint_t>(~0) && "pointer overflow");
619 p += static_cast<pint_t>(length);
620 _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", "
621 "expression=0x%" PRIx64 ", "
622 "length=%" PRIu64 ")\n",
623 reg, results->savedRegisters[reg].value, length);
624 break;
625 case DW_CFA_offset_extended_sf:
626 reg = addressSpace.getULEB128(p, instructionsEnd);
627 if (reg > kMaxRegisterNumber) {
628 _LIBUNWIND_LOG0(
629 "malformed DW_CFA_offset_extended_sf DWARF unwind, reg too big");
630 return false;
631 }
632 offset =
633 addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
634 results->setRegister(reg, kRegisterInCFA, offset, initialState);
635 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", "
636 "offset=%" PRId64 ")\n",
637 reg, offset);
638 break;
639 case DW_CFA_def_cfa_sf:
640 reg = addressSpace.getULEB128(p, instructionsEnd);
641 offset =
642 addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
643 if (reg > kMaxRegisterNumber) {
644 _LIBUNWIND_LOG0(
645 "malformed DW_CFA_def_cfa_sf DWARF unwind, reg too big");
646 return false;
647 }
648 results->cfaRegister = (uint32_t)reg;
649 results->cfaRegisterOffset = (int32_t)offset;
650 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", "
651 "offset=%" PRId64 ")\n",
652 reg, offset);
653 break;
654 case DW_CFA_def_cfa_offset_sf:
655 results->cfaRegisterOffset = (int32_t)
656 (addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor);
657 results->codeOffsetAtStackDecrement = (uint32_t)codeOffset;
658 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n",
659 results->cfaRegisterOffset);
660 break;
661 case DW_CFA_val_offset:
662 reg = addressSpace.getULEB128(p, instructionsEnd);
663 if (reg > kMaxRegisterNumber) {
664 _LIBUNWIND_LOG(
665 "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64
666 ") out of range\n",
667 reg);
668 return false;
669 }
670 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
671 * cieInfo.dataAlignFactor;
672 results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
673 _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", "
674 "offset=%" PRId64 "\n",
675 reg, offset);
676 break;
677 case DW_CFA_val_offset_sf:
678 reg = addressSpace.getULEB128(p, instructionsEnd);
679 if (reg > kMaxRegisterNumber) {
680 _LIBUNWIND_LOG0(
681 "malformed DW_CFA_val_offset_sf DWARF unwind, reg too big");
682 return false;
683 }
684 offset =
685 addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
686 results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
687 _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", "
688 "offset=%" PRId64 "\n",
689 reg, offset);
690 break;
691 case DW_CFA_val_expression:
692 reg = addressSpace.getULEB128(p, instructionsEnd);
693 if (reg > kMaxRegisterNumber) {
694 _LIBUNWIND_LOG0(
695 "malformed DW_CFA_val_expression DWARF unwind, reg too big");
696 return false;
697 }
698 results->setRegister(reg, kRegisterIsExpression, (int64_t)p,
699 initialState);
700 length = addressSpace.getULEB128(p, instructionsEnd);
701 assert(length < static_cast<pint_t>(~0) && "pointer overflow");
702 p += static_cast<pint_t>(length);
703 _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", "
704 "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
705 reg, results->savedRegisters[reg].value, length);
706 break;
707 case DW_CFA_GNU_args_size:
708 length = addressSpace.getULEB128(p, instructionsEnd);
709 results->spExtraArgSize = (uint32_t)length;
710 _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length);
711 break;
712 case DW_CFA_GNU_negative_offset_extended:
713 reg = addressSpace.getULEB128(p, instructionsEnd);
714 if (reg > kMaxRegisterNumber) {
715 _LIBUNWIND_LOG0("malformed DW_CFA_GNU_negative_offset_extended DWARF "
716 "unwind, reg too big");
717 return false;
718 }556 }
719 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)557 case DW_CFA_restore_state:
720 * cieInfo.dataAlignFactor;558 if (rememberStack.entry != NULL) {
721 results->setRegister(reg, kRegisterInCFA, -offset, initialState);559 PrologInfoStackEntry *top = rememberStack.entry;
722 _LIBUNWIND_TRACE_DWARF(560 *results = top->info;
723 "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);561 rememberStack.entry = top->next;
724 break;562 _LIBUNWIND_REMEMBER_FREE(top);
563 } else {
564 return false;
565 }
566 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n");
567 break;
568 case DW_CFA_def_cfa:
569 reg = addressSpace.getULEB128(p, instructionsEnd);
570 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd);
571 if (reg > kMaxRegisterNumber) {
572 _LIBUNWIND_LOG0("malformed DW_CFA_def_cfa DWARF unwind, reg too big");
573 return false;
574 }
575 results->cfaRegister = (uint32_t)reg;
576 results->cfaRegisterOffset = (int32_t)offset;
577 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64
578 ")\n",
579 reg, offset);
580 break;
581 case DW_CFA_def_cfa_register:
582 reg = addressSpace.getULEB128(p, instructionsEnd);
583 if (reg > kMaxRegisterNumber) {
584 _LIBUNWIND_LOG0(
585 "malformed DW_CFA_def_cfa_register DWARF unwind, reg too big");
586 return false;
587 }
588 results->cfaRegister = (uint32_t)reg;
589 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg);
590 break;
591 case DW_CFA_def_cfa_offset:
592 results->cfaRegisterOffset =
593 (int32_t)addressSpace.getULEB128(p, instructionsEnd);
594 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n",
595 results->cfaRegisterOffset);
596 break;
597 case DW_CFA_def_cfa_expression:
598 results->cfaRegister = 0;
599 results->cfaExpression = (int64_t)p;
600 length = addressSpace.getULEB128(p, instructionsEnd);
601 assert(length < static_cast<pint_t>(~0) && "pointer overflow");
602 p += static_cast<pint_t>(length);
603 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64
604 ", length=%" PRIu64 ")\n",
605 results->cfaExpression, length);
606 break;
607 case DW_CFA_expression:
608 reg = addressSpace.getULEB128(p, instructionsEnd);
609 if (reg > kMaxRegisterNumber) {
610 _LIBUNWIND_LOG0(
611 "malformed DW_CFA_expression DWARF unwind, reg too big");
612 return false;
613 }
614 results->setRegister(reg, kRegisterAtExpression, (int64_t)p,
615 initialState);
616 length = addressSpace.getULEB128(p, instructionsEnd);
617 assert(length < static_cast<pint_t>(~0) && "pointer overflow");
618 p += static_cast<pint_t>(length);
619 _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", "
620 "expression=0x%" PRIx64 ", "
621 "length=%" PRIu64 ")\n",
622 reg, results->savedRegisters[reg].value, length);
623 break;
624 case DW_CFA_offset_extended_sf:
625 reg = addressSpace.getULEB128(p, instructionsEnd);
626 if (reg > kMaxRegisterNumber) {
627 _LIBUNWIND_LOG0(
628 "malformed DW_CFA_offset_extended_sf DWARF unwind, reg too big");
629 return false;
630 }
631 offset = addressSpace.getSLEB128(p, instructionsEnd) *
632 cieInfo.dataAlignFactor;
633 results->setRegister(reg, kRegisterInCFA, offset, initialState);
634 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", "
635 "offset=%" PRId64 ")\n",
636 reg, offset);
637 break;
638 case DW_CFA_def_cfa_sf:
639 reg = addressSpace.getULEB128(p, instructionsEnd);
640 offset = addressSpace.getSLEB128(p, instructionsEnd) *
641 cieInfo.dataAlignFactor;
642 if (reg > kMaxRegisterNumber) {
643 _LIBUNWIND_LOG0(
644 "malformed DW_CFA_def_cfa_sf DWARF unwind, reg too big");
645 return false;
646 }
647 results->cfaRegister = (uint32_t)reg;
648 results->cfaRegisterOffset = (int32_t)offset;
649 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", "
650 "offset=%" PRId64 ")\n",
651 reg, offset);
652 break;
653 case DW_CFA_def_cfa_offset_sf:
654 results->cfaRegisterOffset =
655 (int32_t)(addressSpace.getSLEB128(p, instructionsEnd) *
656 cieInfo.dataAlignFactor);
657 _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n",
658 results->cfaRegisterOffset);
659 break;
660 case DW_CFA_val_offset:
661 reg = addressSpace.getULEB128(p, instructionsEnd);
662 if (reg > kMaxRegisterNumber) {
663 _LIBUNWIND_LOG(
664 "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64
665 ") out of range\n",
666 reg);
667 return false;
668 }
669 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
670 cieInfo.dataAlignFactor;
671 results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
672 _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", "
673 "offset=%" PRId64 "\n",
674 reg, offset);
675 break;
676 case DW_CFA_val_offset_sf:
677 reg = addressSpace.getULEB128(p, instructionsEnd);
678 if (reg > kMaxRegisterNumber) {
679 _LIBUNWIND_LOG0(
680 "malformed DW_CFA_val_offset_sf DWARF unwind, reg too big");
681 return false;
682 }
683 offset = addressSpace.getSLEB128(p, instructionsEnd) *
684 cieInfo.dataAlignFactor;
685 results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
686 _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", "
687 "offset=%" PRId64 "\n",
688 reg, offset);
689 break;
690 case DW_CFA_val_expression:
691 reg = addressSpace.getULEB128(p, instructionsEnd);
692 if (reg > kMaxRegisterNumber) {
693 _LIBUNWIND_LOG0(
694 "malformed DW_CFA_val_expression DWARF unwind, reg too big");
695 return false;
696 }
697 results->setRegister(reg, kRegisterIsExpression, (int64_t)p,
698 initialState);
699 length = addressSpace.getULEB128(p, instructionsEnd);
700 assert(length < static_cast<pint_t>(~0) && "pointer overflow");
701 p += static_cast<pint_t>(length);
702 _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", "
703 "expression=0x%" PRIx64 ", length=%" PRIu64
704 ")\n",
705 reg, results->savedRegisters[reg].value, length);
706 break;
707 case DW_CFA_GNU_args_size:
708 length = addressSpace.getULEB128(p, instructionsEnd);
709 results->spExtraArgSize = (uint32_t)length;
710 _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length);
711 break;
712 case DW_CFA_GNU_negative_offset_extended:
713 reg = addressSpace.getULEB128(p, instructionsEnd);
714 if (reg > kMaxRegisterNumber) {
715 _LIBUNWIND_LOG0("malformed DW_CFA_GNU_negative_offset_extended DWARF "
716 "unwind, reg too big");
717 return false;
718 }
719 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
720 cieInfo.dataAlignFactor;
721 results->setRegister(reg, kRegisterInCFA, -offset, initialState);
722 _LIBUNWIND_TRACE_DWARF(
723 "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
724 break;
725725
726#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC)726#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC)
727 // The same constant is used to represent different instructions on727 // The same constant is used to represent different instructions on
728 // AArch64 (negate_ra_state) and SPARC (window_save).728 // AArch64 (negate_ra_state) and SPARC (window_save).
729 static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,729 static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
730 "uses the same constant");730 "uses the same constant");
731 case DW_CFA_AARCH64_negate_ra_state:731 case DW_CFA_AARCH64_negate_ra_state:
732 switch (arch) {732 switch (arch) {
733#if defined(_LIBUNWIND_TARGET_AARCH64)733#if defined(_LIBUNWIND_TARGET_AARCH64)
734 case REGISTERS_ARM64: {734 case REGISTERS_ARM64: {
735 int64_t value =735 int64_t value =
736 results->savedRegisters[UNW_ARM64_RA_SIGN_STATE].value ^ 0x1;736 results->savedRegisters[UNW_ARM64_RA_SIGN_STATE].value ^ 0x1;
737 results->setRegisterValue(UNW_ARM64_RA_SIGN_STATE, value, initialState);737 results->setRegisterValue(UNW_ARM64_RA_SIGN_STATE, value,
738 initialState);
738 _LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n");739 _LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n");
739 } break;740 } break;
740#endif741#endif
741742
742#if defined(_LIBUNWIND_TARGET_SPARC)743#if defined(_LIBUNWIND_TARGET_SPARC)
743 // case DW_CFA_GNU_window_save:744 // case DW_CFA_GNU_window_save:
744 case REGISTERS_SPARC:745 case REGISTERS_SPARC:
745 _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n");746 _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n");
746 for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) {747 for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) {
747 results->setRegister(reg, kRegisterInRegister,748 results->setRegister(reg, kRegisterInRegister,
748 ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0,749 ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0,
749 initialState);750 initialState);
750 }751 }
751752
752 for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {753 for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
753 results->setRegister(reg, kRegisterInCFA,754 results->setRegister(reg, kRegisterInCFA,
754 ((int64_t)reg - UNW_SPARC_L0) * 4, initialState);755 ((int64_t)reg - UNW_SPARC_L0) * 4,
756 initialState);
757 }
758 break;
759#endif
755 }760 }
756 break;761 break;
757#endif
758 }
759 break;
760#else762#else
761 (void)arch;763 (void)arch;
762#endif764#endif
763765
764 default:766 default:
765 operand = opcode & 0x3F;767 operand = opcode & 0x3F;
766 switch (opcode & 0xC0) {768 switch (opcode & 0xC0) {
767 case DW_CFA_offset:769 case DW_CFA_offset:
768 reg = operand;770 reg = operand;
769 if (reg > kMaxRegisterNumber) {771 if (reg > kMaxRegisterNumber) {
770 _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64772 _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64
771 ") out of range",773 ") out of range",
772 reg);774 reg);
773 return false;775 return false;
774 }776 }
775 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)777 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
776 * cieInfo.dataAlignFactor;778 cieInfo.dataAlignFactor;
777 results->setRegister(reg, kRegisterInCFA, offset, initialState);779 results->setRegister(reg, kRegisterInCFA, offset, initialState);
778 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",780 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
779 operand, offset);781 operand, offset);
780 break;782 break;
781 case DW_CFA_advance_loc:783 case DW_CFA_advance_loc:
782 codeOffset += operand * cieInfo.codeAlignFactor;784 codeOffset += operand * cieInfo.codeAlignFactor;
783 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n",785 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
784 static_cast<uint64_t>(codeOffset));786 static_cast<uint64_t>(codeOffset));
785 break;787 break;
786 case DW_CFA_restore:788 case DW_CFA_restore:
787 reg = operand;789 reg = operand;
788 if (reg > kMaxRegisterNumber) {790 if (reg > kMaxRegisterNumber) {
789 _LIBUNWIND_LOG("malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64791 _LIBUNWIND_LOG(
790 ") out of range",792 "malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64
791 reg);793 ") out of range",
794 reg);
795 return false;
796 }
797 results->restoreRegisterToInitialState(reg, initialState);
798 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n",
799 static_cast<uint64_t>(operand));
800 break;
801 default:
802 _LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode);
792 return false;803 return false;
793 }804 }
794 results->restoreRegisterToInitialState(reg, initialState);
795 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n",
796 static_cast<uint64_t>(operand));
797 break;
798 default:
799 _LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode);
800 return false;
801 }805 }
802 }806 }
803 }807 }
804
805 return true;808 return true;
806}809}
807810
lib/libunwind/src/FrameHeaderCache.hpp+1-1
...@@ -32,7 +32,7 @@...@@ -32,7 +32,7 @@
32class _LIBUNWIND_HIDDEN FrameHeaderCache {32class _LIBUNWIND_HIDDEN FrameHeaderCache {
33 struct CacheEntry {33 struct CacheEntry {
34 uintptr_t LowPC() { return Info.dso_base; };34 uintptr_t LowPC() { return Info.dso_base; };
35 uintptr_t HighPC() { return Info.dso_base + Info.dwarf_section_length; };35 uintptr_t HighPC() { return Info.dso_base + Info.text_segment_length; };
36 UnwindInfoSections Info;36 UnwindInfoSections Info;
37 CacheEntry *Next;37 CacheEntry *Next;
38 };38 };
lib/libunwind/src/Registers.hpp+11-5
...@@ -39,6 +39,8 @@ enum {...@@ -39,6 +39,8 @@ enum {
39};39};
4040
41#if defined(_LIBUNWIND_TARGET_I386)41#if defined(_LIBUNWIND_TARGET_I386)
42class _LIBUNWIND_HIDDEN Registers_x86;
43extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
42/// Registers_x86 holds the register state of a thread in a 32-bit intel44/// Registers_x86 holds the register state of a thread in a 32-bit intel
43/// process.45/// process.
44class _LIBUNWIND_HIDDEN Registers_x86 {46class _LIBUNWIND_HIDDEN Registers_x86 {
...@@ -56,7 +58,7 @@ public:...@@ -56,7 +58,7 @@ public:
56 v128 getVectorRegister(int num) const;58 v128 getVectorRegister(int num) const;
57 void setVectorRegister(int num, v128 value);59 void setVectorRegister(int num, v128 value);
58 static const char *getRegisterName(int num);60 static const char *getRegisterName(int num);
59 void jumpto();61 void jumpto() { __libunwind_Registers_x86_jumpto(this); }
60 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }62 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
61 static int getArch() { return REGISTERS_X86; }63 static int getArch() { return REGISTERS_X86; }
6264
...@@ -248,6 +250,8 @@ inline void Registers_x86::setVectorRegister(int, v128) {...@@ -248,6 +250,8 @@ inline void Registers_x86::setVectorRegister(int, v128) {
248#if defined(_LIBUNWIND_TARGET_X86_64)250#if defined(_LIBUNWIND_TARGET_X86_64)
249/// Registers_x86_64 holds the register state of a thread in a 64-bit intel251/// Registers_x86_64 holds the register state of a thread in a 64-bit intel
250/// process.252/// process.
253class _LIBUNWIND_HIDDEN Registers_x86_64;
254extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
251class _LIBUNWIND_HIDDEN Registers_x86_64 {255class _LIBUNWIND_HIDDEN Registers_x86_64 {
252public:256public:
253 Registers_x86_64();257 Registers_x86_64();
...@@ -263,7 +267,7 @@ public:...@@ -263,7 +267,7 @@ public:
263 v128 getVectorRegister(int num) const;267 v128 getVectorRegister(int num) const;
264 void setVectorRegister(int num, v128 value);268 void setVectorRegister(int num, v128 value);
265 static const char *getRegisterName(int num);269 static const char *getRegisterName(int num);
266 void jumpto();270 void jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
267 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }271 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
268 static int getArch() { return REGISTERS_X86_64; }272 static int getArch() { return REGISTERS_X86_64; }
269273
...@@ -1510,12 +1514,12 @@ inline void Registers_ppc64::setFloatRegister(int regNum, double value) {...@@ -1510,12 +1514,12 @@ inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1510}1514}
15111515
1512inline bool Registers_ppc64::validVectorRegister(int regNum) const {1516inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1513#ifdef PPC64_HAS_VMX1517#if defined(__VSX__)
1514 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)1518 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1515 return true;1519 return true;
1516 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)1520 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1517 return true;1521 return true;
1518#else1522#elif defined(__ALTIVEC__)
1519 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)1523 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1520 return true;1524 return true;
1521#endif1525#endif
...@@ -1771,6 +1775,8 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) {...@@ -1771,6 +1775,8 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) {
1771#if defined(_LIBUNWIND_TARGET_AARCH64)1775#if defined(_LIBUNWIND_TARGET_AARCH64)
1772/// Registers_arm64 holds the register state of a thread in a 64-bit arm1776/// Registers_arm64 holds the register state of a thread in a 64-bit arm
1773/// process.1777/// process.
1778class _LIBUNWIND_HIDDEN Registers_arm64;
1779extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
1774class _LIBUNWIND_HIDDEN Registers_arm64 {1780class _LIBUNWIND_HIDDEN Registers_arm64 {
1775public:1781public:
1776 Registers_arm64();1782 Registers_arm64();
...@@ -1786,7 +1792,7 @@ public:...@@ -1786,7 +1792,7 @@ public:
1786 v128 getVectorRegister(int num) const;1792 v128 getVectorRegister(int num) const;
1787 void setVectorRegister(int num, v128 value);1793 void setVectorRegister(int num, v128 value);
1788 static const char *getRegisterName(int num);1794 static const char *getRegisterName(int num);
1789 void jumpto();1795 void jumpto() { __libunwind_Registers_arm64_jumpto(this); }
1790 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }1796 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
1791 static int getArch() { return REGISTERS_ARM64; }1797 static int getArch() { return REGISTERS_ARM64; }
17921798
lib/libunwind/src/Unwind-seh.cpp+4-16
...@@ -46,18 +46,6 @@ using namespace libunwind;...@@ -46,18 +46,6 @@ using namespace libunwind;
46/// handling.46/// handling.
47#define STATUS_GCC_UNWIND MAKE_GCC_EXCEPTION(1) // 0x2147434347#define STATUS_GCC_UNWIND MAKE_GCC_EXCEPTION(1) // 0x21474343
4848
49/// Class of foreign exceptions based on unrecognized SEH exceptions.
50static const uint64_t kSEHExceptionClass = 0x434C4E4753454800; // CLNGSEH\0
51
52/// Exception cleanup routine used by \c _GCC_specific_handler to
53/// free foreign exceptions.
54static void seh_exc_cleanup(_Unwind_Reason_Code urc, _Unwind_Exception *exc) {
55 (void)urc;
56 if (exc->exception_class != kSEHExceptionClass)
57 _LIBUNWIND_ABORT("SEH cleanup called on non-SEH exception");
58 free(exc);
59}
60
61static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);49static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);
62static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);50static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);
63static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor,51static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor,
...@@ -108,10 +96,10 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,...@@ -108,10 +96,10 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
108 }96 }
109 } else {97 } else {
110 // Foreign exception.98 // Foreign exception.
111 exc = (_Unwind_Exception *)malloc(sizeof(_Unwind_Exception));99 // We can't interact with them (we don't know the original target frame
112 exc->exception_class = kSEHExceptionClass;100 // that we should pass on to RtlUnwindEx in _Unwind_Resume), so just
113 exc->exception_cleanup = seh_exc_cleanup;101 // pass without calling our destructors here.
114 memset(exc->private_, 0, sizeof(exc->private_));102 return ExceptionContinueSearch;
115 }103 }
116 if (!ctx) {104 if (!ctx) {
117 __unw_init_seh(&cursor, disp->ContextRecord);105 __unw_init_seh(&cursor, disp->ContextRecord);
lib/libunwind/src/UnwindCursor.hpp+51-64
...@@ -81,6 +81,7 @@ template <typename A>...@@ -81,6 +81,7 @@ template <typename A>
81class _LIBUNWIND_HIDDEN DwarfFDECache {81class _LIBUNWIND_HIDDEN DwarfFDECache {
82 typedef typename A::pint_t pint_t;82 typedef typename A::pint_t pint_t;
83public:83public:
84 static constexpr pint_t kSearchAll = static_cast<pint_t>(-1);
84 static pint_t findFDE(pint_t mh, pint_t pc);85 static pint_t findFDE(pint_t mh, pint_t pc);
85 static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);86 static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
86 static void removeAllIn(pint_t mh);87 static void removeAllIn(pint_t mh);
...@@ -138,7 +139,7 @@ typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {...@@ -138,7 +139,7 @@ typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
138 pint_t result = 0;139 pint_t result = 0;
139 _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());140 _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
140 for (entry *p = _buffer; p < _bufferUsed; ++p) {141 for (entry *p = _buffer; p < _bufferUsed; ++p) {
141 if ((mh == p->mh) || (mh == 0)) {142 if ((mh == p->mh) || (mh == kSearchAll)) {
142 if ((p->ip_start <= pc) && (pc < p->ip_end)) {143 if ((p->ip_start <= pc) && (pc < p->ip_end)) {
143 result = p->fde;144 result = p->fde;
144 break;145 break;
...@@ -530,6 +531,8 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)...@@ -530,6 +531,8 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
530 : _addressSpace(as), _unwindInfoMissing(false) {531 : _addressSpace(as), _unwindInfoMissing(false) {
531 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),532 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
532 "UnwindCursor<> does not fit in unw_cursor_t");533 "UnwindCursor<> does not fit in unw_cursor_t");
534 static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)),
535 "UnwindCursor<> requires more alignment than unw_cursor_t");
533 memset(&_info, 0, sizeof(_info));536 memset(&_info, 0, sizeof(_info));
534 memset(&_histTable, 0, sizeof(_histTable));537 memset(&_histTable, 0, sizeof(_histTable));
535 _dispContext.ContextRecord = &_msContext;538 _dispContext.ContextRecord = &_msContext;
...@@ -923,6 +926,9 @@ private:...@@ -923,6 +926,9 @@ private:
923#endif926#endif
924927
925#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)928#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
929 bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo,
930 const typename CFI_Parser<A>::CIE_Info &cieInfo,
931 pint_t pc, uintptr_t dso_base);
926 bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections &sects,932 bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections &sects,
927 uint32_t fdeSectionOffsetHint=0);933 uint32_t fdeSectionOffsetHint=0);
928 int stepWithDwarfFDE() {934 int stepWithDwarfFDE() {
...@@ -1182,6 +1188,8 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)...@@ -1182,6 +1188,8 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
1182 _isSignalFrame(false) {1188 _isSignalFrame(false) {
1183 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),1189 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
1184 "UnwindCursor<> does not fit in unw_cursor_t");1190 "UnwindCursor<> does not fit in unw_cursor_t");
1191 static_assert((alignof(UnwindCursor<A, R>) <= alignof(unw_cursor_t)),
1192 "UnwindCursor<> requires more alignment than unw_cursor_t");
1185 memset(&_info, 0, sizeof(_info));1193 memset(&_info, 0, sizeof(_info));
1186}1194}
11871195
...@@ -1472,6 +1480,32 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection(...@@ -1472,6 +1480,32 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection(
1472#endif1480#endif
14731481
1474#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)1482#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1483template <typename A, typename R>
1484bool UnwindCursor<A, R>::getInfoFromFdeCie(
1485 const typename CFI_Parser<A>::FDE_Info &fdeInfo,
1486 const typename CFI_Parser<A>::CIE_Info &cieInfo, pint_t pc,
1487 uintptr_t dso_base) {
1488 typename CFI_Parser<A>::PrologInfo prolog;
1489 if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
1490 R::getArch(), &prolog)) {
1491 // Save off parsed FDE info
1492 _info.start_ip = fdeInfo.pcStart;
1493 _info.end_ip = fdeInfo.pcEnd;
1494 _info.lsda = fdeInfo.lsda;
1495 _info.handler = cieInfo.personality;
1496 // Some frameless functions need SP altered when resuming in function, so
1497 // propagate spExtraArgSize.
1498 _info.gp = prolog.spExtraArgSize;
1499 _info.flags = 0;
1500 _info.format = dwarfEncoding();
1501 _info.unwind_info = fdeInfo.fdeStart;
1502 _info.unwind_info_size = static_cast<uint32_t>(fdeInfo.fdeLength);
1503 _info.extra = static_cast<unw_word_t>(dso_base);
1504 return true;
1505 }
1506 return false;
1507}
1508
1475template <typename A, typename R>1509template <typename A, typename R>
1476bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,1510bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
1477 const UnwindInfoSections &sects,1511 const UnwindInfoSections &sects,
...@@ -1483,7 +1517,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,...@@ -1483,7 +1517,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
1483 // If compact encoding table gave offset into dwarf section, go directly there1517 // If compact encoding table gave offset into dwarf section, go directly there
1484 if (fdeSectionOffsetHint != 0) {1518 if (fdeSectionOffsetHint != 0) {
1485 foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,1519 foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1486 (uint32_t)sects.dwarf_section_length,1520 sects.dwarf_section_length,
1487 sects.dwarf_section + fdeSectionOffsetHint,1521 sects.dwarf_section + fdeSectionOffsetHint,
1488 &fdeInfo, &cieInfo);1522 &fdeInfo, &cieInfo);
1489 }1523 }
...@@ -1500,7 +1534,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,...@@ -1500,7 +1534,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
1500 if (cachedFDE != 0) {1534 if (cachedFDE != 0) {
1501 foundFDE =1535 foundFDE =
1502 CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,1536 CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1503 (uint32_t)sects.dwarf_section_length,1537 sects.dwarf_section_length,
1504 cachedFDE, &fdeInfo, &cieInfo);1538 cachedFDE, &fdeInfo, &cieInfo);
1505 foundInCache = foundFDE;1539 foundInCache = foundFDE;
1506 }1540 }
...@@ -1508,25 +1542,11 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,...@@ -1508,25 +1542,11 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
1508 if (!foundFDE) {1542 if (!foundFDE) {
1509 // Still not found, do full scan of __eh_frame section.1543 // Still not found, do full scan of __eh_frame section.
1510 foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,1544 foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1511 (uint32_t)sects.dwarf_section_length, 0,1545 sects.dwarf_section_length, 0,
1512 &fdeInfo, &cieInfo);1546 &fdeInfo, &cieInfo);
1513 }1547 }
1514 if (foundFDE) {1548 if (foundFDE) {
1515 typename CFI_Parser<A>::PrologInfo prolog;1549 if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) {
1516 if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
1517 R::getArch(), &prolog)) {
1518 // Save off parsed FDE info
1519 _info.start_ip = fdeInfo.pcStart;
1520 _info.end_ip = fdeInfo.pcEnd;
1521 _info.lsda = fdeInfo.lsda;
1522 _info.handler = cieInfo.personality;
1523 _info.gp = prolog.spExtraArgSize;
1524 _info.flags = 0;
1525 _info.format = dwarfEncoding();
1526 _info.unwind_info = fdeInfo.fdeStart;
1527 _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
1528 _info.extra = (unw_word_t) sects.dso_base;
1529
1530 // Add to cache (to make next lookup faster) if we had no hint1550 // Add to cache (to make next lookup faster) if we had no hint
1531 // and there was no index.1551 // and there was no index.
1532 if (!foundInCache && (fdeSectionOffsetHint == 0)) {1552 if (!foundInCache && (fdeSectionOffsetHint == 0)) {
...@@ -1759,12 +1779,12 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,...@@ -1759,12 +1779,12 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
1759 }1779 }
1760 }1780 }
17611781
1762 // extact personality routine, if encoding says function has one1782 // extract personality routine, if encoding says function has one
1763 uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >>1783 uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >>
1764 (__builtin_ctz(UNWIND_PERSONALITY_MASK));1784 (__builtin_ctz(UNWIND_PERSONALITY_MASK));
1765 if (personalityIndex != 0) {1785 if (personalityIndex != 0) {
1766 --personalityIndex; // change 1-based to zero-based index1786 --personalityIndex; // change 1-based to zero-based index
1767 if (personalityIndex > sectionHeader.personalityArrayCount()) {1787 if (personalityIndex >= sectionHeader.personalityArrayCount()) {
1768 _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, "1788 _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, "
1769 "but personality table has only %d entries",1789 "but personality table has only %d entries",
1770 encoding, personalityIndex,1790 encoding, personalityIndex,
...@@ -1926,60 +1946,27 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {...@@ -1926,60 +1946,27 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
1926#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)1946#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
1927 // There is no static unwind info for this pc. Look to see if an FDE was1947 // There is no static unwind info for this pc. Look to see if an FDE was
1928 // dynamically registered for it.1948 // dynamically registered for it.
1929 pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);1949 pint_t cachedFDE = DwarfFDECache<A>::findFDE(DwarfFDECache<A>::kSearchAll,
1950 pc);
1930 if (cachedFDE != 0) {1951 if (cachedFDE != 0) {
1931 CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;1952 typename CFI_Parser<A>::FDE_Info fdeInfo;
1932 CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;1953 typename CFI_Parser<A>::CIE_Info cieInfo;
1933 const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace,1954 if (!CFI_Parser<A>::decodeFDE(_addressSpace, cachedFDE, &fdeInfo, &cieInfo))
1934 cachedFDE, &fdeInfo, &cieInfo);1955 if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
1935 if (msg == NULL) {
1936 typename CFI_Parser<A>::PrologInfo prolog;
1937 if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
1938 pc, R::getArch(), &prolog)) {
1939 // save off parsed FDE info
1940 _info.start_ip = fdeInfo.pcStart;
1941 _info.end_ip = fdeInfo.pcEnd;
1942 _info.lsda = fdeInfo.lsda;
1943 _info.handler = cieInfo.personality;
1944 _info.gp = prolog.spExtraArgSize;
1945 // Some frameless functions need SP
1946 // altered when resuming in function.
1947 _info.flags = 0;
1948 _info.format = dwarfEncoding();
1949 _info.unwind_info = fdeInfo.fdeStart;
1950 _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
1951 _info.extra = 0;
1952 return;1956 return;
1953 }
1954 }
1955 }1957 }
19561958
1957 // Lastly, ask AddressSpace object about platform specific ways to locate1959 // Lastly, ask AddressSpace object about platform specific ways to locate
1958 // other FDEs.1960 // other FDEs.
1959 pint_t fde;1961 pint_t fde;
1960 if (_addressSpace.findOtherFDE(pc, fde)) {1962 if (_addressSpace.findOtherFDE(pc, fde)) {
1961 CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;1963 typename CFI_Parser<A>::FDE_Info fdeInfo;
1962 CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;1964 typename CFI_Parser<A>::CIE_Info cieInfo;
1963 if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {1965 if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
1964 // Double check this FDE is for a function that includes the pc.1966 // Double check this FDE is for a function that includes the pc.
1965 if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {1967 if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd))
1966 typename CFI_Parser<A>::PrologInfo prolog;1968 if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
1967 if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
1968 pc, R::getArch(), &prolog)) {
1969 // save off parsed FDE info
1970 _info.start_ip = fdeInfo.pcStart;
1971 _info.end_ip = fdeInfo.pcEnd;
1972 _info.lsda = fdeInfo.lsda;
1973 _info.handler = cieInfo.personality;
1974 _info.gp = prolog.spExtraArgSize;
1975 _info.flags = 0;
1976 _info.format = dwarfEncoding();
1977 _info.unwind_info = fdeInfo.fdeStart;
1978 _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
1979 _info.extra = 0;
1980 return;1969 return;
1981 }
1982 }
1983 }1970 }
1984 }1971 }
1985#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)1972#endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
lib/libunwind/src/UnwindLevel1.c+1-3
...@@ -39,8 +39,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except...@@ -39,8 +39,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
39 __unw_init_local(cursor, uc);39 __unw_init_local(cursor, uc);
4040
41 // Walk each frame looking for a place to stop.41 // Walk each frame looking for a place to stop.
42 bool handlerNotFound = true;42 while (true) {
43 while (handlerNotFound) {
44 // Ask libunwind to get next frame (skip over first which is43 // Ask libunwind to get next frame (skip over first which is
45 // _Unwind_RaiseException).44 // _Unwind_RaiseException).
46 int stepResult = __unw_step(cursor);45 int stepResult = __unw_step(cursor);
...@@ -102,7 +101,6 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except...@@ -102,7 +101,6 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
102 case _URC_HANDLER_FOUND:101 case _URC_HANDLER_FOUND:
103 // found a catch clause or locals that need destructing in this frame102 // found a catch clause or locals that need destructing in this frame
104 // stop search and remember stack pointer at the frame103 // stop search and remember stack pointer at the frame
105 handlerNotFound = false;
106 __unw_get_reg(cursor, UNW_REG_SP, &sp);104 __unw_get_reg(cursor, UNW_REG_SP, &sp);
107 exception_object->private_2 = (uintptr_t)sp;105 exception_object->private_2 = (uintptr_t)sp;
108 _LIBUNWIND_TRACE_UNWINDING(106 _LIBUNWIND_TRACE_UNWINDING(
lib/libunwind/src/UnwindRegistersRestore.S+13-12
...@@ -13,14 +13,10 @@...@@ -13,14 +13,10 @@
13#if !defined(__USING_SJLJ_EXCEPTIONS__)13#if !defined(__USING_SJLJ_EXCEPTIONS__)
1414
15#if defined(__i386__)15#if defined(__i386__)
16DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)16DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto)
17#17#
18# void libunwind::Registers_x86::jumpto()18# extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
19#19#
20#if defined(_WIN32)
21# On windows, the 'this' pointer is passed in ecx instead of on the stack
22 movl %ecx, %eax
23#else
24# On entry:20# On entry:
25# + +21# + +
26# +-----------------------+22# +-----------------------+
...@@ -30,7 +26,6 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)...@@ -30,7 +26,6 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
30# +-----------------------+ <-- SP26# +-----------------------+ <-- SP
31# + +27# + +
32 movl 4(%esp), %eax28 movl 4(%esp), %eax
33#endif
34 # set up eax and ret on new stack location29 # set up eax and ret on new stack location
35 movl 28(%eax), %edx # edx holds new stack pointer30 movl 28(%eax), %edx # edx holds new stack pointer
36 subl $8,%edx31 subl $8,%edx
...@@ -60,9 +55,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)...@@ -60,9 +55,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
6055
61#elif defined(__x86_64__)56#elif defined(__x86_64__)
6257
63DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)58DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto)
64#59#
65# void libunwind::Registers_x86_64::jumpto()60# extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
66#61#
67#if defined(_WIN64)62#if defined(_WIN64)
68# On entry, thread_state pointer is in rcx; move it into rdi63# On entry, thread_state pointer is in rcx; move it into rdi
...@@ -175,7 +170,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)...@@ -175,7 +170,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
175 PPC64_LR(30)170 PPC64_LR(30)
176 PPC64_LR(31)171 PPC64_LR(31)
177172
178#ifdef PPC64_HAS_VMX173#if defined(__VSX__)
179174
180 // restore VS registers175 // restore VS registers
181 // (note that this also restores floating point registers and V registers,176 // (note that this also restores floating point registers and V registers,
...@@ -317,6 +312,7 @@ PPC64_CLVS_BOTTOM(n)...@@ -317,6 +312,7 @@ PPC64_CLVS_BOTTOM(n)
317 PPC64_LF(30)312 PPC64_LF(30)
318 PPC64_LF(31)313 PPC64_LF(31)
319314
315#if defined(__ALTIVEC__)
320 // restore vector registers if any are in use316 // restore vector registers if any are in use
321 ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave317 ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave
322 cmpwi %r5, 0318 cmpwi %r5, 0
...@@ -378,6 +374,7 @@ PPC64_CLV_UNALIGNED_BOTTOM(n)...@@ -378,6 +374,7 @@ PPC64_CLV_UNALIGNED_BOTTOM(n)
378 PPC64_CLV_UNALIGNEDh(31)374 PPC64_CLV_UNALIGNEDh(31)
379375
380#endif376#endif
377#endif
381378
382Lnovec:379Lnovec:
383 ld %r0, PPC64_OFFS_CR(%r3)380 ld %r0, PPC64_OFFS_CR(%r3)
...@@ -436,6 +433,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)...@@ -436,6 +433,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
436 lwz %r30,128(%r3)433 lwz %r30,128(%r3)
437 lwz %r31,132(%r3)434 lwz %r31,132(%r3)
438435
436#ifndef __NO_FPRS__
439 // restore float registers437 // restore float registers
440 lfd %f0, 160(%r3)438 lfd %f0, 160(%r3)
441 lfd %f1, 168(%r3)439 lfd %f1, 168(%r3)
...@@ -469,7 +467,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)...@@ -469,7 +467,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
469 lfd %f29,392(%r3)467 lfd %f29,392(%r3)
470 lfd %f30,400(%r3)468 lfd %f30,400(%r3)
471 lfd %f31,408(%r3)469 lfd %f31,408(%r3)
470#endif
472471
472#if defined(__ALTIVEC__)
473 // restore vector registers if any are in use473 // restore vector registers if any are in use
474 lwz %r5, 156(%r3) // test VRsave474 lwz %r5, 156(%r3) // test VRsave
475 cmpwi %r5, 0475 cmpwi %r5, 0
...@@ -542,6 +542,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)...@@ -542,6 +542,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
542 LOAD_VECTOR_UNALIGNEDh(29)542 LOAD_VECTOR_UNALIGNEDh(29)
543 LOAD_VECTOR_UNALIGNEDh(30)543 LOAD_VECTOR_UNALIGNEDh(30)
544 LOAD_VECTOR_UNALIGNEDh(31)544 LOAD_VECTOR_UNALIGNEDh(31)
545#endif
545546
546Lnovec:547Lnovec:
547 lwz %r0, 136(%r3) // __cr548 lwz %r0, 136(%r3) // __cr
...@@ -560,13 +561,13 @@ Lnovec:...@@ -560,13 +561,13 @@ Lnovec:
560#elif defined(__aarch64__)561#elif defined(__aarch64__)
561562
562//563//
563// void libunwind::Registers_arm64::jumpto()564// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
564//565//
565// On entry:566// On entry:
566// thread_state pointer is in x0567// thread_state pointer is in x0
567//568//
568 .p2align 2569 .p2align 2
569DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)570DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
570 // skip restore of x0,x1 for now571 // skip restore of x0,x1 for now
571 ldp x2, x3, [x0, #0x010]572 ldp x2, x3, [x0, #0x010]
572 ldp x4, x5, [x0, #0x020]573 ldp x4, x5, [x0, #0x020]
lib/libunwind/src/UnwindRegistersSave.S+7-2
...@@ -384,7 +384,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -384,7 +384,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
384 mfvrsave %r0384 mfvrsave %r0
385 std %r0, PPC64_OFFS_VRSAVE(%r3)385 std %r0, PPC64_OFFS_VRSAVE(%r3)
386386
387#ifdef PPC64_HAS_VMX387#if defined(__VSX__)
388 // save VS registers388 // save VS registers
389 // (note that this also saves floating point registers and V registers,389 // (note that this also saves floating point registers and V registers,
390 // because part of VS is mapped to these registers)390 // because part of VS is mapped to these registers)
...@@ -501,6 +501,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -501,6 +501,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
501 PPC64_STF(30)501 PPC64_STF(30)
502 PPC64_STF(31)502 PPC64_STF(31)
503503
504#if defined(__ALTIVEC__)
504 // save vector registers505 // save vector registers
505506
506 // Use 16-bytes below the stack pointer as an507 // Use 16-bytes below the stack pointer as an
...@@ -548,6 +549,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -548,6 +549,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
548 PPC64_STV_UNALIGNED(30)549 PPC64_STV_UNALIGNED(30)
549 PPC64_STV_UNALIGNED(31)550 PPC64_STV_UNALIGNED(31)
550551
552#endif
551#endif553#endif
552554
553 li %r3, 0 // return UNW_ESUCCESS555 li %r3, 0 // return UNW_ESUCCESS
...@@ -608,6 +610,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -608,6 +610,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
608 mfctr %r0610 mfctr %r0
609 stw %r0, 148(%r3)611 stw %r0, 148(%r3)
610612
613#if !defined(__NO_FPRS__)
611 // save float registers614 // save float registers
612 stfd %f0, 160(%r3)615 stfd %f0, 160(%r3)
613 stfd %f1, 168(%r3)616 stfd %f1, 168(%r3)
...@@ -641,8 +644,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -641,8 +644,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
641 stfd %f29,392(%r3)644 stfd %f29,392(%r3)
642 stfd %f30,400(%r3)645 stfd %f30,400(%r3)
643 stfd %f31,408(%r3)646 stfd %f31,408(%r3)
647#endif
644648
645649#if defined(__ALTIVEC__)
646 // save vector registers650 // save vector registers
647651
648 subi %r4, %r1, 16652 subi %r4, %r1, 16
...@@ -692,6 +696,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)...@@ -692,6 +696,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
692 SAVE_VECTOR_UNALIGNED(%v29, 424+0x1D0)696 SAVE_VECTOR_UNALIGNED(%v29, 424+0x1D0)
693 SAVE_VECTOR_UNALIGNED(%v30, 424+0x1E0)697 SAVE_VECTOR_UNALIGNED(%v30, 424+0x1E0)
694 SAVE_VECTOR_UNALIGNED(%v31, 424+0x1F0)698 SAVE_VECTOR_UNALIGNED(%v31, 424+0x1F0)
699#endif
695700
696 li %r3, 0 // return UNW_ESUCCESS701 li %r3, 0 // return UNW_ESUCCESS
697 blr702 blr
lib/libunwind/src/Unwind_AppleExtras.cpp-70
...@@ -8,35 +8,6 @@...@@ -8,35 +8,6 @@
8//===----------------------------------------------------------------------===//8//===----------------------------------------------------------------------===//
99
10#include "config.h"10#include "config.h"
11#include "AddressSpace.hpp"
12#include "DwarfParser.hpp"
13
14
15// private keymgr stuff
16#define KEYMGR_GCC3_DW2_OBJ_LIST 302
17extern "C" {
18 extern void _keymgr_set_and_unlock_processwide_ptr(int key, void *ptr);
19 extern void *_keymgr_get_and_lock_processwide_ptr(int key);
20}
21
22// undocumented libgcc "struct object"
23struct libgcc_object {
24 void *start;
25 void *unused1;
26 void *unused2;
27 void *fde;
28 unsigned long encoding;
29 void *fde_end;
30 libgcc_object *next;
31};
32
33// undocumented libgcc "struct km_object_info" referenced by
34// KEYMGR_GCC3_DW2_OBJ_LIST
35struct libgcc_object_info {
36 libgcc_object *seen_objects;
37 libgcc_object *unseen_objects;
38 unsigned spare[2];
39};
4011
4112
42// static linker symbols to prevent wrong two level namespace for _Unwind symbols13// static linker symbols to prevent wrong two level namespace for _Unwind symbols
...@@ -140,44 +111,3 @@ NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)...@@ -140,44 +111,3 @@ NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)
140NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)111NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)
141112
142#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS)113#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS)
143
144
145namespace libunwind {
146
147_LIBUNWIND_HIDDEN
148bool checkKeyMgrRegisteredFDEs(uintptr_t pc, void *&fde) {
149#if __MAC_OS_X_VERSION_MIN_REQUIRED
150 // lastly check for old style keymgr registration of dynamically generated
151 // FDEs acquire exclusive access to libgcc_object_info
152 libgcc_object_info *head = (libgcc_object_info *)
153 _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST);
154 if (head != NULL) {
155 // look at each FDE in keymgr
156 for (libgcc_object *ob = head->unseen_objects; ob != NULL; ob = ob->next) {
157 CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
158 CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
159 const char *msg = CFI_Parser<LocalAddressSpace>::decodeFDE(
160 LocalAddressSpace::sThisAddressSpace,
161 (uintptr_t)ob->fde, &fdeInfo, &cieInfo);
162 if (msg == NULL) {
163 // Check if this FDE is for a function that includes the pc
164 if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
165 fde = (void*)fdeInfo.pcStart;
166 _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST,
167 head);
168 return true;
169 }
170 }
171 }
172 }
173 // release libgcc_object_info
174 _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head);
175#else
176 (void)pc;
177 (void)fde;
178#endif
179 return false;
180}
181
182}
183
lib/libunwind/src/assembly.h+20-4
...@@ -25,9 +25,6 @@...@@ -25,9 +25,6 @@
25#define PPC64_OFFS_VRSAVE 30425#define PPC64_OFFS_VRSAVE 304
26#define PPC64_OFFS_FP 31226#define PPC64_OFFS_FP 312
27#define PPC64_OFFS_V 82427#define PPC64_OFFS_V 824
28#ifdef _ARCH_PWR8
29#define PPC64_HAS_VMX
30#endif
31#elif defined(__APPLE__) && defined(__aarch64__)28#elif defined(__APPLE__) && defined(__aarch64__)
32#define SEPARATOR %%29#define SEPARATOR %%
33#else30#else
...@@ -48,6 +45,24 @@...@@ -48,6 +45,24 @@
48#define PPC64_OPD245#define PPC64_OPD2
49#endif46#endif
5047
48#if defined(__ARM_FEATURE_BTI_DEFAULT)
49 .pushsection ".note.gnu.property", "a" SEPARATOR \
50 .balign 8 SEPARATOR \
51 .long 4 SEPARATOR \
52 .long 0x10 SEPARATOR \
53 .long 0x5 SEPARATOR \
54 .asciz "GNU" SEPARATOR \
55 .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \
56 .long 4 SEPARATOR \
57 .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */ \
58 /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ \
59 .long 0 SEPARATOR \
60 .popsection SEPARATOR
61#define AARCH64_BTI bti c
62#else
63#define AARCH64_BTI
64#endif
65
51#define GLUE2(a, b) a ## b66#define GLUE2(a, b) a ## b
52#define GLUE(a, b) GLUE2(a, b)67#define GLUE(a, b) GLUE2(a, b)
53#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)68#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
...@@ -144,7 +159,8 @@...@@ -144,7 +159,8 @@
144 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \159 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
145 PPC64_OPD1 \160 PPC64_OPD1 \
146 SYMBOL_NAME(name): \161 SYMBOL_NAME(name): \
147 PPC64_OPD2162 PPC64_OPD2 \
163 AARCH64_BTI
148164
149#if defined(__arm__)165#if defined(__arm__)
150#if !defined(__ARM_ARCH)166#if !defined(__ARM_ARCH)
lib/libunwind/src/config.h+39-15
...@@ -18,23 +18,15 @@...@@ -18,23 +18,15 @@
18#include <stdint.h>18#include <stdint.h>
19#include <stdlib.h>19#include <stdlib.h>
2020
21// Define static_assert() unless already defined by compiler.21#include <__libunwind_config.h>
22#ifndef __has_feature
23 #define __has_feature(__x) 0
24#endif
25#if !(__has_feature(cxx_static_assert)) && !defined(static_assert)
26 #define static_assert(__b, __m) \
27 extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ] \
28 __attribute__( ( unused ) );
29#endif
3022
31// Platform specific configuration defines.23// Platform specific configuration defines.
32#ifdef __APPLE__24#ifdef __APPLE__
33 #if defined(FOR_DYLD)25 #if defined(FOR_DYLD)
34 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND26 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
35 #else27 #else
36 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND28 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
37 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 129 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
38 #endif30 #endif
39#elif defined(_WIN32)31#elif defined(_WIN32)
40 #ifdef __SEH__32 #ifdef __SEH__
...@@ -42,8 +34,19 @@...@@ -42,8 +34,19 @@
42 #else34 #else
43 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 135 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
44 #endif36 #endif
37#elif defined(_LIBUNWIND_IS_BAREMETAL)
38 #if !defined(_LIBUNWIND_ARM_EHABI)
39 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
40 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
41 #endif
42#elif defined(__BIONIC__) && defined(_LIBUNWIND_ARM_EHABI)
43 // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After
44 // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster.
45 #define _LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX 1
45#else46#else
46 #if defined(__ARM_DWARF_EH__) || !defined(__arm__)47 // Assume an ELF system with a dl_iterate_phdr function.
48 #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1
49 #if !defined(_LIBUNWIND_ARM_EHABI)
47 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 150 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
48 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 151 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
49 #endif52 #endif
...@@ -91,6 +94,8 @@...@@ -91,6 +94,8 @@
91#error Unsupported target94#error Unsupported target
92#endif95#endif
9396
97// Apple/armv7k defaults to DWARF/Compact unwinding, but its libunwind also
98// needs to include the SJLJ APIs.
94#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)99#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
95#define _LIBUNWIND_BUILD_SJLJ_APIS100#define _LIBUNWIND_BUILD_SJLJ_APIS
96#endif101#endif
...@@ -111,8 +116,27 @@...@@ -111,8 +116,27 @@
111#endif116#endif
112#endif117#endif
113118
114#if defined(__powerpc64__) && defined(_ARCH_PWR8)119#ifndef _LIBUNWIND_REMEMBER_HEAP_ALLOC
115#define PPC64_HAS_VMX120#if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) || \
121 defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) || \
122 defined(_LIBUNWIND_IS_BAREMETAL)
123#define _LIBUNWIND_REMEMBER_ALLOC(_size) alloca(_size)
124#define _LIBUNWIND_REMEMBER_FREE(_ptr) \
125 do { \
126 } while (0)
127#elif defined(_WIN32)
128#define _LIBUNWIND_REMEMBER_ALLOC(_size) _malloca(_size)
129#define _LIBUNWIND_REMEMBER_FREE(_ptr) _freea(_ptr)
130#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED
131#else
132#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size)
133#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr)
134#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED
135#endif
136#else /* _LIBUNWIND_REMEMBER_HEAP_ALLOC */
137#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size)
138#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr)
139#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED
116#endif140#endif
117141
118#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)142#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)