diff --git a/deps/Versions.make b/deps/Versions.make index 79db4e964ce0e..625f594469725 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -101,7 +101,7 @@ SUITESPARSE_JLL_NAME := SuiteSparse # unwind UNWIND_VER := 1.3.2 UNWIND_JLL_NAME := LibUnwind -UNWIND_JLL_VER := 1.3.2+3 +UNWIND_JLL_VER := 1.3.2+4 # zlib ZLIB_VER := 1.2.11 diff --git a/deps/checksums/unwind b/deps/checksums/unwind index 545c756d07f9a..f94bd78639bbe 100644 --- a/deps/checksums/unwind +++ b/deps/checksums/unwind @@ -1,26 +1,26 @@ LibOSXUnwind.v0.0.6+1.x86_64-apple-darwin.tar.gz/md5/fd98df2005d13aa16341c5aecba1af70 LibOSXUnwind.v0.0.6+1.x86_64-apple-darwin.tar.gz/sha512/2d2263c3e5f095ad9eba7fea7cb882a19fece8a10486489d0a15b8e81ea0f8626804c4822b8c92a26a608d568c0ff1a4e976ea6d746be47ac1a70891455162a6 -LibUnwind.v1.3.2+3.aarch64-linux-gnu.tar.gz/md5/fba1f405a3a7c8bc4f68c17d771100b0 -LibUnwind.v1.3.2+3.aarch64-linux-gnu.tar.gz/sha512/a37d3f9da9a133bb270cc1046c7018579731897fed0ef6ab1fbeb0dde38e7be294a4e2abf41096c7edde617e266f1acc95777b34e22b6a8ced0e27b2228b0ec5 -LibUnwind.v1.3.2+3.aarch64-linux-musl.tar.gz/md5/587de98245251124c0d29b0b478374ec -LibUnwind.v1.3.2+3.aarch64-linux-musl.tar.gz/sha512/9f10eee8e4f5117dfc4689378c93ba16e205aaa89eec5681e0b1e34e7c2d334717b327cae8d5024db6a1f6a2633454cb77b577112a0a03a3282e566705c1a81e -LibUnwind.v1.3.2+3.armv6l-linux-gnueabihf.tar.gz/md5/953bfa931cb8e44d39ae22d7ccab1f22 -LibUnwind.v1.3.2+3.armv6l-linux-gnueabihf.tar.gz/sha512/54ee57c35895cbaed2160d451ca33ac9e8adf157b7f825853f7e92f8304f799f2671f5361dae7d2e7d111a3ab1f749cddb96a2c04b7b8fc7844b1e021dbc443f -LibUnwind.v1.3.2+3.armv6l-linux-musleabihf.tar.gz/md5/5d16fd194ec5a7e46e1e1679072cec0f -LibUnwind.v1.3.2+3.armv6l-linux-musleabihf.tar.gz/sha512/1ae68a77eadaf73de9de266bb3e2f61457faae6b2f971988363d2d1bebf855bdbc55ad848266335a9b3c040308e0bd3e3b66d5b66fe8807e0fb774c22bac928d -LibUnwind.v1.3.2+3.armv7l-linux-gnueabihf.tar.gz/md5/569da138256de02784ba81b01e08a3db -LibUnwind.v1.3.2+3.armv7l-linux-gnueabihf.tar.gz/sha512/264636b57ca49feb005752636671fe1c24264b15d1caca0c0808e89966a7683e7821a56e41b89cde9e32b688cf94647ae61de74f0428b7b1f92be2bed6674114 -LibUnwind.v1.3.2+3.armv7l-linux-musleabihf.tar.gz/md5/c9d2f634a742d71e471dd7ff691bf39d -LibUnwind.v1.3.2+3.armv7l-linux-musleabihf.tar.gz/sha512/01c2085d49390ace5c128507a86d23b99d746cce080cc7b6415e1c75e63082d01b047b2cf98f3f76768fb49423c5524f53d253858d82864f09e8182a86be57ad -LibUnwind.v1.3.2+3.i686-linux-gnu.tar.gz/md5/92e075574e65c735f6202cc49ec51593 -LibUnwind.v1.3.2+3.i686-linux-gnu.tar.gz/sha512/03f9a71b1b1b0752a835201248cdb2d17f076a82b0928e20f45fc2b8db0914128028c0d589ff94a97847265c216420240b2369af83c4a343d3ca37c58fdcf35a -LibUnwind.v1.3.2+3.i686-linux-musl.tar.gz/md5/fa506359a72ffdf2c3713b5724ad4413 -LibUnwind.v1.3.2+3.i686-linux-musl.tar.gz/sha512/0558e871e838e6ce265c73fd7335bd0a486722ce9a710957b2e67731c494c5781a3a37176ba758f74fee37d48ee43acf02aac5092e24230523dd537610b58720 -LibUnwind.v1.3.2+3.powerpc64le-linux-gnu.tar.gz/md5/3f76849a52550e169d6f47ef95ca3d75 -LibUnwind.v1.3.2+3.powerpc64le-linux-gnu.tar.gz/sha512/2f3a119ccf1fffa8460e2350b66bf2303d11d636e649e144750e362d2e08f61d076adda71b5441b4337eaee6fb1e95049aac87de89be1415ca80f1b69c77f310 -LibUnwind.v1.3.2+3.x86_64-linux-gnu.tar.gz/md5/624779c4bc930ae2ba5f6a5d25c73aeb -LibUnwind.v1.3.2+3.x86_64-linux-gnu.tar.gz/sha512/2eb467537e5f2acee7d5b2a5939c712ca96195584c37606d1ff1bcc0683514decefcae042f566633905472c177115c1467c1503bf331d8d7293b3026628bc138 -LibUnwind.v1.3.2+3.x86_64-linux-musl.tar.gz/md5/7ddcbe93c8bdb1edde0ffab23db3ced7 -LibUnwind.v1.3.2+3.x86_64-linux-musl.tar.gz/sha512/06901d074c15c34002957122897b6b9c449f9c64745363f6fe2886c862197cc6848ca17c3d777eac315fd1d8d90fe236a223167b0aa9fd3b625fd80e3db97655 -LibUnwind.v1.3.2+3.x86_64-unknown-freebsd.tar.gz/md5/ca388d44a8ca365b66999e4b4d1853a2 -LibUnwind.v1.3.2+3.x86_64-unknown-freebsd.tar.gz/sha512/dfbe0a6b5835b51ebea181bb996ffc8fcd8b08acf71243e171c59edb655fd65b6ba59291c10af923f75b7cbb2f52b46adf65ebdca3eee172d279ae357a35205c +LibUnwind.v1.3.2+4.aarch64-linux-gnu.tar.gz/md5/8f5cbf9820033211513f6d33e36194f1 +LibUnwind.v1.3.2+4.aarch64-linux-gnu.tar.gz/sha512/589886c4f141064126aecc1bf63365c610a4c3dd70e386aa8e17ce562505cac873542fa92cea023850e9bf54fcef3cf475d52f035d17d830a81c01d06d0454e4 +LibUnwind.v1.3.2+4.aarch64-linux-musl.tar.gz/md5/836a2d8ea7a11d87a74aee09f82582b5 +LibUnwind.v1.3.2+4.aarch64-linux-musl.tar.gz/sha512/4cd3805ae59854fdceee441967ba4b812246cf1a1e9ed20367f5bbbad9a47f0093731b4f78f881c696e52c101dec83498398c7b798c81c1a441232cd4ee96b58 +LibUnwind.v1.3.2+4.armv6l-linux-gnueabihf.tar.gz/md5/0047d02c4b4888050b363c77106d4ea1 +LibUnwind.v1.3.2+4.armv6l-linux-gnueabihf.tar.gz/sha512/8b02fb5189ca749e421fc17d560601e8624cbcc19a4c5c45e38828323b33db30ced8a92e08ebd429c663e52358c486d3e284e7e04898229cff2839cc01c067d5 +LibUnwind.v1.3.2+4.armv6l-linux-musleabihf.tar.gz/md5/1fe78c6f0ff7120b35c6745b16c6f838 +LibUnwind.v1.3.2+4.armv6l-linux-musleabihf.tar.gz/sha512/9576f913fbc40d00b42573f600c038fea85eb3c9b88a4878cff0e041c4096d9d005b856dbcd0d057dc40a3cdb74deeca6e9c1cc5c213e6e062328f75633ba8e3 +LibUnwind.v1.3.2+4.armv7l-linux-gnueabihf.tar.gz/md5/510db51b0364cf17207eb00e44d58974 +LibUnwind.v1.3.2+4.armv7l-linux-gnueabihf.tar.gz/sha512/76f119654a65b460917f41a321008c5a0593523db53fa12ac9aa82732368ebdee05d6366fdfdcdd300ba0fe4c7239aac25d80fb3b1ad0235f79b235dab68c796 +LibUnwind.v1.3.2+4.armv7l-linux-musleabihf.tar.gz/md5/4bb58bdc423312c74eafe52a781dd712 +LibUnwind.v1.3.2+4.armv7l-linux-musleabihf.tar.gz/sha512/02b69ec40dfcacc447169786bab3aac39c6db6b07874e9657c49a2907654be79efe16863abf09ee1e2a647cd6a651155b65bdbbd6d810a3ceaa332fc0a3ace4b +LibUnwind.v1.3.2+4.i686-linux-gnu.tar.gz/md5/76f549ae171aad91570d7874e73f44f6 +LibUnwind.v1.3.2+4.i686-linux-gnu.tar.gz/sha512/a5a654dd6233099e841d1b9c54b16cb99d736549d063e28d17d5f2014c3090d829a4a8dc4fee042d0f4a9d8a155fb30c5840cb84b9fd71758256fa072137baad +LibUnwind.v1.3.2+4.i686-linux-musl.tar.gz/md5/f8b58f061a03f24111f39f2f8cf72c61 +LibUnwind.v1.3.2+4.i686-linux-musl.tar.gz/sha512/cc6dedc551ee4d5e131cdd7ea7dd4a9cc64efe930d16cddb0c21dca7b13076b6810e00e406acb949404c80b506ca9e09d1e223069d8159e9f73fa8aa022e3f41 +LibUnwind.v1.3.2+4.powerpc64le-linux-gnu.tar.gz/md5/2fd4fda3c82c99ff102b630d078723f5 +LibUnwind.v1.3.2+4.powerpc64le-linux-gnu.tar.gz/sha512/b1c7f16d2877e08cfc9d1aa63c5c9acf30049bd11bdad90c6b1425a09f86762c76f0c1a27817ea1b939244f6e24320854552bc860c95f297a772403eeddc053d +LibUnwind.v1.3.2+4.x86_64-linux-gnu.tar.gz/md5/cd98359922fddcbbcfda56fbc011bea4 +LibUnwind.v1.3.2+4.x86_64-linux-gnu.tar.gz/sha512/7b2d78869be148db23ab8372bb6699abcf26cc58718871f050b8e67054c0c6c909f9a8c59d27c748abeef0ecb5eabc09484043c3b2232469d03c78a42a590e13 +LibUnwind.v1.3.2+4.x86_64-linux-musl.tar.gz/md5/bd8ea5006d6078a1d91743f599f37732 +LibUnwind.v1.3.2+4.x86_64-linux-musl.tar.gz/sha512/1c7feea46d70c60dbecfe6b945a29a086dc120e0d674ea9d488dc7943901711ba0505288694c94a2b0804bab6cd826b32e58912e407ed918724d16b6b6ec1d3d +LibUnwind.v1.3.2+4.x86_64-unknown-freebsd.tar.gz/md5/e72c36f0563a088282147275de90048b +LibUnwind.v1.3.2+4.x86_64-unknown-freebsd.tar.gz/sha512/3aaa7e5c21b3bcc30ff7826af4bc0b926865cac3a5b14dfa7f27f0c5d4344fa2a568a78c0c4ee32a18e668758cdac70c09f31f5ca55cc56c3d6a88654aa906fa diff --git a/deps/patches/libunwind-cfa-rsp.patch b/deps/patches/libunwind-cfa-rsp.patch new file mode 100644 index 0000000000000..7803f0b52924e --- /dev/null +++ b/deps/patches/libunwind-cfa-rsp.patch @@ -0,0 +1,393 @@ +commit c71298423c26b2143dc6f6ce554ec910ed882f8a +Author: Keno Fischer +Date: Sat Feb 6 18:13:16 2021 -0500 + + 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 + +diff --git a/include/dwarf.h b/include/dwarf.h +index fab93c61..b845e2eb 100644 +--- a/include/dwarf.h ++++ b/include/dwarf.h +@@ -227,6 +227,7 @@ typedef enum + DWARF_WHERE_REG, /* register saved in another register */ + DWARF_WHERE_EXPR, /* register saved */ + DWARF_WHERE_VAL_EXPR, /* register has computed value */ ++ DWARF_WHERE_CFA, /* register is set to the computed cfa value */ + } + dwarf_where_t; + +@@ -309,7 +310,7 @@ typedef struct dwarf_cursor + void *as_arg; /* argument to address-space callbacks */ + unw_addr_space_t as; /* reference to per-address-space info */ + +- unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */ ++ unw_word_t cfa; /* canonical frame address; aka frame-pointer */ + unw_word_t ip; /* instruction pointer */ + 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 +--- a/include/libunwind_i.h ++++ b/include/libunwind_i.h +@@ -351,6 +351,10 @@ static inline void invalidate_edi (struct elf_dyn_info *edi) + + #include "tdep/libunwind_i.h" + ++#ifndef TDEP_DWARF_SP ++#define TDEP_DWARF_SP UNW_TDEP_SP ++#endif ++ + #ifndef tdep_get_func_addr + # 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 +--- 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. */ + typedef struct dwarf_loc + { + unw_word_t val; +-#ifndef UNW_LOCAL_ONLY + unw_word_t type; /* see X86_LOC_TYPE_* macros. */ +-#endif + } + dwarf_loc_t; + +diff --git a/include/tdep-x86/libunwind_i.h b/include/tdep-x86/libunwind_i.h +index 5231189a..1b59fe34 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) + + #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) ++ ++# 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) ++# define DWARF_IS_VAL_LOC(l) (((l).type & DWARF_LOC_TYPE_VAL) != 0) ++ ++# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) + # define DWARF_NULL_LOC DWARF_LOC (0, 0) +-# define DWARF_IS_NULL_LOC(l) (DWARF_GET_LOC (l) == 0) +-# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r) }) +-# define DWARF_IS_REG_LOC(l) 0 ++# define DWARF_IS_NULL_LOC(l) \ ++ ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) ++# define DWARF_VAL_LOC(c,v) DWARF_LOC ((v), DWARF_LOC_TYPE_VAL) ++# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), DWARF_LOC_TYPE_MEM) ++ ++#ifdef UNW_LOCAL_ONLY + # define DWARF_REG_LOC(c,r) (DWARF_LOC((unw_word_t) \ + tdep_uc_addr(dwarf_get_uc(c), (r)), 0)) +-# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) + # 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) + return 0; + } + +-static inline int +-dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) +-{ +- if (!DWARF_GET_LOC (loc)) +- return -1; +- return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, +- 0, c->as_arg); +-} +- +-static inline int +-dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) +-{ +- if (!DWARF_GET_LOC (loc)) +- return -1; +- return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), &val, +- 1, c->as_arg); +-} +- + #else /* !UNW_LOCAL_ONLY */ +-# define DWARF_LOC_TYPE_FP (1 << 0) +-# define DWARF_LOC_TYPE_REG (1 << 1) +-# define DWARF_NULL_LOC DWARF_LOC (0, 0) +-# define DWARF_IS_NULL_LOC(l) \ +- ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) +-# define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) +-# 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_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) +-# define DWARF_MEM_LOC(c,m) DWARF_LOC ((m), 0) + # 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) + 1, c->as_arg); + } + ++#endif /* !UNW_LOCAL_ONLY */ ++ + static inline int + dwarf_get (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t *val) + { + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + +- /* If a code-generator were to save a value of type unw_word_t in a +- floating-point register, we would have to support this case. I +- suppose it could happen with MMX registers, but does it really +- happen? */ +- assert (!DWARF_IS_FP_LOC (loc)); +- + if (DWARF_IS_REG_LOC (loc)) + return (*c->as->acc.access_reg) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); +- else ++ if (DWARF_IS_MEM_LOC (loc)) + return (*c->as->acc.access_mem) (c->as, DWARF_GET_LOC (loc), val, + 0, c->as_arg); ++ assert(DWARF_IS_VAL_LOC (loc)); ++ *val = DWARF_GET_LOC (loc); ++ return 0; + } + + static inline int + dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) + { ++ assert(!DWARF_IS_VAL_LOC (loc)); ++ + if (DWARF_IS_NULL_LOC (loc)) + return -UNW_EBADREG; + +- /* If a code-generator were to save a value of type unw_word_t in a +- floating-point register, we would have to support this case. I +- suppose it could happen with MMX registers, but does it really +- happen? */ +- assert (!DWARF_IS_FP_LOC (loc)); +- + 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) + 1, c->as_arg); + } + +-#endif /* !UNW_LOCAL_ONLY */ ++// For historical reasons, the DWARF numbering does not match the libunwind ++// numbering, necessitating this override ++#define TDEP_DWARF_SP 4 + + #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 +--- 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) + for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) + set_reg (sr, i, DWARF_WHERE_SAME, 0); + ++ // SP defaults to CFA (but is overridable) ++ set_reg (sr, TDEP_DWARF_SP, DWARF_WHERE_CFA, 0); ++ + 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) + /* 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. */ +- if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == UNW_TDEP_SP) +- && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg.val)) +- && (rs->reg.where[UNW_TDEP_SP] == DWARF_WHERE_SAME)) ++ if ((rs->reg.val[DWARF_CFA_REG_COLUMN] == TDEP_DWARF_SP) ++ && (TDEP_DWARF_SP < ARRAY_SIZE(rs->reg.val)) ++ && (DWARF_IS_NULL_LOC(c->loc[TDEP_DWARF_SP]))) + cfa = c->cfa; + else + { + regnum = dwarf_to_unw_regnum (rs->reg.val[DWARF_CFA_REG_COLUMN]); +- if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0) ++ if ((ret = unw_get_reg (dwarf_to_cursor(c), regnum, &cfa)) < 0) + 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) + case DWARF_WHERE_SAME: + break; + ++ case DWARF_WHERE_CFA: ++ new_loc[i] = DWARF_VAL_LOC (c, cfa); ++ break; ++ + case DWARF_WHERE_CFAREL: + 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 +--- a/src/x86/Gos-freebsd.c ++++ b/src/x86/Gos-freebsd.c +@@ -138,6 +138,7 @@ x86_handle_signal_frame (unw_cursor_t *cursor) + c->dwarf.loc[ST0] = DWARF_NULL_LOC; + } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) { + c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0); ++ c->dwarf.loc[ESP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 4); + c->dwarf.loc[EAX] = DWARF_NULL_LOC; + 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 +--- 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, + break; + + case UNW_X86_CFA: +- case UNW_X86_ESP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; +@@ -81,6 +80,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; + case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; + ++ case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break; + case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; + 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 +--- a/src/x86/Gstep.c ++++ b/src/x86/Gstep.c +@@ -47,7 +47,7 @@ unw_step (unw_cursor_t *cursor) + { + /* DWARF failed, let's see if we can follow the frame-chain + or skip over the signal trampoline. */ +- struct dwarf_loc ebp_loc, eip_loc; ++ struct dwarf_loc ebp_loc, eip_loc, esp_loc; + + /* We could get here because of missing/bad unwind information. + Validate all addresses before dereferencing. */ +@@ -77,6 +77,7 @@ unw_step (unw_cursor_t *cursor) + c->dwarf.cfa); + + ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); ++ esp_loc = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); + eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); + c->dwarf.cfa += 8; + +@@ -87,6 +88,7 @@ unw_step (unw_cursor_t *cursor) + c->dwarf.loc[i] = DWARF_NULL_LOC; + + c->dwarf.loc[EBP] = ebp_loc; ++ c->dwarf.loc[ESP] = esp_loc; + 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 +--- 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) + c->dwarf.loc[RCX] = c->dwarf.loc[R10]; + /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ + /* rbp_loc = c->dwarf.loc[RBP]; */ ++ c->dwarf.loc[RSP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + 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 +--- 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, + break; + + case UNW_X86_64_CFA: +- case UNW_X86_64_RSP: + if (write) + return -UNW_EREADONLYREG; + *valp = c->dwarf.cfa; +@@ -107,6 +106,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, + case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break; + case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; + ++ case UNW_X86_64_RSP: loc = c->dwarf.loc[RSP]; break; + case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; + 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 +--- 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", diff --git a/deps/patches/libunwind-rsp-cfa.patch b/deps/patches/libunwind-rsp-cfa.patch deleted file mode 100644 index 05986b0e7010a..0000000000000 --- a/deps/patches/libunwind-rsp-cfa.patch +++ /dev/null @@ -1,177 +0,0 @@ -commit 66f68ab50d35bb17a7ae3ac47f17e1ba5913760c -Author: Keno Fischer -Date: Sat Feb 6 18:13:16 2021 -0500 - - 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 - -diff --git a/include/dwarf.h b/include/dwarf.h -index fab93c61..b845e2eb 100644 ---- a/include/dwarf.h -+++ b/include/dwarf.h -@@ -227,6 +227,7 @@ typedef enum - DWARF_WHERE_REG, /* register saved in another register */ - DWARF_WHERE_EXPR, /* register saved */ - DWARF_WHERE_VAL_EXPR, /* register has computed value */ -+ DWARF_WHERE_CFA, /* register is set to the computed cfa value */ - } - dwarf_where_t; - -@@ -309,7 +310,7 @@ typedef struct dwarf_cursor - void *as_arg; /* argument to address-space callbacks */ - unw_addr_space_t as; /* reference to per-address-space info */ - -- unw_word_t cfa; /* canonical frame address; aka frame-/stack-pointer */ -+ unw_word_t cfa; /* canonical frame address; aka frame-pointer */ - unw_word_t ip; /* instruction pointer */ - unw_word_t args_size; /* size of arguments */ - unw_word_t eh_args[UNW_TDEP_NUM_EH_REGS]; -diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c -index 7d255aee..986c4a89 100644 ---- a/src/dwarf/Gparser.c -+++ b/src/dwarf/Gparser.c -@@ -500,6 +500,8 @@ setup_fde (struct dwarf_cursor *c, dwarf_state_record_t *sr) - memset (sr, 0, sizeof (*sr)); - for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) - set_reg (sr, i, DWARF_WHERE_SAME, 0); -+ // SP defaults to CFA (but is overridable) -+ set_reg (sr, UNW_TDEP_SP, DWARF_WHERE_CFA, 0); - - struct dwarf_cie_info *dci = c->pi.unwind_info; - sr->rs_current.ret_addr_column = dci->ret_addr_column; -@@ -826,6 +828,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) - case DWARF_WHERE_SAME: - break; - -+ case DWARF_WHERE_CFA: -+ new_loc[i] = DWARF_VAL_LOC (c, cfa); -+ break; -+ - case DWARF_WHERE_CFAREL: - 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 ---- a/src/x86/Gos-freebsd.c -+++ b/src/x86/Gos-freebsd.c -@@ -138,6 +138,7 @@ x86_handle_signal_frame (unw_cursor_t *cursor) - c->dwarf.loc[ST0] = DWARF_NULL_LOC; - } else if (c->sigcontext_format == X86_SCF_FREEBSD_SYSCALL) { - c->dwarf.loc[EIP] = DWARF_LOC (c->dwarf.cfa, 0); -+ c->dwarf.loc[ESP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 4); - c->dwarf.loc[EAX] = DWARF_NULL_LOC; - 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 ---- 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, - break; - - case UNW_X86_CFA: -- case UNW_X86_ESP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; -@@ -81,6 +80,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - case UNW_X86_ECX: loc = c->dwarf.loc[ECX]; break; - case UNW_X86_EBX: loc = c->dwarf.loc[EBX]; break; - -+ case UNW_X86_ESP: loc = c->dwarf.loc[ESP]; break; - case UNW_X86_EBP: loc = c->dwarf.loc[EBP]; break; - 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 ---- a/src/x86/Gstep.c -+++ b/src/x86/Gstep.c -@@ -47,7 +47,7 @@ unw_step (unw_cursor_t *cursor) - { - /* DWARF failed, let's see if we can follow the frame-chain - or skip over the signal trampoline. */ -- struct dwarf_loc ebp_loc, eip_loc; -+ struct dwarf_loc ebp_loc, eip_loc, esp_loc; - - /* We could get here because of missing/bad unwind information. - Validate all addresses before dereferencing. */ -@@ -77,6 +77,7 @@ unw_step (unw_cursor_t *cursor) - c->dwarf.cfa); - - ebp_loc = DWARF_LOC (c->dwarf.cfa, 0); -+ esp_loc = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); - eip_loc = DWARF_LOC (c->dwarf.cfa + 4, 0); - c->dwarf.cfa += 8; - -@@ -87,6 +88,7 @@ unw_step (unw_cursor_t *cursor) - c->dwarf.loc[i] = DWARF_NULL_LOC; - - c->dwarf.loc[EBP] = ebp_loc; -+ c->dwarf.loc[ESP] = esp_loc; - c->dwarf.loc[EIP] = eip_loc; - c->dwarf.use_prev_instr = 1; - } -diff --git a/src/x86_64/Gos-freebsd.c b/src/x86_64/Gos-freebsd.c -index 883025c8..8bb101ea 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) - c->dwarf.loc[RCX] = c->dwarf.loc[R10]; - /* rsp_loc = DWARF_LOC(c->dwarf.cfa - 8, 0); */ - /* rbp_loc = c->dwarf.loc[RBP]; */ -+ c->dwarf.loc[RSP] = DWARF_VAL_LOC (c, c->dwarf.cfa + 8); - c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); - 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 ---- 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, - break; - - case UNW_X86_64_CFA: -- case UNW_X86_64_RSP: - if (write) - return -UNW_EREADONLYREG; - *valp = c->dwarf.cfa; -@@ -107,6 +106,7 @@ tdep_access_reg (struct cursor *c, unw_regnum_t reg, unw_word_t *valp, - case UNW_X86_64_RCX: loc = c->dwarf.loc[RCX]; break; - case UNW_X86_64_RBX: loc = c->dwarf.loc[RBX]; break; - -+ case UNW_X86_64_RSP: loc = c->dwarf.loc[RSP]; break; - case UNW_X86_64_RBP: loc = c->dwarf.loc[RBP]; break; - 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 ---- 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", diff --git a/deps/unwind.mk b/deps/unwind.mk index 0c9f1e9aa0643..d89045242a11b 100644 --- a/deps/unwind.mk +++ b/deps/unwind.mk @@ -24,11 +24,11 @@ $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-static-arm.patch-applied: $(SRCCAC cd $(SRCCACHE)/libunwind-$(UNWIND_VER) && patch -p1 -f < $(SRCDIR)/patches/libunwind-static-arm.patch echo 1 > $@ -$(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-rsp-cfa.patch-applied: $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-static-arm.patch-applied - cd $(SRCCACHE)/libunwind-$(UNWIND_VER) && patch -p1 -f -u < $(SRCDIR)/patches/libunwind-rsp-cfa.patch +$(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-cfa-rsp.patch-applied: $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-static-arm.patch-applied + cd $(SRCCACHE)/libunwind-$(UNWIND_VER) && patch -p1 -f -u < $(SRCDIR)/patches/libunwind-cfa-rsp.patch echo 1 > $@ -$(BUILDDIR)/libunwind-$(UNWIND_VER)/build-configured: $(SRCCACHE)/libunwind-$(UNWIND_VER)/source-extracted $(SRCCACHE)/libunwind-$(UNWIND_VER)/libunwind-rsp-cfa.patch-applied +$(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