diff --git a/deps/Versions.make b/deps/Versions.make index 083dc0b48a1b8d..5829a0c5b9fccb 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -104,9 +104,9 @@ LIBSUITESPARSE_VER := 5.10.1 LIBSUITESPARSE_JLL_NAME := SuiteSparse # unwind -UNWIND_VER := 1.3.2 +UNWIND_VER := 1.5.0 UNWIND_JLL_NAME := LibUnwind -UNWIND_JLL_VER := 1.3.2+4 +UNWIND_JLL_VER := 1.5.0+0 # zlib ZLIB_VER := 1.2.11 diff --git a/deps/patches/libunwind-cfa-rsp.patch b/deps/patches/libunwind-cfa-rsp.patch index 7803f0b52924e0..6b2080c10c2cf1 100644 --- a/deps/patches/libunwind-cfa-rsp.patch +++ b/deps/patches/libunwind-cfa-rsp.patch @@ -1,34 +1,46 @@ -commit c71298423c26b2143dc6f6ce554ec910ed882f8a -Author: Keno Fischer -Date: Sat Feb 6 18:13:16 2021 -0500 +From 8c8c78e2db09c5dc66ad0188a088b1664483a13f Mon Sep 17 00:00:00 2001 +From: Keno Fischer +Date: Sun, 29 Aug 2021 11:07:54 -0700 +Subject: [PATCH] x86_64: Stop aliasing RSP and CFA - x86_64: Stop aliasing RSP and CFA - - RSP and CFA are different concepts. RSP refers to the physical - register, CFA is a virtual register that serves as the base - address for various other saved registers. It is true that - in many frames these are set to alias, however this is not - a requirement. For example, a function that performs a stack - switch would likely change the rsp in the middle of the function, - but would keep the CFA at the original RSP such that saved registers - may be appropriately recovered. - - We are seeing incorrect unwinds in the Julia runtime when running - julia under rr. This is because injects code (with correct CFI) - that performs just such a stack switch [1]. GDB manages to unwind - this correctly, but libunwind incorrectly sets the rsp to the CFA - address, causing a misunwind. - - Tested on x86_64, patches for other architectures are ported, but - not tested. - - [1] https://github.com/rr-debugger/rr/blob/469c22059a4a1798d33a8a224457faf22b2c178c/src/preload/syscall_hook.S#L454 +RSP and CFA are different concepts. RSP refers to the physical +register, CFA is a virtual register that serves as the base +address for various other saved registers. It is true that +in many frames these are set to alias, however this is not +a requirement. For example, a function that performs a stack +switch would likely change the rsp in the middle of the function, +but would keep the CFA at the original RSP such that saved registers +may be appropriately recovered. + +We are seeing incorrect unwinds in the Julia runtime when running +julia under rr. This is because injects code (with correct CFI) +that performs just such a stack switch [1]. GDB manages to unwind +this correctly, but libunwind incorrectly sets the rsp to the CFA +address, causing a misunwind. + +Tested on x86_64, patches for other architectures are ported, but +not tested. + +[1] https://github.com/rr-debugger/rr/blob/469c22059a4a1798d33a8a224457faf22b2c178c/src/preload/syscall_hook.S#L454 +--- + include/dwarf.h | 3 +- + include/libunwind_i.h | 4 ++ + include/tdep-x86/dwarf-config.h | 2 - + include/tdep-x86/libunwind_i.h | 73 ++++++++++++--------------------- + src/dwarf/Gparser.c | 15 +++++-- + src/x86/Gos-freebsd.c | 1 + + src/x86/Gregs.c | 2 +- + src/x86/Gstep.c | 4 +- + src/x86_64/Gos-freebsd.c | 1 + + src/x86_64/Gregs.c | 2 +- + src/x86_64/Gstep.c | 2 +- + 11 files changed, 52 insertions(+), 57 deletions(-) diff --git a/include/dwarf.h b/include/dwarf.h -index fab93c61..b845e2eb 100644 +index 175c419bb..23ff4c4f6 100644 --- a/include/dwarf.h +++ b/include/dwarf.h -@@ -227,6 +227,7 @@ typedef enum +@@ -231,6 +231,7 @@ typedef enum DWARF_WHERE_REG, /* register saved in another register */ DWARF_WHERE_EXPR, /* register saved */ DWARF_WHERE_VAL_EXPR, /* register has computed value */ @@ -36,7 +48,7 @@ index fab93c61..b845e2eb 100644 } dwarf_where_t; -@@ -309,7 +310,7 @@ typedef struct dwarf_cursor +@@ -313,7 +314,7 @@ typedef struct dwarf_cursor void *as_arg; /* argument to address-space callbacks */ unw_addr_space_t as; /* reference to per-address-space info */ @@ -46,10 +58,10 @@ index fab93c61..b845e2eb 100644 unw_word_t args_size; /* size of arguments */ unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS]; diff --git a/include/libunwind_i.h b/include/libunwind_i.h -index 36cf7a14..dcec1683 100644 +index fea5c2607..6c7dda9a8 100644 --- a/include/libunwind_i.h +++ b/include/libunwind_i.h -@@ -351,6 +351,10 @@ static inline void invalidate_edi (struct elf_dyn_info *edi) +@@ -346,6 +346,10 @@ static inline void invalidate_edi (struct elf_dyn_info *edi) #include "tdep/libunwind_i.h" @@ -61,7 +73,7 @@ index 36cf7a14..dcec1683 100644 # define tdep_get_func_addr(as,addr,v) (*(v) = addr, 0) #endif diff --git a/include/tdep-x86/dwarf-config.h b/include/tdep-x86/dwarf-config.h -index f76f9c1c..11398e4e 100644 +index f76f9c1c4..11398e4e6 100644 --- a/include/tdep-x86/dwarf-config.h +++ b/include/tdep-x86/dwarf-config.h @@ -43,9 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ @@ -75,21 +87,19 @@ index f76f9c1c..11398e4e 100644 dwarf_loc_t; diff --git a/include/tdep-x86/libunwind_i.h b/include/tdep-x86/libunwind_i.h -index 5231189a..1b59fe34 100644 +index d4c5ccdb1..ad4edc2f5 100644 --- a/include/tdep-x86/libunwind_i.h +++ b/include/tdep-x86/libunwind_i.h -@@ -88,14 +88,28 @@ dwarf_get_uc(const struct dwarf_cursor *cursor) +@@ -84,15 +84,26 @@ dwarf_get_uc(const struct dwarf_cursor *cursor) + } #define DWARF_GET_LOC(l) ((l).val) - --#ifdef UNW_LOCAL_ONLY -+ -+#define DWARF_GET_LOC(l) ((l).val) +# define DWARF_LOC_TYPE_MEM (0 << 0) +# define DWARF_LOC_TYPE_FP (1 << 0) +# define DWARF_LOC_TYPE_REG (1 << 1) +# define DWARF_LOC_TYPE_VAL (1 << 2) -+ + +-#ifdef UNW_LOCAL_ONLY +# define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) +# define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) +# define DWARF_IS_MEM_LOC(l) ((l).type == DWARF_LOC_TYPE_MEM) @@ -112,7 +122,7 @@ index 5231189a..1b59fe34 100644 # define DWARF_FPREG_LOC(c,r) (DWARF_LOC((unw_word_t) \ tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) -@@ -117,35 +131,8 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +@@ -114,35 +125,8 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) return 0; } @@ -148,7 +158,7 @@ index 5231189a..1b59fe34 100644 # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ | DWARF_LOC_TYPE_FP)) -@@ -195,38 +182,33 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) +@@ -192,38 +176,33 @@ dwarf_putfp (struct dwarf_cursor *c, dwarf_loc_t loc, unw_fpreg_t val) 1, c->as_arg); } @@ -195,7 +205,7 @@ index 5231189a..1b59fe34 100644 if (DWARF_IS_REG_LOC (loc)) return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), &val, 1, c->as_arg); -@@ -235,7 +217,9 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +@@ -232,7 +211,9 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) 1, c->as_arg); } @@ -207,18 +217,10 @@ index 5231189a..1b59fe34 100644 #define tdep_getcontext_trace unw_getcontext #define tdep_init_done UNW_OBJ(init_done) diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c -index 7d255aee..b1308d3c 100644 +index da170d4b3..70a62c505 100644 --- a/src/dwarf/Gparser.c +++ b/src/dwarf/Gparser.c -@@ -28,6 +28,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #include - #include - -+ - #define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool)) - #define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs)) - -@@ -501,6 +502,9 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) +@@ -508,6 +508,9 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) set_reg (sr, i, DWARF_WHERE_SAME, 0); @@ -228,7 +230,7 @@ index 7d255aee..b1308d3c 100644 struct dwarf_cie_info *dci = c->pi.unwind_info; sr->rs_current.ret_addr_column = dci->ret_addr_column; unw_word_t addr = dci->cie_instr_start; -@@ -785,14 +789,14 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) +@@ -792,14 +795,14 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) /* As a special-case, if the stack-pointer is the CFA and the stack-pointer wasn't saved, popping the CFA implicitly pops the stack-pointer as well. */ @@ -247,7 +249,7 @@ index 7d255aee..b1308d3c 100644 return ret; } cfa += rs->reg.val[DWARF_CFA_OFF_COLUMN]; -@@ -826,6 +830,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) +@@ -836,6 +839,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) case DWARF_WHERE_SAME: break; @@ -259,7 +261,7 @@ index 7d255aee..b1308d3c 100644 new_loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg.val[i]); break; diff --git a/src/x86/Gos-freebsd.c b/src/x86/Gos-freebsd.c -index 7dd01404..1b251d02 100644 +index 7dd014046..1b251d027 100644 --- a/src/x86/Gos-freebsd.c +++ b/src/x86/Gos-freebsd.c @@ -138,6 +138,7 @@ x86_handle_signal_frame (unw_cursor_t *cursor) @@ -271,7 +273,7 @@ index 7dd01404..1b251d02 100644 c->dwarf.cfa += 4; c->dwarf.use_prev_instr = 1; diff --git a/src/x86/Gregs.c b/src/x86/Gregs.c -index 4a959261..9446d6c6 100644 +index 4a9592617..9446d6c62 100644 --- a/src/x86/Gregs.c +++ b/src/x86/Gregs.c @@ -53,7 +53,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, @@ -291,7 +293,7 @@ index 4a959261..9446d6c6 100644 case UNW_X86_ESI: loc = c->dwarf.loc[ESI]; break; case UNW_X86_EDI: loc = c->dwarf.loc[EDI]; break; diff --git a/src/x86/Gstep.c b/src/x86/Gstep.c -index 129b739a..061dcbaa 100644 +index 129b739a3..061dcbaaa 100644 --- a/src/x86/Gstep.c +++ b/src/x86/Gstep.c @@ -47,7 +47,7 @@ unw_step (unw_cursor_t *cursor) @@ -319,35 +321,8 @@ index 129b739a..061dcbaa 100644 c->dwarf.loc[EIP] = eip_loc; c->dwarf.use_prev_instr = 1; } -diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c -index b7e8e462..64b800af 100644 ---- a/src/x86_64/Ginit.c -+++ b/src/x86_64/Ginit.c -@@ -49,8 +49,6 @@ static struct unw_addr_space local_addr_space; - - unw_addr_space_t unw_local_addr_space = &local_addr_space; - --HIDDEN unw_dyn_info_list_t _U_dyn_info_list; -- - /* XXX fix me: there is currently no way to locate the dyn-info list - by a remote unwinder. On ia64, this is done via a special - unwind-table entry. Perhaps something similar can be done with -@@ -66,7 +64,12 @@ static int - get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, - void *arg) - { -- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; -+#ifndef UNW_LOCAL_ONLY -+# pragma weak _U_dyn_info_list_addr -+ if (!_U_dyn_info_list_addr) -+ return -UNW_ENOINFO; -+#endif -+ *dyn_info_list_addr = _U_dyn_info_list_addr (); - return 0; - } - diff --git a/src/x86_64/Gos-freebsd.c b/src/x86_64/Gos-freebsd.c -index 883025c8..8bb101ea 100644 +index 8f28d1d8c..0c5a17940 100644 --- a/src/x86_64/Gos-freebsd.c +++ b/src/x86_64/Gos-freebsd.c @@ -133,6 +133,7 @@ x86_64_handle_signal_frame (unw_cursor_t *cursor) @@ -359,7 +334,7 @@ index 883025c8..8bb101ea 100644 ret = dwarf_get (&c->dwarf, c->dwarf.loc[RIP], &c->dwarf.ip); Debug (1, "Frame Chain [RIP=0x%Lx] = 0x%Lx\n", diff --git a/src/x86_64/Gregs.c b/src/x86_64/Gregs.c -index baf8a24f..dff5bcbe 100644 +index baf8a24f0..dff5bcbe7 100644 --- a/src/x86_64/Gregs.c +++ b/src/x86_64/Gregs.c @@ -79,7 +79,6 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, @@ -379,15 +354,15 @@ index baf8a24f..dff5bcbe 100644 case UNW_X86_64_RSI: loc = c->dwarf.loc[RSI]; break; case UNW_X86_64_RDI: loc = c->dwarf.loc[RDI]; break; diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c -index 10498170..5425e3db 100644 +index 3c5c3830f..fdad298c7 100644 --- a/src/x86_64/Gstep.c +++ b/src/x86_64/Gstep.c -@@ -160,7 +160,7 @@ unw_step (unw_cursor_t *cursor) - { - unw_word_t rbp1 = 0; - rbp_loc = DWARF_LOC(rbp, 0); -- rsp_loc = DWARF_NULL_LOC; -+ rsp_loc = DWARF_VAL_LOC(c, rbp + 16); - rip_loc = DWARF_LOC (rbp + 8, 0); - ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); - Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", +@@ -223,7 +223,7 @@ unw_step (unw_cursor_t *cursor) + Debug (2, "RIP fixup didn't work, falling back\n"); + unw_word_t rbp1 = 0; + rbp_loc = DWARF_LOC(rbp, 0); +- rsp_loc = DWARF_NULL_LOC; ++ rsp_loc = DWARF_VAL_LOC(c, rbp + 16); + rip_loc = DWARF_LOC (rbp + 8, 0); + ret = dwarf_get (&c->dwarf, rbp_loc, &rbp1); + Debug (1, "[RBP=0x%lx] = 0x%lx (cfa = 0x%lx) -> 0x%lx\n", diff --git a/deps/patches/libunwind-prefer-extbl.patch b/deps/patches/libunwind-prefer-extbl.patch index 8d93605e337af7..07b172604d6236 100644 --- a/deps/patches/libunwind-prefer-extbl.patch +++ b/deps/patches/libunwind-prefer-extbl.patch @@ -1,6 +1,6 @@ -From bc7b50355cb37cfa56f6131b2f9174b499053188 Mon Sep 17 00:00:00 2001 +From 2d6a50435bb743be1e4d88eee002372344348349 Mon Sep 17 00:00:00 2001 From: Yichao Yu -Date: Sat, 1 Oct 2016 16:55:40 +0000 +Date: Sun, 29 Aug 2021 13:43:01 -0700 Subject: [PATCH] Prefer EXTBL unwinding on ARM It is part of the C++ ABI so a EXTBL unwind info that's not `CANT_UNWIND` @@ -8,16 +8,16 @@ should always be reliable/correct. Ignore `ESTOPUNWIND` so that a `CANT_UNWIND` info can fallback to unwinding using the debug info instead. --- - include/tdep-arm/libunwind_i.h | 4 ++++ - src/arm/Gex_tables.c | 18 ++++++++++++++---- - src/arm/Gstep.c | 35 +++++++++++++++++++++-------------- - 3 files changed, 39 insertions(+), 18 deletions(-) + include/tdep-arm/libunwind_i.h | 4 +++ + src/arm/Gex_tables.c | 18 ++++++++--- + src/arm/Gstep.c | 55 ++++++++++++++++++++-------------- + 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h -index 2602f41c..074fc8cb 100644 +index 88ebfb069..5bd28c953 100644 --- a/include/tdep-arm/libunwind_i.h +++ b/include/tdep-arm/libunwind_i.h -@@ -253,6 +253,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +@@ -256,6 +256,7 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) #define tdep_init_done UNW_OBJ(init_done) #define tdep_init UNW_OBJ(init) #define arm_find_proc_info UNW_OBJ(find_proc_info) @@ -25,7 +25,7 @@ index 2602f41c..074fc8cb 100644 #define arm_put_unwind_info UNW_OBJ(put_unwind_info) /* Platforms that support UNW_INFO_FORMAT_TABLE need to define tdep_search_unwind_table. */ -@@ -294,6 +295,9 @@ extern void tdep_init (void); +@@ -297,6 +298,9 @@ extern void tdep_init (void); extern int arm_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, int need_unwind_info, void *arg); @@ -36,7 +36,7 @@ index 2602f41c..074fc8cb 100644 unw_proc_info_t *pi, void *arg); extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip, diff --git a/src/arm/Gex_tables.c b/src/arm/Gex_tables.c -index d6573a65..a895e0cc 100644 +index efdcf2978..083d2b2f7 100644 --- a/src/arm/Gex_tables.c +++ b/src/arm/Gex_tables.c @@ -506,18 +506,20 @@ arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data) @@ -80,17 +80,17 @@ index d6573a65..a895e0cc 100644 arm_put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) { diff --git a/src/arm/Gstep.c b/src/arm/Gstep.c -index adec02e0..c43daa1c 100644 +index 895e8a892..e4ada651b 100644 --- a/src/arm/Gstep.c +++ b/src/arm/Gstep.c -@@ -53,8 +53,15 @@ arm_exidx_step (struct cursor *c) +@@ -54,17 +54,22 @@ arm_exidx_step (struct cursor *c) c->dwarf.as_arg); if (ret == -UNW_ENOINFO) { +#ifdef UNW_LOCAL_ONLY -+ if ((ret = arm_find_proc_info2 (c->dwarf.as, ip, &c->dwarf.pi, -+ 1, c->dwarf.as_arg, -+ UNW_ARM_METHOD_EXIDX)) < 0) ++ if ((ret = arm_find_proc_info2 (c->dwarf.as, ip, &c->dwarf.pi, ++ 1, c->dwarf.as_arg, ++ UNW_ARM_METHOD_EXIDX)) < 0) + return ret; +#else if ((ret = tdep_find_proc_info (&c->dwarf, ip, 1)) < 0) @@ -99,21 +99,39 @@ index adec02e0..c43daa1c 100644 } if (c->dwarf.pi.format != UNW_INFO_FORMAT_ARM_EXIDX) -@@ -94,8 +101,21 @@ unw_step (unw_cursor_t *cursor) + return -UNW_ENOINFO; + + ret = arm_exidx_extract (&c->dwarf, buf); +- if (ret == -UNW_ESTOPUNWIND) +- return 0; +- else if (ret < 0) ++ if (ret < 0) + return ret; + + ret = arm_exidx_decode (buf, ret, &c->dwarf); +@@ -88,6 +93,7 @@ unw_step (unw_cursor_t *cursor) + { + struct cursor *c = (struct cursor *) cursor; + int ret = -UNW_EUNSPEC; ++ int has_stopunwind = 0; + + Debug (1, "(cursor=%p)\n", c); + +@@ -95,17 +101,31 @@ unw_step (unw_cursor_t *cursor) if (unw_is_signal_frame (cursor) > 0) return arm_handle_signal_frame (cursor); + /* First, try extbl-based unwinding. */ + if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) + { -+ Debug (13, "%s(ret=%d), trying extbl\n", -+ UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() failed " : "", -+ ret); + ret = arm_exidx_step (c); ++ Debug(1, "arm_exidx_step()=%d\n", ret); + if (ret > 0) + return 1; + if (ret == 0) + return ret; ++ if (ret == -UNW_ESTOPUNWIND) ++ has_stopunwind = 1; + } + #ifdef CONFIG_DEBUG_FRAME @@ -121,24 +139,56 @@ index adec02e0..c43daa1c 100644 + /* Second, try DWARF-based unwinding. */ if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) { ++ Debug (13, "%s(ret=%d), trying extbl\n", ++ UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) ? "arm_exidx_step() failed " : "", ++ ret); ret = dwarf_step (&c->dwarf); -@@ -114,16 +129,6 @@ unw_step (unw_cursor_t *cursor) + Debug(1, "dwarf_step()=%d\n", ret); + + if (likely (ret > 0)) + return 1; +- else if (unlikely (ret == -UNW_ESTOPUNWIND)) +- return ret; + + if (ret < 0 && ret != -UNW_ENOINFO) + { +@@ -115,18 +135,9 @@ unw_step (unw_cursor_t *cursor) } #endif /* CONFIG_DEBUG_FRAME */ - /* Next, try extbl-based unwinding. */ - if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)) - { +- Debug (13, "%s(ret=%d), trying extbl\n", +- UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() failed " : "", +- ret); - ret = arm_exidx_step (c); - if (ret > 0) - return 1; - if (ret == -UNW_ESTOPUNWIND || ret == 0) - return ret; - } -- ++ // Before trying the fallback, if any unwind info tell us to stop, do that. ++ if (has_stopunwind) ++ return -UNW_ESTOPUNWIND; + /* Fall back on APCS frame parsing. Note: This won't work in case the ARM EABI is used. */ - #ifdef __FreeBSD__ --- -2.16.1 - +@@ -139,13 +150,13 @@ unw_step (unw_cursor_t *cursor) + if (UNW_TRY_METHOD(UNW_ARM_METHOD_FRAME)) + { + Debug (13, "%s%s%s%s(ret=%d), trying frame-chain\n", +- UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() " : "", +- (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) && UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "and " : "", + UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) ? "arm_exidx_step() " : "", +- (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) || UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX)) ? "failed " : "", ++ (UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) && UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) ? "and " : "", ++ UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF) ? "dwarf_step() " : "", ++ (UNW_TRY_METHOD(UNW_ARM_METHOD_EXIDX) || UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)) ? "failed " : "", + ret); + ret = UNW_ESUCCESS; +- /* DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ ++ /* EXIDX and/or DWARF unwinding failed, try to follow APCS/optimized APCS frame chain */ + unw_word_t instr, i; + dwarf_loc_t ip_loc, fp_loc; + unw_word_t frame; diff --git a/deps/unwind.mk b/deps/unwind.mk index f494e704abc0c0..a4f6c6099f07cb 100644 --- a/deps/unwind.mk +++ b/deps/unwind.mk @@ -4,8 +4,15 @@ ifneq ($(USE_BINARYBUILDER_LIBUNWIND),1) LIBUNWIND_CFLAGS := -U_FORTIFY_SOURCE $(fPIC) LIBUNWIND_CPPFLAGS := +# XXX: Kludge for libunwind 1.5.0 tag name not being the full version +ifeq ($(UNWIND_VER),1.5.0) +UNWIND_TAG := 1.5 +else +UNWIND_TAG := $(UNWIND_VER) +endif + $(SRCCACHE)/libunwind-$(UNWIND_VER).tar.gz: | $(SRCCACHE) - $(JLDOWNLOAD) $@ https://github.com/libunwind/libunwind/releases/download/v$(UNWIND_VER)/libunwind-$(UNWIND_VER).tar.gz + $(JLDOWNLOAD) $@ https://github.com/libunwind/libunwind/releases/download/v$(UNWIND_TAG)/libunwind-$(UNWIND_VER).tar.gz $(SRCCACHE)/libunwind-$(UNWIND_VER)/source-extracted: $(SRCCACHE)/libunwind-$(UNWIND_VER).tar.gz $(JLCHECKSUM) $< @@ -31,7 +38,7 @@ $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-cfa-rsp.patch-applied: $(SRCCACHE) $(BUILDDIR)/libunwind-$(UNWIND_VER)/build-configured: $(SRCCACHE)/libunwind-$(UNWIND_VER)/source-extracted $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-cfa-rsp.patch-applied mkdir -p $(dir $@) cd $(dir $@) && \ - $(dir $<)/configure $(CONFIGURE_COMMON) CPPFLAGS="$(CPPFLAGS) $(LIBUNWIND_CPPFLAGS)" CFLAGS="$(CFLAGS) $(LIBUNWIND_CFLAGS)" --enable-shared --disable-minidebuginfo --disable-tests + $(dir $<)/configure $(CONFIGURE_COMMON) CPPFLAGS="$(CPPFLAGS) $(LIBUNWIND_CPPFLAGS)" CFLAGS="$(CFLAGS) $(LIBUNWIND_CFLAGS)" --enable-shared --disable-minidebuginfo --disable-tests --disable-zlibdebuginfo echo 1 > $@ $(BUILDDIR)/libunwind-$(UNWIND_VER)/build-compiled: $(BUILDDIR)/libunwind-$(UNWIND_VER)/build-configured