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 @@
4343 #define LIBUNWIND_AVAIL
4444#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
4652/* error codes */
4753enum {
4854 UNW_ESUCCESS = 0, /* no error */
......@@ -68,7 +74,7 @@ typedef struct unw_context_t unw_context_t;
6874
6975struct unw_cursor_t {
7076 uint64_t data[_LIBUNWIND_CURSOR_SIZE];
71};
77} LIBUNWIND_CURSOR_ALIGNMENT_ATTR;
7278typedef struct unw_cursor_t unw_cursor_t;
7379
7480typedef struct unw_addr_space *unw_addr_space_t;
lib/libunwind/src/AddressSpace.hpp+98-162
......@@ -17,6 +17,12 @@
1717#include <stdlib.h>
1818#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
2026#ifndef _LIBUNWIND_USE_DLADDR
2127 #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32)
2228 #define _LIBUNWIND_USE_DLADDR 1
......@@ -39,19 +45,6 @@ struct EHABIIndexEntry {
3945};
4046#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
5548#ifdef __APPLE__
5649
5750 struct dyld_unwind_sections
......@@ -62,43 +55,9 @@ namespace libunwind {
6255 const void* compact_unwind_section;
6356 uintptr_t compact_unwind_section_length;
6457 };
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 struct
87 info->mh = (const struct mach_header *)mh;
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
59 // In 10.7.0 or later, libSystem.dylib implements this function.
60 extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *);
10261
10362#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
10463
......@@ -139,22 +98,15 @@ extern char __eh_frame_hdr_end;
13998extern char __exidx_start;
14099extern 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
152103#include <windows.h>
153104#include <psapi.h>
154#endif
155#if !defined(ElfW)
156#define ElfW(type) Elf_##type
157#endif
105
106#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR) || \
107 defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX)
108
109#include <link.h>
158110
159111#endif
160112
......@@ -162,11 +114,15 @@ namespace libunwind {
162114
163115/// Used by findUnwindSections() to return info about needed sections.
164116struct UnwindInfoSections {
165#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || defined(_LIBUNWIND_SUPPORT_DWARF_INDEX) || \
166 defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
167 // No dso_base for SEH or ARM EHABI.
117#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) || \
118 defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND) || \
119 defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
120 // No dso_base for SEH.
168121 uintptr_t dso_base;
169122#endif
123#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
124 uintptr_t text_segment_length;
125#endif
170126#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
171127 uintptr_t dwarf_section;
172128 uintptr_t dwarf_section_length;
......@@ -290,11 +246,11 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
290246 if (p == pend)
291247 _LIBUNWIND_ABORT("truncated sleb128 expression");
292248 byte = *p++;
293 result |= ((byte & 0x7f) << bit);
249 result |= (uint64_t)(byte & 0x7f) << bit;
294250 bit += 7;
295251 } while (byte & 0x80);
296252 // sign extend negative numbers
297 if ((byte & 0x40) != 0)
253 if ((byte & 0x40) != 0 && bit < 64)
298254 result |= (-1ULL) << bit;
299255 addr = (pint_t) p;
300256 return result;
......@@ -392,23 +348,14 @@ LocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
392348 return result;
393349}
394350
395#ifdef __APPLE__
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)
351#if defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
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
412359#if !defined(Elf_Half)
413360 typedef ElfW(Half) Elf_Half;
414361#endif
......@@ -447,16 +394,12 @@ struct _LIBUNWIND_HIDDEN dl_iterate_cb_data {
447394 uintptr_t targetAddr;
448395};
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
455397#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
456398#include "FrameHeaderCache.hpp"
457399
458// There should be just one of these per process.
459static FrameHeaderCache ProcessFrameHeaderCache;
400// Typically there is one cache per process, but when libunwind is built as a
401// hermetic static library, then each shared object may have its own cache.
402static FrameHeaderCache TheFrameHeaderCache;
460403#endif
461404
462405static 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,
466409 uintptr_t end = begin + phdr->p_memsz;
467410 if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) {
468411 cbdata->sects->dso_base = begin;
469 cbdata->sects->dwarf_section_length = phdr->p_memsz;
412 cbdata->sects->text_segment_length = phdr->p_memsz;
470413 return true;
471414 }
472415 }
473416 return false;
474417}
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
476451static int findUnwindSectionsByPhdr(struct dl_phdr_info *pinfo,
477452 size_t pinfo_size, void *data) {
478453 auto cbdata = static_cast<dl_iterate_cb_data *>(data);
479454 if (pinfo->dlpi_phnum == 0 || cbdata->targetAddr < pinfo->dlpi_addr)
480455 return 0;
481456#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
482 if (ProcessFrameHeaderCache.find(pinfo, pinfo_size, data))
457 if (TheFrameHeaderCache.find(pinfo, pinfo_size, data))
483458 return 1;
459#else
460 // Avoid warning about unused variable.
461 (void)pinfo_size;
484462#endif
485463
486464 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.
491 if (pinfo->dlpi_phnum > 2)
492 found_obj = checkAddrInSegment(&pinfo->dlpi_phdr[2], image_base, cbdata);
466 // Most shared objects seen in this callback function likely don't contain the
467 // target address, so optimize for that. Scan for a matching PT_LOAD segment
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 know
495 // that there is one or more phdrs.
479 // PT_GNU_EH_FRAME and PT_ARM_EXIDX are usually near the end. Iterate
480 // backward.
481 bool found_unwind = false;
496482 for (Elf_Half i = pinfo->dlpi_phnum; i > 0; i--) {
497483 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i - 1];
498 if (!found_hdr && phdr->p_type == PT_GNU_EH_FRAME) {
499 EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo;
500 uintptr_t eh_frame_hdr_start = image_base + phdr->p_vaddr;
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;
484 if (checkForUnwindInfoSegment(phdr, image_base, cbdata)) {
485 found_unwind = true;
486 break;
516487 }
517488 }
518 cbdata->sects->dwarf_section_length = 0;
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)
489 if (!found_unwind)
536490 return 0;
537491
538 Elf_Addr image_base = calculateImageBase(pinfo);
539
540 for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) {
541 const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i];
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;
492#if defined(_LIBUNWIND_USE_FRAME_HEADER_CACHE)
493 TheFrameHeaderCache.add(cbdata->sects);
494#endif
495 return 1;
555496}
556#endif // defined(LIBUNWIND_SUPPORT_DWARF_UNWIND)
557#endif // defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
497
498#endif // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
558499
559500
560501inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
......@@ -572,6 +513,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
572513 return true;
573514 }
574515#elif defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND) && defined(_LIBUNWIND_IS_BAREMETAL)
516 info.dso_base = 0;
575517 // Bare metal is statically linked, so no need to ask the dynamic loader
576518 info.dwarf_section_length = (uintptr_t)(&__eh_frame_end - &__eh_frame_start);
577519 info.dwarf_section = (uintptr_t)(&__eh_frame_start);
......@@ -638,16 +580,14 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
638580 (void)targetAddr;
639581 (void)info;
640582 return true;
641#elif defined(_LIBUNWIND_ARM_EHABI) && defined(__BIONIC__)
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.
583#elif defined(_LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX)
644584 int length = 0;
645585 info.arm_section =
646586 (uintptr_t)dl_unwind_find_exidx((_Unwind_Ptr)targetAddr, &length);
647587 info.arm_section_length = (uintptr_t)length * sizeof(EHABIIndexEntry);
648588 if (info.arm_section && info.arm_section_length)
649589 return true;
650#elif defined(_LIBUNWIND_ARM_EHABI) || defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
590#elif defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
651591 dl_iterate_cb_data cb_data = {this, &info, targetAddr};
652592 int found = dl_iterate_phdr(findUnwindSectionsByPhdr, &cb_data);
653593 return static_cast<bool>(found);
......@@ -658,14 +598,10 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
658598
659599
660600inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
661#ifdef __APPLE__
662 return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde));
663#else
664601 // TO DO: if OS has way to dynamically register FDEs, check that.
665602 (void)targetAddr;
666603 (void)fde;
667604 return false;
668#endif
669605}
670606
671607inline 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(
9393
9494 case CFI_Parser<A>::kRegisterInRegister:
9595 return registers.getRegister((int)savedReg.value);
96
96 case CFI_Parser<A>::kRegisterUndefined:
97 return 0;
9798 case CFI_Parser<A>::kRegisterUnused:
9899 case CFI_Parser<A>::kRegisterOffsetFromCFA:
99100 // FIX ME
......@@ -117,6 +118,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister(
117118
118119 case CFI_Parser<A>::kRegisterIsExpression:
119120 case CFI_Parser<A>::kRegisterUnused:
121 case CFI_Parser<A>::kRegisterUndefined:
120122 case CFI_Parser<A>::kRegisterOffsetFromCFA:
121123 case CFI_Parser<A>::kRegisterInRegister:
122124 // FIX ME
......@@ -140,6 +142,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister(
140142
141143 case CFI_Parser<A>::kRegisterIsExpression:
142144 case CFI_Parser<A>::kRegisterUnused:
145 case CFI_Parser<A>::kRegisterUndefined:
143146 case CFI_Parser<A>::kRegisterOffsetFromCFA:
144147 case CFI_Parser<A>::kRegisterInRegister:
145148 // FIX ME
......@@ -190,6 +193,10 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
190193 prolog.savedRegisters[i]));
191194 else
192195 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);
193200 }
194201 }
195202
lib/libunwind/src/DwarfParser.hpp+407-404
......@@ -69,6 +69,7 @@ public:
6969 };
7070 enum RegisterSavedWhere {
7171 kRegisterUnused,
72 kRegisterUndefined,
7273 kRegisterInCFA,
7374 kRegisterOffsetFromCFA,
7475 kRegisterInRegister,
......@@ -87,9 +88,6 @@ public:
8788 int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
8889 int64_t cfaExpression; // CFA = expression
8990 uint32_t spExtraArgSize;
90 uint32_t codeOffsetAtStackDecrement;
91 bool registersInOtherRegisters;
92 bool sameValueUsed;
9391 RegisterLocation savedRegisters[kMaxRegisterNumber + 1];
9492 enum class InitializeTime { kLazy, kNormal };
9593
......@@ -134,8 +132,26 @@ public:
134132 PrologInfo info;
135133 };
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
137153 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,
139155 CIE_Info *cieInfo);
140156 static const char *decodeFDE(A &addressSpace, pint_t fdeStart,
141157 FDE_Info *fdeInfo, CIE_Info *cieInfo);
......@@ -144,13 +160,6 @@ public:
144160 int arch, PrologInfo *results);
145161
146162 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);
154163};
155164
156165/// 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,
166175 p += 8;
167176 }
168177 if (cfiLength == 0)
169 return "FDE has zero length"; // end marker
178 return "FDE has zero length"; // zero terminator
170179 uint32_t ciePointer = addressSpace.get32(p);
171180 if (ciePointer == 0)
172181 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,
211220/// Scan an eh_frame section to find an FDE for a pc
212221template <typename A>
213222bool 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,
215224 FDE_Info *fdeInfo, CIE_Info *cieInfo) {
216225 //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);
217226 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);
219230 while (p < ehSectionEnd) {
220231 pint_t currentCFI = p;
221232 //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,
227238 p += 8;
228239 }
229240 if (cfiLength == 0)
230 return false; // end marker
241 return false; // zero terminator
231242 uint32_t id = addressSpace.get32(p);
232243 if (id == 0) {
233244 // Skip over CIEs.
......@@ -336,7 +347,8 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
336347 // parse data alignment factor
337348 cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
338349 // 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);
340352 assert(raReg < 255 && "return address register too large");
341353 cieInfo->returnAddressRegister = (uint8_t)raReg;
342354 // parse augmentation data based on augmentation string
......@@ -390,418 +402,409 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
390402 const FDE_Info &fdeInfo,
391403 const CIE_Info &cieInfo, pint_t upToPC,
392404 int arch, PrologInfo *results) {
393 PrologInfoStackEntry *rememberStack = NULL;
394
395 // parse CIE then FDE instructions
396 bool returnValue =
397 parseInstructions(addressSpace, cieInfo.cieInstructions,
398 cieInfo.cieStart + cieInfo.cieLength, cieInfo,
399 (pint_t)(-1), rememberStack, arch, results) &&
400 parseInstructions(addressSpace, fdeInfo.fdeInstructions,
401 fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo,
402 upToPC - fdeInfo.pcStart, rememberStack, arch, results);
403
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}
405 // Alloca is used for the allocation of the rememberStack entries. It removes
406 // the dependency on new/malloc but the below for loop can not be refactored
407 // into functions. Entry could be saved during the processing of a CIE and
408 // restored by an FDE.
409 RememberStack rememberStack;
410
411 struct ParseInfo {
412 pint_t instructions;
413 pint_t instructionsEnd;
414 pint_t pcoffset;
415 };
418416
419/// "run" the DWARF instructions
420template <typename A>
421bool CFI_Parser<A>::parseInstructions(A &addressSpace, pint_t instructions,
422 pint_t instructionsEnd,
423 const CIE_Info &cieInfo, pint_t pcoffset,
424 PrologInfoStackEntry *&rememberStack,
425 int arch, PrologInfo *results) {
426 pint_t p = instructions;
427 pint_t codeOffset = 0;
428 // initialState initialized as registers in results are modified. Use
429 // PrologInfo accessor functions to avoid reading uninitialized data.
430 PrologInfo initialState(PrologInfo::InitializeTime::kLazy);
431
432 _LIBUNWIND_TRACE_DWARF("parseInstructions(instructions=0x%0" PRIx64 ")\n",
433 static_cast<uint64_t>(instructionsEnd));
434
435 // see DWARF Spec, section 6.4.2 for details on unwind opcodes
436 while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
437 uint64_t reg;
438 uint64_t reg2;
439 int64_t offset;
440 uint64_t length;
441 uint8_t opcode = addressSpace.get8(p);
442 uint8_t operand;
443#if !defined(_LIBUNWIND_NO_HEAP)
444 PrologInfoStackEntry *entry;
445#endif
446 ++p;
447 switch (opcode) {
448 case DW_CFA_nop:
449 _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n");
450 break;
451 case DW_CFA_set_loc:
452 codeOffset =
453 addressSpace.getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding);
454 _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n");
455 break;
456 case DW_CFA_advance_loc1:
457 codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
458 p += 1;
459 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
460 static_cast<uint64_t>(codeOffset));
461 break;
462 case DW_CFA_advance_loc2:
463 codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
464 p += 2;
465 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
466 static_cast<uint64_t>(codeOffset));
467 break;
468 case DW_CFA_advance_loc4:
469 codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
470 p += 4;
471 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
472 static_cast<uint64_t>(codeOffset));
473 break;
474 case DW_CFA_offset_extended:
475 reg = addressSpace.getULEB128(p, instructionsEnd);
476 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
477 * cieInfo.dataAlignFactor;
478 if (reg > kMaxRegisterNumber) {
479 _LIBUNWIND_LOG0(
480 "malformed DW_CFA_offset_extended DWARF unwind, reg too big");
481 return false;
482 }
483 results->setRegister(reg, kRegisterInCFA, offset, initialState);
484 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "
485 "offset=%" PRId64 ")\n",
486 reg, offset);
487 break;
488 case DW_CFA_restore_extended:
489 reg = addressSpace.getULEB128(p, instructionsEnd);
490 if (reg > kMaxRegisterNumber) {
491 _LIBUNWIND_LOG0(
492 "malformed DW_CFA_restore_extended DWARF unwind, reg too big");
493 return false;
494 }
495 results->restoreRegisterToInitialState(reg, initialState);
496 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg);
497 break;
498 case DW_CFA_undefined:
499 reg = addressSpace.getULEB128(p, instructionsEnd);
500 if (reg > kMaxRegisterNumber) {
501 _LIBUNWIND_LOG0(
502 "malformed DW_CFA_undefined DWARF unwind, reg too big");
503 return false;
504 }
505 results->setRegisterLocation(reg, kRegisterUnused, initialState);
506 _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
507 break;
508 case DW_CFA_same_value:
509 reg = addressSpace.getULEB128(p, instructionsEnd);
510 if (reg > kMaxRegisterNumber) {
511 _LIBUNWIND_LOG0(
512 "malformed DW_CFA_same_value DWARF unwind, reg too big");
513 return false;
514 }
515 // <rdar://problem/8456377> DW_CFA_same_value unsupported
516 // "same value" means register was stored in frame, but its current
517 // value has not changed, so no need to restore from frame.
518 // We model this as if the register was never saved.
519 results->setRegisterLocation(reg, kRegisterUnused, initialState);
520 // set flag to disable conversion to compact unwind
521 results->sameValueUsed = true;
522 _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
523 break;
524 case DW_CFA_register:
525 reg = addressSpace.getULEB128(p, instructionsEnd);
526 reg2 = addressSpace.getULEB128(p, instructionsEnd);
527 if (reg > kMaxRegisterNumber) {
528 _LIBUNWIND_LOG0(
529 "malformed DW_CFA_register DWARF unwind, reg too big");
530 return false;
531 }
532 if (reg2 > kMaxRegisterNumber) {
533 _LIBUNWIND_LOG0(
534 "malformed DW_CFA_register DWARF unwind, reg2 too big");
535 return false;
536 }
537 results->setRegister(reg, kRegisterInRegister, (int64_t)reg2,
538 initialState);
539 // set flag to disable conversion to compact unwind
540 results->registersInOtherRegisters = true;
541 _LIBUNWIND_TRACE_DWARF(
542 "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2);
543 break;
544#if !defined(_LIBUNWIND_NO_HEAP)
545 case DW_CFA_remember_state:
546 // avoid operator new, because that would be an upward dependency
547 entry = (PrologInfoStackEntry *)malloc(sizeof(PrologInfoStackEntry));
548 if (entry != NULL) {
549 entry->next = rememberStack;
550 entry->info = *results;
551 rememberStack = entry;
552 } else {
553 return false;
554 }
555 _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n");
556 break;
557 case DW_CFA_restore_state:
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;
417 ParseInfo parseInfoArray[] = {
418 {cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength,
419 (pint_t)(-1)},
420 {fdeInfo.fdeInstructions, fdeInfo.fdeStart + fdeInfo.fdeLength,
421 upToPC - fdeInfo.pcStart}};
422
423 for (const auto &info : parseInfoArray) {
424 pint_t p = info.instructions;
425 pint_t instructionsEnd = info.instructionsEnd;
426 pint_t pcoffset = info.pcoffset;
427 pint_t codeOffset = 0;
428
429 // initialState initialized as registers in results are modified. Use
430 // PrologInfo accessor functions to avoid reading uninitialized data.
431 PrologInfo initialState(PrologInfo::InitializeTime::kLazy);
432
433 _LIBUNWIND_TRACE_DWARF("parseFDEInstructions(instructions=0x%0" PRIx64
434 ")\n",
435 static_cast<uint64_t>(instructionsEnd));
436
437 // see DWARF Spec, section 6.4.2 for details on unwind opcodes
438 while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
439 uint64_t reg;
440 uint64_t reg2;
441 int64_t offset;
442 uint64_t length;
443 uint8_t opcode = addressSpace.get8(p);
444 uint8_t operand;
445
446 ++p;
447 switch (opcode) {
448 case DW_CFA_nop:
449 _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n");
450 break;
451 case DW_CFA_set_loc:
452 codeOffset = addressSpace.getEncodedP(p, instructionsEnd,
453 cieInfo.pointerEncoding);
454 _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n");
455 break;
456 case DW_CFA_advance_loc1:
457 codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
458 p += 1;
459 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
460 static_cast<uint64_t>(codeOffset));
461 break;
462 case DW_CFA_advance_loc2:
463 codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
464 p += 2;
465 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
466 static_cast<uint64_t>(codeOffset));
467 break;
468 case DW_CFA_advance_loc4:
469 codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
470 p += 4;
471 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
472 static_cast<uint64_t>(codeOffset));
473 break;
474 case DW_CFA_offset_extended:
475 reg = addressSpace.getULEB128(p, instructionsEnd);
476 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
477 cieInfo.dataAlignFactor;
478 if (reg > kMaxRegisterNumber) {
479 _LIBUNWIND_LOG0(
480 "malformed DW_CFA_offset_extended DWARF unwind, reg too big");
481 return false;
482 }
483 results->setRegister(reg, kRegisterInCFA, offset, initialState);
484 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "
485 "offset=%" PRId64 ")\n",
486 reg, offset);
487 break;
488 case DW_CFA_restore_extended:
489 reg = addressSpace.getULEB128(p, instructionsEnd);
490 if (reg > kMaxRegisterNumber) {
491 _LIBUNWIND_LOG0(
492 "malformed DW_CFA_restore_extended DWARF unwind, reg too big");
493 return false;
494 }
495 results->restoreRegisterToInitialState(reg, initialState);
496 _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n",
497 reg);
498 break;
499 case DW_CFA_undefined:
500 reg = addressSpace.getULEB128(p, instructionsEnd);
501 if (reg > kMaxRegisterNumber) {
502 _LIBUNWIND_LOG0(
503 "malformed DW_CFA_undefined DWARF unwind, reg too big");
504 return false;
505 }
506 results->setRegisterLocation(reg, kRegisterUndefined, initialState);
507 _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
508 break;
509 case DW_CFA_same_value:
510 reg = addressSpace.getULEB128(p, instructionsEnd);
511 if (reg > kMaxRegisterNumber) {
512 _LIBUNWIND_LOG0(
513 "malformed DW_CFA_same_value DWARF unwind, reg too big");
514 return false;
515 }
516 // <rdar://problem/8456377> DW_CFA_same_value unsupported
517 // "same value" means register was stored in frame, but its current
518 // value has not changed, so no need to restore from frame.
519 // We model this as if the register was never saved.
520 results->setRegisterLocation(reg, kRegisterUnused, initialState);
521 _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
522 break;
523 case DW_CFA_register:
524 reg = addressSpace.getULEB128(p, instructionsEnd);
525 reg2 = addressSpace.getULEB128(p, instructionsEnd);
526 if (reg > kMaxRegisterNumber) {
527 _LIBUNWIND_LOG0(
528 "malformed DW_CFA_register DWARF unwind, reg too big");
529 return false;
530 }
531 if (reg2 > kMaxRegisterNumber) {
532 _LIBUNWIND_LOG0(
533 "malformed DW_CFA_register DWARF unwind, reg2 too big");
534 return false;
535 }
536 results->setRegister(reg, kRegisterInRegister, (int64_t)reg2,
537 initialState);
538 _LIBUNWIND_TRACE_DWARF(
539 "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2);
540 break;
541 case DW_CFA_remember_state: {
542 // Avoid operator new because that would be an upward dependency.
543 // Avoid malloc because it needs heap allocation.
544 PrologInfoStackEntry *entry =
545 (PrologInfoStackEntry *)_LIBUNWIND_REMEMBER_ALLOC(
546 sizeof(PrologInfoStackEntry));
547 if (entry != NULL) {
548 entry->next = rememberStack.entry;
549 entry->info = *results;
550 rememberStack.entry = entry;
551 } else {
552 return false;
553 }
554 _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n");
555 break;
718556 }
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;
557 case DW_CFA_restore_state:
558 if (rememberStack.entry != NULL) {
559 PrologInfoStackEntry *top = rememberStack.entry;
560 *results = top->info;
561 rememberStack.entry = top->next;
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
726726#if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC)
727 // The same constant is used to represent different instructions on
728 // AArch64 (negate_ra_state) and SPARC (window_save).
729 static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
730 "uses the same constant");
731 case DW_CFA_AARCH64_negate_ra_state:
732 switch (arch) {
727 // The same constant is used to represent different instructions on
728 // AArch64 (negate_ra_state) and SPARC (window_save).
729 static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
730 "uses the same constant");
731 case DW_CFA_AARCH64_negate_ra_state:
732 switch (arch) {
733733#if defined(_LIBUNWIND_TARGET_AARCH64)
734734 case REGISTERS_ARM64: {
735735 int64_t value =
736736 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);
738739 _LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n");
739740 } break;
740741#endif
741742
742743#if defined(_LIBUNWIND_TARGET_SPARC)
743 // case DW_CFA_GNU_window_save:
744 case REGISTERS_SPARC:
745 _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n");
746 for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) {
747 results->setRegister(reg, kRegisterInRegister,
748 ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0,
749 initialState);
750 }
744 // case DW_CFA_GNU_window_save:
745 case REGISTERS_SPARC:
746 _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n");
747 for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) {
748 results->setRegister(reg, kRegisterInRegister,
749 ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0,
750 initialState);
751 }
751752
752 for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
753 results->setRegister(reg, kRegisterInCFA,
754 ((int64_t)reg - UNW_SPARC_L0) * 4, initialState);
753 for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
754 results->setRegister(reg, kRegisterInCFA,
755 ((int64_t)reg - UNW_SPARC_L0) * 4,
756 initialState);
757 }
758 break;
759#endif
755760 }
756761 break;
757#endif
758 }
759 break;
760762#else
761 (void)arch;
763 (void)arch;
762764#endif
763765
764 default:
765 operand = opcode & 0x3F;
766 switch (opcode & 0xC0) {
767 case DW_CFA_offset:
768 reg = operand;
769 if (reg > kMaxRegisterNumber) {
770 _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64
771 ") out of range",
772 reg);
773 return false;
774 }
775 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
776 * cieInfo.dataAlignFactor;
777 results->setRegister(reg, kRegisterInCFA, offset, initialState);
778 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
779 operand, offset);
780 break;
781 case DW_CFA_advance_loc:
782 codeOffset += operand * cieInfo.codeAlignFactor;
783 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
784 static_cast<uint64_t>(codeOffset));
785 break;
786 case DW_CFA_restore:
787 reg = operand;
788 if (reg > kMaxRegisterNumber) {
789 _LIBUNWIND_LOG("malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64
790 ") out of range",
791 reg);
766 default:
767 operand = opcode & 0x3F;
768 switch (opcode & 0xC0) {
769 case DW_CFA_offset:
770 reg = operand;
771 if (reg > kMaxRegisterNumber) {
772 _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64
773 ") out of range",
774 reg);
775 return false;
776 }
777 offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
778 cieInfo.dataAlignFactor;
779 results->setRegister(reg, kRegisterInCFA, offset, initialState);
780 _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
781 operand, offset);
782 break;
783 case DW_CFA_advance_loc:
784 codeOffset += operand * cieInfo.codeAlignFactor;
785 _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
786 static_cast<uint64_t>(codeOffset));
787 break;
788 case DW_CFA_restore:
789 reg = operand;
790 if (reg > kMaxRegisterNumber) {
791 _LIBUNWIND_LOG(
792 "malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64
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);
792803 return false;
793804 }
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;
801805 }
802806 }
803807 }
804
805808 return true;
806809}
807810
lib/libunwind/src/FrameHeaderCache.hpp+1-1
......@@ -32,7 +32,7 @@
3232class _LIBUNWIND_HIDDEN FrameHeaderCache {
3333 struct CacheEntry {
3434 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; };
3636 UnwindInfoSections Info;
3737 CacheEntry *Next;
3838 };
lib/libunwind/src/Registers.hpp+11-5
......@@ -39,6 +39,8 @@ enum {
3939};
4040
4141#if defined(_LIBUNWIND_TARGET_I386)
42class _LIBUNWIND_HIDDEN Registers_x86;
43extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
4244/// Registers_x86 holds the register state of a thread in a 32-bit intel
4345/// process.
4446class _LIBUNWIND_HIDDEN Registers_x86 {
......@@ -56,7 +58,7 @@ public:
5658 v128 getVectorRegister(int num) const;
5759 void setVectorRegister(int num, v128 value);
5860 static const char *getRegisterName(int num);
59 void jumpto();
61 void jumpto() { __libunwind_Registers_x86_jumpto(this); }
6062 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
6163 static int getArch() { return REGISTERS_X86; }
6264
......@@ -248,6 +250,8 @@ inline void Registers_x86::setVectorRegister(int, v128) {
248250#if defined(_LIBUNWIND_TARGET_X86_64)
249251/// Registers_x86_64 holds the register state of a thread in a 64-bit intel
250252/// process.
253class _LIBUNWIND_HIDDEN Registers_x86_64;
254extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
251255class _LIBUNWIND_HIDDEN Registers_x86_64 {
252256public:
253257 Registers_x86_64();
......@@ -263,7 +267,7 @@ public:
263267 v128 getVectorRegister(int num) const;
264268 void setVectorRegister(int num, v128 value);
265269 static const char *getRegisterName(int num);
266 void jumpto();
270 void jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
267271 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
268272 static int getArch() { return REGISTERS_X86_64; }
269273
......@@ -1510,12 +1514,12 @@ inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
15101514}
15111515
15121516inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1513#ifdef PPC64_HAS_VMX
1517#if defined(__VSX__)
15141518 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
15151519 return true;
15161520 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
15171521 return true;
1518#else
1522#elif defined(__ALTIVEC__)
15191523 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
15201524 return true;
15211525#endif
......@@ -1771,6 +1775,8 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) {
17711775#if defined(_LIBUNWIND_TARGET_AARCH64)
17721776/// Registers_arm64 holds the register state of a thread in a 64-bit arm
17731777/// process.
1778class _LIBUNWIND_HIDDEN Registers_arm64;
1779extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
17741780class _LIBUNWIND_HIDDEN Registers_arm64 {
17751781public:
17761782 Registers_arm64();
......@@ -1786,7 +1792,7 @@ public:
17861792 v128 getVectorRegister(int num) const;
17871793 void setVectorRegister(int num, v128 value);
17881794 static const char *getRegisterName(int num);
1789 void jumpto();
1795 void jumpto() { __libunwind_Registers_arm64_jumpto(this); }
17901796 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
17911797 static int getArch() { return REGISTERS_ARM64; }
17921798
lib/libunwind/src/Unwind-seh.cpp+4-16
......@@ -46,18 +46,6 @@ using namespace libunwind;
4646/// handling.
4747#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
6149static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);
6250static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);
6351static 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,
10896 }
10997 } else {
11098 // Foreign exception.
111 exc = (_Unwind_Exception *)malloc(sizeof(_Unwind_Exception));
112 exc->exception_class = kSEHExceptionClass;
113 exc->exception_cleanup = seh_exc_cleanup;
114 memset(exc->private_, 0, sizeof(exc->private_));
99 // We can't interact with them (we don't know the original target frame
100 // that we should pass on to RtlUnwindEx in _Unwind_Resume), so just
101 // pass without calling our destructors here.
102 return ExceptionContinueSearch;
115103 }
116104 if (!ctx) {
117105 __unw_init_seh(&cursor, disp->ContextRecord);
lib/libunwind/src/UnwindCursor.hpp+51-64
......@@ -81,6 +81,7 @@ template <typename A>
8181class _LIBUNWIND_HIDDEN DwarfFDECache {
8282 typedef typename A::pint_t pint_t;
8383public:
84 static constexpr pint_t kSearchAll = static_cast<pint_t>(-1);
8485 static pint_t findFDE(pint_t mh, pint_t pc);
8586 static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
8687 static void removeAllIn(pint_t mh);
......@@ -138,7 +139,7 @@ typename A::pint_t DwarfFDECache<A>::findFDE(pint_t mh, pint_t pc) {
138139 pint_t result = 0;
139140 _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
140141 for (entry *p = _buffer; p < _bufferUsed; ++p) {
141 if ((mh == p->mh) || (mh == 0)) {
142 if ((mh == p->mh) || (mh == kSearchAll)) {
142143 if ((p->ip_start <= pc) && (pc < p->ip_end)) {
143144 result = p->fde;
144145 break;
......@@ -530,6 +531,8 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
530531 : _addressSpace(as), _unwindInfoMissing(false) {
531532 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
532533 "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");
533536 memset(&_info, 0, sizeof(_info));
534537 memset(&_histTable, 0, sizeof(_histTable));
535538 _dispContext.ContextRecord = &_msContext;
......@@ -923,6 +926,9 @@ private:
923926#endif
924927
925928#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);
926932 bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections &sects,
927933 uint32_t fdeSectionOffsetHint=0);
928934 int stepWithDwarfFDE() {
......@@ -1182,6 +1188,8 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
11821188 _isSignalFrame(false) {
11831189 static_assert((check_fit<UnwindCursor<A, R>, unw_cursor_t>::does_fit),
11841190 "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");
11851193 memset(&_info, 0, sizeof(_info));
11861194}
11871195
......@@ -1472,6 +1480,32 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection(
14721480#endif
14731481
14741482#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
14751509template <typename A, typename R>
14761510bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
14771511 const UnwindInfoSections &sects,
......@@ -1483,7 +1517,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
14831517 // If compact encoding table gave offset into dwarf section, go directly there
14841518 if (fdeSectionOffsetHint != 0) {
14851519 foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1486 (uint32_t)sects.dwarf_section_length,
1520 sects.dwarf_section_length,
14871521 sects.dwarf_section + fdeSectionOffsetHint,
14881522 &fdeInfo, &cieInfo);
14891523 }
......@@ -1500,7 +1534,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
15001534 if (cachedFDE != 0) {
15011535 foundFDE =
15021536 CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1503 (uint32_t)sects.dwarf_section_length,
1537 sects.dwarf_section_length,
15041538 cachedFDE, &fdeInfo, &cieInfo);
15051539 foundInCache = foundFDE;
15061540 }
......@@ -1508,25 +1542,11 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
15081542 if (!foundFDE) {
15091543 // Still not found, do full scan of __eh_frame section.
15101544 foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
1511 (uint32_t)sects.dwarf_section_length, 0,
1545 sects.dwarf_section_length, 0,
15121546 &fdeInfo, &cieInfo);
15131547 }
15141548 if (foundFDE) {
1515 typename CFI_Parser<A>::PrologInfo prolog;
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
1549 if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) {
15301550 // Add to cache (to make next lookup faster) if we had no hint
15311551 // and there was no index.
15321552 if (!foundInCache && (fdeSectionOffsetHint == 0)) {
......@@ -1759,12 +1779,12 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
17591779 }
17601780 }
17611781
1762 // extact personality routine, if encoding says function has one
1782 // extract personality routine, if encoding says function has one
17631783 uint32_t personalityIndex = (encoding & UNWIND_PERSONALITY_MASK) >>
17641784 (__builtin_ctz(UNWIND_PERSONALITY_MASK));
17651785 if (personalityIndex != 0) {
17661786 --personalityIndex; // change 1-based to zero-based index
1767 if (personalityIndex > sectionHeader.personalityArrayCount()) {
1787 if (personalityIndex >= sectionHeader.personalityArrayCount()) {
17681788 _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, "
17691789 "but personality table has only %d entries",
17701790 encoding, personalityIndex,
......@@ -1926,60 +1946,27 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {
19261946#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
19271947 // There is no static unwind info for this pc. Look to see if an FDE was
19281948 // 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);
19301951 if (cachedFDE != 0) {
1931 CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
1932 CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
1933 const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace,
1934 cachedFDE, &fdeInfo, &cieInfo);
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 typename CFI_Parser<A>::FDE_Info fdeInfo;
1953 typename CFI_Parser<A>::CIE_Info cieInfo;
1954 if (!CFI_Parser<A>::decodeFDE(_addressSpace, cachedFDE, &fdeInfo, &cieInfo))
1955 if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
19521956 return;
1953 }
1954 }
19551957 }
19561958
19571959 // Lastly, ask AddressSpace object about platform specific ways to locate
19581960 // other FDEs.
19591961 pint_t fde;
19601962 if (_addressSpace.findOtherFDE(pc, fde)) {
1961 CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
1962 CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
1963 typename CFI_Parser<A>::FDE_Info fdeInfo;
1964 typename CFI_Parser<A>::CIE_Info cieInfo;
19631965 if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
19641966 // Double check this FDE is for a function that includes the pc.
1965 if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
1966 typename CFI_Parser<A>::PrologInfo prolog;
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;
1967 if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd))
1968 if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
19801969 return;
1981 }
1982 }
19831970 }
19841971 }
19851972#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
3939 __unw_init_local(cursor, uc);
4040
4141 // Walk each frame looking for a place to stop.
42 bool handlerNotFound = true;
43 while (handlerNotFound) {
42 while (true) {
4443 // Ask libunwind to get next frame (skip over first which is
4544 // _Unwind_RaiseException).
4645 int stepResult = __unw_step(cursor);
......@@ -102,7 +101,6 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
102101 case _URC_HANDLER_FOUND:
103102 // found a catch clause or locals that need destructing in this frame
104103 // stop search and remember stack pointer at the frame
105 handlerNotFound = false;
106104 __unw_get_reg(cursor, UNW_REG_SP, &sp);
107105 exception_object->private_2 = (uintptr_t)sp;
108106 _LIBUNWIND_TRACE_UNWINDING(
lib/libunwind/src/UnwindRegistersRestore.S+13-12
......@@ -13,14 +13,10 @@
1313#if !defined(__USING_SJLJ_EXCEPTIONS__)
1414
1515#if defined(__i386__)
16DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
16DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto)
1717#
18# void libunwind::Registers_x86::jumpto()
18# extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
1919#
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
2420# On entry:
2521# + +
2622# +-----------------------+
......@@ -30,7 +26,6 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
3026# +-----------------------+ <-- SP
3127# + +
3228 movl 4(%esp), %eax
33#endif
3429 # set up eax and ret on new stack location
3530 movl 28(%eax), %edx # edx holds new stack pointer
3631 subl $8,%edx
......@@ -60,9 +55,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
6055
6156#elif defined(__x86_64__)
6257
63DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
58DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto)
6459#
65# void libunwind::Registers_x86_64::jumpto()
60# extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
6661#
6762#if defined(_WIN64)
6863# On entry, thread_state pointer is in rcx; move it into rdi
......@@ -175,7 +170,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv)
175170 PPC64_LR(30)
176171 PPC64_LR(31)
177172
178#ifdef PPC64_HAS_VMX
173#if defined(__VSX__)
179174
180175 // restore VS registers
181176 // (note that this also restores floating point registers and V registers,
......@@ -317,6 +312,7 @@ PPC64_CLVS_BOTTOM(n)
317312 PPC64_LF(30)
318313 PPC64_LF(31)
319314
315#if defined(__ALTIVEC__)
320316 // restore vector registers if any are in use
321317 ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave
322318 cmpwi %r5, 0
......@@ -378,6 +374,7 @@ PPC64_CLV_UNALIGNED_BOTTOM(n)
378374 PPC64_CLV_UNALIGNEDh(31)
379375
380376#endif
377#endif
381378
382379Lnovec:
383380 ld %r0, PPC64_OFFS_CR(%r3)
......@@ -436,6 +433,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
436433 lwz %r30,128(%r3)
437434 lwz %r31,132(%r3)
438435
436#ifndef __NO_FPRS__
439437 // restore float registers
440438 lfd %f0, 160(%r3)
441439 lfd %f1, 168(%r3)
......@@ -469,7 +467,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
469467 lfd %f29,392(%r3)
470468 lfd %f30,400(%r3)
471469 lfd %f31,408(%r3)
470#endif
472471
472#if defined(__ALTIVEC__)
473473 // restore vector registers if any are in use
474474 lwz %r5, 156(%r3) // test VRsave
475475 cmpwi %r5, 0
......@@ -542,6 +542,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
542542 LOAD_VECTOR_UNALIGNEDh(29)
543543 LOAD_VECTOR_UNALIGNEDh(30)
544544 LOAD_VECTOR_UNALIGNEDh(31)
545#endif
545546
546547Lnovec:
547548 lwz %r0, 136(%r3) // __cr
......@@ -560,13 +561,13 @@ Lnovec:
560561#elif defined(__aarch64__)
561562
562563//
563// void libunwind::Registers_arm64::jumpto()
564// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
564565//
565566// On entry:
566567// thread_state pointer is in x0
567568//
568569 .p2align 2
569DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
570DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
570571 // skip restore of x0,x1 for now
571572 ldp x2, x3, [x0, #0x010]
572573 ldp x4, x5, [x0, #0x020]
lib/libunwind/src/UnwindRegistersSave.S+7-2
......@@ -384,7 +384,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
384384 mfvrsave %r0
385385 std %r0, PPC64_OFFS_VRSAVE(%r3)
386386
387#ifdef PPC64_HAS_VMX
387#if defined(__VSX__)
388388 // save VS registers
389389 // (note that this also saves floating point registers and V registers,
390390 // because part of VS is mapped to these registers)
......@@ -501,6 +501,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
501501 PPC64_STF(30)
502502 PPC64_STF(31)
503503
504#if defined(__ALTIVEC__)
504505 // save vector registers
505506
506507 // Use 16-bytes below the stack pointer as an
......@@ -548,6 +549,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
548549 PPC64_STV_UNALIGNED(30)
549550 PPC64_STV_UNALIGNED(31)
550551
552#endif
551553#endif
552554
553555 li %r3, 0 // return UNW_ESUCCESS
......@@ -608,6 +610,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
608610 mfctr %r0
609611 stw %r0, 148(%r3)
610612
613#if !defined(__NO_FPRS__)
611614 // save float registers
612615 stfd %f0, 160(%r3)
613616 stfd %f1, 168(%r3)
......@@ -641,8 +644,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
641644 stfd %f29,392(%r3)
642645 stfd %f30,400(%r3)
643646 stfd %f31,408(%r3)
647#endif
644648
645
649#if defined(__ALTIVEC__)
646650 // save vector registers
647651
648652 subi %r4, %r1, 16
......@@ -692,6 +696,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
692696 SAVE_VECTOR_UNALIGNED(%v29, 424+0x1D0)
693697 SAVE_VECTOR_UNALIGNED(%v30, 424+0x1E0)
694698 SAVE_VECTOR_UNALIGNED(%v31, 424+0x1F0)
699#endif
695700
696701 li %r3, 0 // return UNW_ESUCCESS
697702 blr
lib/libunwind/src/Unwind_AppleExtras.cpp-70
......@@ -8,35 +8,6 @@
88//===----------------------------------------------------------------------===//
99
1010#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
4213// 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)
140111NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)
141112
142113#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 @@
2525#define PPC64_OFFS_VRSAVE 304
2626#define PPC64_OFFS_FP 312
2727#define PPC64_OFFS_V 824
28#ifdef _ARCH_PWR8
29#define PPC64_HAS_VMX
30#endif
3128#elif defined(__APPLE__) && defined(__aarch64__)
3229#define SEPARATOR %%
3330#else
......@@ -48,6 +45,24 @@
4845#define PPC64_OPD2
4946#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
5166#define GLUE2(a, b) a ## b
5267#define GLUE(a, b) GLUE2(a, b)
5368#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
......@@ -144,7 +159,8 @@
144159 SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \
145160 PPC64_OPD1 \
146161 SYMBOL_NAME(name): \
147 PPC64_OPD2
162 PPC64_OPD2 \
163 AARCH64_BTI
148164
149165#if defined(__arm__)
150166#if !defined(__ARM_ARCH)
lib/libunwind/src/config.h+39-15
......@@ -18,23 +18,15 @@
1818#include <stdint.h>
1919#include <stdlib.h>
2020
21// Define static_assert() unless already defined by compiler.
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
21#include <__libunwind_config.h>
3022
3123// Platform specific configuration defines.
3224#ifdef __APPLE__
3325 #if defined(FOR_DYLD)
34 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
26 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
3527 #else
36 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
37 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
28 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
29 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
3830 #endif
3931#elif defined(_WIN32)
4032 #ifdef __SEH__
......@@ -42,8 +34,19 @@
4234 #else
4335 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
4436 #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
4546#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)
4750 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
4851 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
4952 #endif
......@@ -91,6 +94,8 @@
9194#error Unsupported target
9295#endif
9396
97// Apple/armv7k defaults to DWARF/Compact unwinding, but its libunwind also
98// needs to include the SJLJ APIs.
9499#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
95100#define _LIBUNWIND_BUILD_SJLJ_APIS
96101#endif
......@@ -111,8 +116,27 @@
111116#endif
112117#endif
113118
114#if defined(__powerpc64__) && defined(_ARCH_PWR8)
115#define PPC64_HAS_VMX
119#ifndef _LIBUNWIND_REMEMBER_HEAP_ALLOC
120#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
116140#endif
117141
118142#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)