diff --git a/Also-define-NLGA-when-we-build-with-atomic-ops-80.patch b/Also-define-NLGA-when-we-build-with-atomic-ops-80.patch deleted file mode 100644 index fbd47f672c0661be6bba07b9ca2856512e2c35df..0000000000000000000000000000000000000000 --- a/Also-define-NLGA-when-we-build-with-atomic-ops-80.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 038556f57e3433cbaaa7b087c9798143709caa9c Mon Sep 17 00:00:00 2001 -From: Milian Wolff -Date: Thu, 31 May 2018 16:11:30 +0200 -Subject: [PATCH 24/50] Also define NLGA when we build with atomic ops (#80) - -This uncovered the use of NLGA to guard the initializaition -of the valid mem cache. This code is removed, as it isn't -working properly for a per-thread cache anyways. What's more, -it shouldn't be required anyways since static data is guaranteed -to be initialized to zero anyways. - -Fixes https://github.com/libunwind/libunwind/issues/79 ---- - src/x86_64/Ginit.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c -index 669e9ed..6161da6 100644 ---- a/src/x86_64/Ginit.c -+++ b/src/x86_64/Ginit.c -@@ -174,8 +174,8 @@ tdep_init_mem_validate (void) - } - - /* Cache of already validated addresses */ --#if defined(HAVE___THREAD) && HAVE___THREAD - #define NLGA 4 -+#if defined(HAVE___THREAD) && HAVE___THREAD - // thread-local variant - static __thread unw_word_t last_good_addr[NLGA]; - static __thread int lga_victim; -@@ -394,11 +394,6 @@ x86_64_local_addr_space_init (void) - local_addr_space.acc.resume = x86_64_local_resume; - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); -- --#if NLGA > 0 -- memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); -- lga_victim = 0; --#endif - } - - #endif /* !UNW_REMOTE_ONLY */ --- -1.8.3.1 - diff --git a/Cleanup-remove-unused-variable.patch b/Cleanup-remove-unused-variable.patch deleted file mode 100644 index fb7e6ecc659277680444c06963baa1b7af0e82ef..0000000000000000000000000000000000000000 --- a/Cleanup-remove-unused-variable.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 3f689c9ee1562c44506f563c381036be88fb82de Mon Sep 17 00:00:00 2001 -From: Milian Wolff -Date: Tue, 24 Apr 2018 15:41:09 +0200 -Subject: [PATCH 21/50] Cleanup: remove unused variable - ---- - src/x86_64/Ginit.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c -index 28e096f..76e183e 100644 ---- a/src/x86_64/Ginit.c -+++ b/src/x86_64/Ginit.c -@@ -132,7 +132,6 @@ static int msync_validate (void *addr, size_t len) - static int mincore_validate (void *addr, size_t len) - { - unsigned char mvec[2]; /* Unaligned access may cross page boundary */ -- size_t i; - - /* mincore could fail with EAGAIN but we conservatively return -1 - instead of looping. */ --- -1.8.3.1 - diff --git a/Don-t-check-if-the-memory-is-in-core-64.patch b/Don-t-check-if-the-memory-is-in-core-64.patch deleted file mode 100644 index fb9f2d20deed27274b13688a52e6bc3133a47ca6..0000000000000000000000000000000000000000 --- a/Don-t-check-if-the-memory-is-in-core-64.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 05d814b64036b1ea2f0f328b3a985b03559dcf10 Mon Sep 17 00:00:00 2001 -From: ShutterQuick -Date: Fri, 9 Feb 2018 16:41:54 +0100 -Subject: [PATCH 10/50] Don't check if the memory is in core (#64) - -libunwind uses mincore() to validate that memory is mapped and available to the process. -For this purpose, checking the return value of mincore() is sufficient. -The result array tells us if the kernel has swapped out the page or not. -We don't care about this, and the check leads to failure in those -cases where the kernel has swapped out the page. ---- - src/x86_64/Ginit.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c -index 2a84a1e..b7e8e46 100644 ---- a/src/x86_64/Ginit.c -+++ b/src/x86_64/Ginit.c -@@ -140,11 +140,6 @@ static int mincore_validate (void *addr, size_t len) - return -1; - } - -- for (i = 0; i < (len + PAGE_SIZE - 1) / PAGE_SIZE; i++) -- { -- if (!(mvec[i] & 1)) return -1; -- } -- - return write_validate (addr); - } - #endif -@@ -165,7 +160,7 @@ tdep_init_mem_validate (void) - int ret; - while ((ret = mincore ((void*)addr, PAGE_SIZE, mvec)) == -1 && - errno == EAGAIN) {} -- if (ret == 0 && (mvec[0] & 1)) -+ if (ret == 0) - { - Debug(1, "using mincore to validate memory\n"); - mem_validate_func = mincore_validate; --- -1.8.3.1 - diff --git a/Fix-race-conditions-in-validate_mem-via-atomics.patch b/Fix-race-conditions-in-validate_mem-via-atomics.patch deleted file mode 100644 index e8457e65b1e19da44b752be7fc4a3d69202a1fff..0000000000000000000000000000000000000000 --- a/Fix-race-conditions-in-validate_mem-via-atomics.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 3d473e183da99d9965112e45ab43f4d06c01ccab Mon Sep 17 00:00:00 2001 -From: Milian Wolff -Date: Tue, 24 Apr 2018 15:41:21 +0200 -Subject: [PATCH 22/50] Fix race conditions in validate_mem via atomics - -When atomics are not available, the address cache is disabled. - -Fixes data race found by TSAN: - -WARNING: ThreadSanitizer: data race (pid=17824) - Read of size 8 at 0x7f4dac484140 by thread T3: - #0 validate_mem ../../src/x86_64/Ginit.c:201 (libunwind.so. -8+0x00000001f836) - #1 access_mem ../../src/x86_64/Ginit.c:242 (libunwind.so.8+0x00000001fe06) - #2 dwarf_get ../../include/tdep-x86_64/libunwind_i.h:168 (libunwind.so. -8+0x0000000221cf) - #3 _ULx86_64_access_reg ../../src/x86_64/Gregs.c:130 (libunwind.so. -8+0x000000022e99) - #4 _ULx86_64_get_reg ../../src/mi/Gget_reg.c:40 (libunwind.so. -8+0x00000001e5bc) - #5 apply_reg_state ../../src/dwarf/Gparser.c:796 (libunwind.so. -8+0x000000038209) - #6 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:961 (libunwind.so. -8+0x000000039dbc) - #7 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. -8+0x00000002481f) - #8 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. -8+0x000000026f0e) - #9 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. -8+0x000000027429) - #10 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. -8+0x00000002789a) - #11 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. -8+0x00000001cb07) - - Previous write of size 8 at 0x7f4dac484140 by thread T2: - #0 validate_mem ../../src/x86_64/Ginit.c:220 (libunwind.so. -8+0x00000001fc54) - #1 access_mem ../../src/x86_64/Ginit.c:242 (libunwind.so.8+0x00000001fe06) - #2 dwarf_get ../../include/tdep-x86_64/libunwind_i.h:168 (libunwind.so. -8+0x0000000221cf) - #3 _ULx86_64_access_reg ../../src/x86_64/Gregs.c:130 (libunwind.so. -8+0x000000022e99) - #4 _ULx86_64_get_reg ../../src/mi/Gget_reg.c:40 (libunwind.so. -8+0x00000001e5bc) - #5 apply_reg_state ../../src/dwarf/Gparser.c:796 (libunwind.so. -8+0x000000038209) - #6 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:961 (libunwind.so. -8+0x000000039dbc) - #7 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. -8+0x00000002481f) - #8 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. -8+0x000000026f0e) - #9 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. -8+0x000000027429) - #10 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. -8+0x00000002789a) - #11 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. -8+0x00000001cb07) - - Location is global 'last_good_addr' of size 32 at 0x7f4dac484140 -(libunwind.so.8+0x000000273140) ---- - src/x86_64/Ginit.c | 71 ++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 50 insertions(+), 21 deletions(-) - -diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c -index 76e183e..21d8c49 100644 ---- a/src/x86_64/Ginit.c -+++ b/src/x86_64/Ginit.c -@@ -174,14 +174,56 @@ tdep_init_mem_validate (void) - } - - /* Cache of already validated addresses */ -+#if HAVE_ATOMIC_OPS_H - #define NLGA 4 --static unw_word_t last_good_addr[NLGA]; --static int lga_victim; -+static AO_T last_good_addr[NLGA]; -+static AO_T lga_victim; - - static int --validate_mem (unw_word_t addr) -+is_cached_valid_mem(unw_word_t addr) -+{ -+ int i; -+ for (i = 0; i < NLGA; i++) -+ { -+ if (addr == AO_load(&last_good_addr[i])) -+ return 1; -+ } -+ return 0; -+} -+ -+static void -+cache_valid_mem(unw_word_t addr) - { - int i, victim; -+ victim = AO_load(&lga_victim); -+ for (i = 0; i < NLGA; i++) { -+ if (AO_compare_and_swap(&last_good_addr[victim], 0, addr)) { -+ return; -+ } -+ victim = (victim + 1) % NLGA; -+ } -+ -+ /* All slots full. Evict the victim. */ -+ AO_store(&last_good_addr[victim], addr); -+ victim = (victim + 1) % NLGA; -+ AO_store(&lga_victim, victim); -+} -+#else -+static int -+is_cached_valid_mem(unw_word_t addr UNUSED) -+{ -+ return 0; -+} -+ -+static void -+cache_valid_mem(unw_word_t addr UNUSED) -+{ -+} -+#endif -+ -+static int -+validate_mem (unw_word_t addr) -+{ - size_t len; - - if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) -@@ -194,28 +236,13 @@ validate_mem (unw_word_t addr) - if (addr == 0) - return -1; - -- for (i = 0; i < NLGA; i++) -- { -- if (last_good_addr[i] && (addr == last_good_addr[i])) -- return 0; -- } -+ if (is_cached_valid_mem(addr)) -+ return 0; - - if (mem_validate_func ((void *) addr, len) == -1) - return -1; - -- victim = lga_victim; -- for (i = 0; i < NLGA; i++) { -- if (!last_good_addr[victim]) { -- last_good_addr[victim++] = addr; -- return 0; -- } -- victim = (victim + 1) % NLGA; -- } -- -- /* All slots full. Evict the victim. */ -- last_good_addr[victim] = addr; -- victim = (victim + 1) % NLGA; -- lga_victim = victim; -+ cache_valid_mem(addr); - - return 0; - } -@@ -330,8 +357,10 @@ x86_64_local_addr_space_init (void) - local_addr_space.acc.get_proc_name = get_static_proc_name; - unw_flush_cache (&local_addr_space, 0, 0); - -+#if NLGA > 0 - memset (last_good_addr, 0, sizeof (unw_word_t) * NLGA); - lga_victim = 0; -+#endif - } - - #endif /* !UNW_REMOTE_ONLY */ --- -1.8.3.1 - diff --git a/Optionally-use-a-thread-local-cache-for-valid-memory.patch b/Optionally-use-a-thread-local-cache-for-valid-memory.patch deleted file mode 100644 index 14ef5f5bce7b58aca6ad2b3a8dc0a8dbaedaa71a..0000000000000000000000000000000000000000 --- a/Optionally-use-a-thread-local-cache-for-valid-memory.patch +++ /dev/null @@ -1,73 +0,0 @@ -From cd8c5d70d4358aee3dc9fee53e9870d0501cc6db Mon Sep 17 00:00:00 2001 -From: Milian Wolff -Date: Fri, 4 May 2018 21:55:52 +0200 -Subject: [PATCH 23/50] Optionally use a thread-local cache for valid memory - -When libunwind is compiled with per-thread-caches, then also -make the cache of valid memory addresses thread-local. ---- - src/x86_64/Ginit.c | 40 +++++++++++++++++++++++++++++++++++++++- - 1 file changed, 39 insertions(+), 1 deletion(-) - -diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c -index 21d8c49..669e9ed 100644 ---- a/src/x86_64/Ginit.c -+++ b/src/x86_64/Ginit.c -@@ -174,8 +174,45 @@ tdep_init_mem_validate (void) - } - - /* Cache of already validated addresses */ --#if HAVE_ATOMIC_OPS_H -+#if defined(HAVE___THREAD) && HAVE___THREAD - #define NLGA 4 -+// thread-local variant -+static __thread unw_word_t last_good_addr[NLGA]; -+static __thread int lga_victim; -+ -+static int -+is_cached_valid_mem(unw_word_t addr) -+{ -+ int i; -+ for (i = 0; i < NLGA; i++) -+ { -+ if (addr == &last_good_addr[i]) -+ return 1; -+ } -+ return 0; -+} -+ -+static void -+cache_valid_mem(unw_word_t addr) -+{ -+ int i, victim; -+ victim = lga_victim; -+ for (i = 0; i < NLGA; i++) { -+ if (last_good_addr[victim] == 0) { -+ last_good_addr[victim] = addr; -+ return; -+ } -+ victim = (victim + 1) % NLGA; -+ } -+ -+ /* All slots full. Evict the victim. */ -+ last_good_addr[victim] = addr; -+ victim = (victim + 1) % NLGA; -+ lga_victim = victim; -+} -+ -+#elif HAVE_ATOMIC_OPS_H -+// global, thread safe variant - static AO_T last_good_addr[NLGA]; - static AO_T lga_victim; - -@@ -209,6 +246,7 @@ cache_valid_mem(unw_word_t addr) - AO_store(&lga_victim, victim); - } - #else -+// disabled, no cache - static int - is_cached_valid_mem(unw_word_t addr UNUSED) - { --- -1.8.3.1 - diff --git a/aarch-v2-aarch64-PLT-entry-recognition-fixes-86.patch b/aarch-v2-aarch64-PLT-entry-recognition-fixes-86.patch deleted file mode 100644 index 2d7dd27cbb71c334f4abf2d47c0f0568582915b8..0000000000000000000000000000000000000000 --- a/aarch-v2-aarch64-PLT-entry-recognition-fixes-86.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 58d3457ff2225d5851cb0195dbbd1170eb7dbbab Mon Sep 17 00:00:00 2001 -From: Dave Watson -Date: Fri, 28 Sep 2018 09:19:59 -0700 -Subject: [PATCH 30/50] aarch: [v2] aarch64 PLT entry recognition & fixes (#86) - -Fix missing Gparser.c changes from patchset - -'aarch64 PLT entry recognition & fixes' ---- - src/dwarf/Gparser.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c -index 3f79ed4..1ce862c 100644 ---- a/src/dwarf/Gparser.c -+++ b/src/dwarf/Gparser.c -@@ -831,7 +831,7 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) - break; - - case DWARF_WHERE_REG: -- new_loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg.val[i])); -+ new_loc[i] = new_loc[rs->reg.val[i]]; - break; - - case DWARF_WHERE_EXPR: --- -1.8.3.1 - diff --git a/dwarf-Add-missing-opcodes-to-the-operands-table-in-G.patch b/dwarf-Add-missing-opcodes-to-the-operands-table-in-G.patch deleted file mode 100644 index 91bb483b3d779d7142f9a284c2c0e795d7cc1ed6..0000000000000000000000000000000000000000 --- a/dwarf-Add-missing-opcodes-to-the-operands-table-in-G.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f551e16213c52169af8bda554e4051b756a169cc Mon Sep 17 00:00:00 2001 -From: Stephen Roberts <43952910+stephen-roberts-work@users.noreply.github.com> -Date: Fri, 12 Oct 2018 17:50:24 +0100 -Subject: [PATCH 33/50] dwarf: Add missing opcodes to the operands table in - Gexpr.c - -This patch adds two opcodes to the operands table in Gexpr.c, which is a mapping between opcodes and the number and types of the operands for those opcodes. Two opcodes, DW_OP_constu and DW_OP_consts are missing from this table, which caused failures later in the CFI expression parsing logic. This patch adds the missing information into the table, and thus allows correct parsing of CFA_def_cfa_expression, CFA_expression and CFA_val_expression expressions which contain the offending opcodes. ---- - src/dwarf/Gexpr.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/dwarf/Gexpr.c b/src/dwarf/Gexpr.c -index f63c3d2..709c0c8 100644 ---- a/src/dwarf/Gexpr.c -+++ b/src/dwarf/Gexpr.c -@@ -60,6 +60,8 @@ static const uint8_t operands[256] = - [DW_OP_const4s] = OPND1 (VAL32), - [DW_OP_const8u] = OPND1 (VAL64), - [DW_OP_const8s] = OPND1 (VAL64), -+ [DW_OP_constu] = OPND1 (ULEB128), -+ [DW_OP_consts] = OPND1 (SLEB128), - [DW_OP_pick] = OPND1 (VAL8), - [DW_OP_plus_uconst] = OPND1 (ULEB128), - [DW_OP_skip] = OPND1 (VAL16), --- -1.8.3.1 - diff --git a/dwarf-Push-correct-CFA-onto-stack-for-dwarf-expressi.patch b/dwarf-Push-correct-CFA-onto-stack-for-dwarf-expressi.patch deleted file mode 100644 index 519f05cf538472ab5ed9ae61c4b18e9e75b5cab3..0000000000000000000000000000000000000000 --- a/dwarf-Push-correct-CFA-onto-stack-for-dwarf-expressi.patch +++ /dev/null @@ -1,335 +0,0 @@ -From 748a2df11f0d10bd39fd5291d2b27b61392732da Mon Sep 17 00:00:00 2001 -From: Stephen Roberts <43952910+stephen-roberts-work@users.noreply.github.com> -Date: Tue, 13 Nov 2018 16:57:42 +0000 -Subject: [PATCH 34/50] dwarf: Push correct CFA onto stack for dwarf expression - evaluation. (#93) - -dwarf: Push correct CFA onto stack for dwarf expression evaluation. - -This change fixes a bug where stale CFAs were pushed onto the dwarf -expression stack before expression evaluation. Some optimising compilers -emit CFI which relies on this being correct. ---- - include/dwarf.h | 2 +- - src/dwarf/Gexpr.c | 14 ++++--- - src/dwarf/Gparser.c | 17 +++++--- - tests/Gx64-test-dwarf-expressions.c | 68 ++++++++++++++++++++++++++++++++ - tests/Lx64-test-dwarf-expressions.c | 5 +++ - tests/Makefile.am | 17 +++++++- - tests/x64-test-dwarf-expressions.S | 78 +++++++++++++++++++++++++++++++++++++ - 7 files changed, 189 insertions(+), 12 deletions(-) - create mode 100644 tests/Gx64-test-dwarf-expressions.c - create mode 100644 tests/Lx64-test-dwarf-expressions.c - create mode 100644 tests/x64-test-dwarf-expressions.S - -diff --git a/include/dwarf.h b/include/dwarf.h -index fab93c6..764f6f2 100644 ---- a/include/dwarf.h -+++ b/include/dwarf.h -@@ -419,7 +419,7 @@ extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t a - unw_word_t ip); - extern void dwarf_put_unwind_info (unw_addr_space_t as, - unw_proc_info_t *pi, void *arg); --extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, -+extern int dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, - unw_word_t len, unw_word_t *valp, - int *is_register); - extern int -diff --git a/src/dwarf/Gexpr.c b/src/dwarf/Gexpr.c -index 709c0c8..2af4543 100644 ---- a/src/dwarf/Gexpr.c -+++ b/src/dwarf/Gexpr.c -@@ -237,8 +237,8 @@ dwarf_stack_aligned(struct dwarf_cursor *c, unw_word_t cfa_addr, - } - - HIDDEN int --dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t *addr, unw_word_t len, -- unw_word_t *valp, int *is_register) -+dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, -+ unw_word_t len, unw_word_t *valp, int *is_register) - { - unw_word_t operand1 = 0, operand2 = 0, tmp1, tmp2 = 0, tmp3, end_addr; - uint8_t opcode, operands_signature, u8; -@@ -287,10 +287,14 @@ do { \ - end_addr = *addr + len; - *is_register = 0; - -- Debug (14, "len=%lu, pushing cfa=0x%lx\n", -- (unsigned long) len, (unsigned long) c->cfa); -+ Debug (14, "len=%lu, pushing initial value=0x%lx\n", -+ (unsigned long) len, (unsigned long) stack_val); - -- push (c->cfa); /* push current CFA as required by DWARF spec */ -+ /* The DWARF standard requires the current CFA to be pushed onto the stack */ -+ /* before evaluating DW_CFA_expression and DW_CFA_val_expression programs. */ -+ /* DW_CFA_def_cfa_expressions do not take an initial value, but we push on */ -+ /* a dummy value to keep this logic consistent. */ -+ push (stack_val); - - while (*addr < end_addr) - { -diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c -index 1ce862c..fe7c581 100644 ---- a/src/dwarf/Gparser.c -+++ b/src/dwarf/Gparser.c -@@ -734,7 +734,7 @@ create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, - } - - static inline int --eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, -+eval_location_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_addr_space_t as, - unw_accessors_t *a, unw_word_t addr, - dwarf_loc_t *locp, void *arg) - { -@@ -746,7 +746,7 @@ eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, - return ret; - - /* evaluate the expression: */ -- if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0) -+ if ((ret = dwarf_eval_expr (c, stack_val, &addr, len, &val, &is_register)) < 0) - return ret; - - if (is_register) -@@ -804,7 +804,10 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) - assert (rs->reg.where[DWARF_CFA_REG_COLUMN] == DWARF_WHERE_EXPR); - - addr = rs->reg.val[DWARF_CFA_REG_COLUMN]; -- if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) -+ /* The dwarf standard doesn't specify an initial value to be pushed on */ -+ /* the stack before DW_CFA_def_cfa_expression evaluation. We push on a */ -+ /* dummy value (0) to keep the eval_location_expr function consistent. */ -+ if ((ret = eval_location_expr (c, 0, as, a, addr, &cfa_loc, arg)) < 0) - return ret; - /* the returned location better be a memory location... */ - if (DWARF_IS_REG_LOC (cfa_loc)) -@@ -844,13 +847,17 @@ apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) - - case DWARF_WHERE_EXPR: - addr = rs->reg.val[i]; -- if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) -+ /* The dwarf standard requires the current CFA to be pushed on the */ -+ /* stack before DW_CFA_expression evaluation. */ -+ if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) - return ret; - break; - - case DWARF_WHERE_VAL_EXPR: - addr = rs->reg.val[i]; -- if ((ret = eval_location_expr (c, as, a, addr, new_loc + i, arg)) < 0) -+ /* The dwarf standard requires the current CFA to be pushed on the */ -+ /* stack before DW_CFA_val_expression evaluation. */ -+ if ((ret = eval_location_expr (c, cfa, as, a, addr, new_loc + i, arg)) < 0) - return ret; - new_loc[i] = DWARF_VAL_LOC (c, DWARF_GET_LOC (new_loc[i])); - break; -diff --git a/tests/Gx64-test-dwarf-expressions.c b/tests/Gx64-test-dwarf-expressions.c -new file mode 100644 -index 0000000..209f871 ---- /dev/null -+++ b/tests/Gx64-test-dwarf-expressions.c -@@ -0,0 +1,68 @@ -+#include -+#include -+#include -+ -+#include -+ -+static int verbose; -+static int nerrors; -+ -+#define panic(args...) \ -+ do { printf (args); ++nerrors; } while (0) -+ -+// Assembly routine which sets up the stack for the test then calls another one -+// which clobbers the stack, and which in turn calls recover_register below -+extern int64_t DW_CFA_expression_testcase(int64_t regnum, int64_t height); -+ -+// recover_register is called by the assembly routines. It returns the value of -+// a register at a specified height from the inner-most frame. The return value -+// is propagated back through the assembly routines to the testcase. -+extern int64_t recover_register(int64_t regnum, int64_t height) -+{ -+ // Initialize cursor to current frame -+ int rc, i; -+ unw_cursor_t cursor; -+ unw_context_t context; -+ unw_getcontext(&context); -+ unw_init_local(&cursor, &context); -+ // Unwind frames until required height from inner-most frame (i.e. this one) -+ for (i = 0; i < height; ++i) -+ { -+ rc = unw_step(&cursor); -+ if (rc < 0) -+ panic("%s: unw_step failed on step %d with return code %d", __FUNCTION__, i, rc); -+ else if (rc == 0) -+ panic("%s: unw_step failed to reach the end of the stack", __FUNCTION__); -+ unw_word_t pc; -+ rc = unw_get_reg(&cursor, UNW_REG_IP, &pc); -+ if (rc < 0 || pc == 0) -+ panic("%s: unw_get_reg failed to locate the program counter", __FUNCTION__); -+ } -+ // We're now at the required height, extract register -+ uint64_t value; -+ if ((rc = unw_get_reg(&cursor, (unw_regnum_t) regnum, &value)) != 0) -+ panic("%s: unw_get_reg failed to retrieve register %lu", __FUNCTION__, regnum); -+ return value; -+} -+ -+int -+main (int argc, char **argv) -+{ -+ if (argc > 1) -+ verbose = 1; -+ -+ if (DW_CFA_expression_testcase(12, 1) != 0) -+ panic("r12 should be clobbered at height 1 (DW_CFA_expression_inner)"); -+ if (DW_CFA_expression_testcase(12, 2) != 111222333) -+ panic("r12 should be restored at height 2 (DW_CFA_expression_testcase)"); -+ -+ if (nerrors > 0) -+ { -+ fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); -+ exit (-1); -+ } -+ -+ if (verbose) -+ printf ("SUCCESS.\n"); -+ return 0; -+} -diff --git a/tests/Lx64-test-dwarf-expressions.c b/tests/Lx64-test-dwarf-expressions.c -new file mode 100644 -index 0000000..07e916e ---- /dev/null -+++ b/tests/Lx64-test-dwarf-expressions.c -@@ -0,0 +1,5 @@ -+#define UNW_LOCAL_ONLY -+#include -+#if !defined(UNW_REMOTE_ONLY) -+#include "Gx64-test-dwarf-expressions.c" -+#endif -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 4b0b9db..fee8a70 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -37,7 +37,11 @@ if ARCH_PPC64 - if USE_ALTIVEC - noinst_PROGRAMS_arch += ppc64-test-altivec - endif #USE_ALTIVEC --endif #ARCH_PPC64 -+else #!ARCH_PPC64 -+if ARCH_X86_64 -+ check_PROGRAMS_arch += Gx64-test-dwarf-expressions Lx64-test-dwarf-expressions -+endif #ARCH X86_64 -+endif #!ARCH_PPC64 - endif #!ARCH_IA64 - check_PROGRAMS_cdep += Gtest-bt Ltest-bt Gtest-exc Ltest-exc \ - Gtest-init Ltest-init \ -@@ -139,6 +143,14 @@ Gia64_test_nat_SOURCES = Gia64-test-nat.c ia64-test-nat-asm.S - ia64_test_dyn1_SOURCES = ia64-test-dyn1.c ia64-dyn-asm.S flush-cache.S \ - flush-cache.h - ppc64_test_altivec_SOURCES = ppc64-test-altivec.c ppc64-test-altivec-utils.c -+ -+ -+Gx64_test_dwarf_expressions_SOURCES = Gx64-test-dwarf-expressions.c \ -+ x64-test-dwarf-expressions.S -+Lx64_test_dwarf_expressions_SOURCES = Lx64-test-dwarf-expressions.c \ -+ x64-test-dwarf-expressions.S -+ -+ - Gtest_init_SOURCES = Gtest-init.cxx - Ltest_init_SOURCES = Ltest-init.cxx - Ltest_cxx_exceptions_SOURCES = Ltest-cxx-exceptions.cxx -@@ -232,3 +244,6 @@ Lia64_test_readonly_LDADD = $(LIBUNWIND_local) - ia64_test_dyn1_LDADD = $(LIBUNWIND) - ia64_test_sig_LDADD = $(LIBUNWIND) - ppc64_test_altivec_LDADD = $(LIBUNWIND) -+ -+Gx64_test_dwarf_expressions_LDADD = $(LIBUNWIND) $(LIBUNWIND_local) -+Lx64_test_dwarf_expressions_LDADD = $(LIBUNWIND_local) -diff --git a/tests/x64-test-dwarf-expressions.S b/tests/x64-test-dwarf-expressions.S -new file mode 100644 -index 0000000..f275625 ---- /dev/null -+++ b/tests/x64-test-dwarf-expressions.S -@@ -0,0 +1,78 @@ -+.global DW_CFA_expression_testcase -+ -+.extern recover_register -+ -+.text -+ -+# CFI expressions were added in DWARF v3 to allow compilers to specify memory -+# locations or register values using DWARF programs. These programs are simple -+# stack-based operations which allow the compiler to encode integer mathematics -+# and other complex logic. CFI expressions are therefore more powerful than the -+# conventional register + offset schemes. -+# -+# These tests capture a bug we have fixed in libunwind. CFI expression programs -+# always start with the current CFA pushed onto the stack. This file contains a -+# pair of routines which test CFI expression parsing. Specifically they test -+# DW_CFA_expression logic, which uses DWARF expressions to compute the address -+# where a non-volatile register was stored. -+# -+# Main calls DW_CFA_expression_testcase, which sets up known state in a -+# non-volatile (caller-saved) register. We use r12 for this purpose. After this -+# DW_CFA_expression_testcase then calls DW_CFA_expression_inner, which clobbers -+# r12 after stashing its value on the stack. This routine contains a DWARF3 CFI -+# expression to restore the value of r12 on unwind which should allow libunwind -+# to recover clobbered state. DW_CFA_expression_inner calls recover_register to -+# retrieve the cached register value. This function recovers the register value -+# by using libunwind to unwind the stack through DW_CFA_expression_inner and up -+# to the call site in DW_CFA_expression_testcase. If our expression is correct, -+# libunwind will be able to restore r12 from the stack. -+# -+# BE CAREFUL WITH rdi, rsi, rax HERE! The arguments to recover_register are -+# passed in via rdi, rsi and I just let them flow through unchanged. Similarly -+# RAX flows back unchanged. Adding any function calls to the below may clobber -+# these registers and cause this test to fail mysteriously. -+ -+ -+######################################################## -+# Test: Restoring a register using a DW_CFA_expression # -+# which uses implicit CFA pushed onto stack. # -+######################################################## -+ -+.type DW_CFA_expression_testcase STT_FUNC -+DW_CFA_expression_testcase: -+ .cfi_startproc -+ push %r12 -+ .cfi_adjust_cfa_offset 8 -+ # Move our sentinel (known) value into non-volatile (Callee-saved) r12 -+ mov $111222333, %r12 -+ .cfi_rel_offset %r12, 0 -+ call DW_CFA_expression_inner -+ pop %r12 -+ .cfi_restore %r12 -+ .cfi_adjust_cfa_offset -8 -+ ret -+ .cfi_endproc -+.size DW_CFA_expression_testcase,.-DW_CFA_expression_testcase -+ -+.type DW_CFA_expression_inner STT_FUNC -+DW_CFA_expression_inner: -+ .cfi_startproc -+ push %r12 -+ .cfi_adjust_cfa_offset 8 -+ # !! IMPORTANT BIT !! The test is all about how we parse the following bytes. -+ # Now we use an expression to describe where our sentinel value is stored: -+ # DW_CFA_expression(0x10), r12(0x0c), Length(0x02), (preamble) -+ # DW_OP_lit16(0x40), DW_OP_minus(0x1c) (instructions) -+ # Parsing starts with the CFA on the stack, then pushes 16, then does a minus -+ # which is eqivalent to a=pop(), b=pop(), push(b-a), leaving us with a value -+ # of cfa-16 (cfa points at old rsp, cfa-8 is our rip, so we stored r12 at -+ # cfa-16). -+ xor %r12, %r12 # Trash r12 -+ .cfi_escape 0x10, 0x0c, 0x2, 0x40, 0x1c # DW_CFA_expression for recovery -+ call recover_register -+ pop %r12 -+ .cfi_restore %r12 -+ .cfi_adjust_cfa_offset -8 -+ ret -+ .cfi_endproc -+.size DW_CFA_expression_inner,.-DW_CFA_expression_inner --- -1.8.3.1 - diff --git a/dwarf-do-not-allocate-in-load_debug_frame-72.patch b/dwarf-do-not-allocate-in-load_debug_frame-72.patch deleted file mode 100644 index 63fb84b0590ea41902068d67224b17a1294fb5c9..0000000000000000000000000000000000000000 --- a/dwarf-do-not-allocate-in-load_debug_frame-72.patch +++ /dev/null @@ -1,39 +0,0 @@ -From b5cbcaee13233ddbc2e6a3fffe85374031f51000 Mon Sep 17 00:00:00 2001 -From: Dave Watson -Date: Tue, 10 Apr 2018 10:55:34 -0700 -Subject: [PATCH 15/50] dwarf: do not allocate in load_debug_frame (#72) - -load_debug_frame calls malloc() in a couple spots, use mmap via -GET_MEMORY instead. These call paths are infrequent, and are never -freed. - -Found by running tcmalloc unit tests on aarch64, when DEBUG_FRAME support is on. ---- - src/dwarf/Gfind_proc_info-lsb.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c -index c18783e..58fa51d 100644 ---- a/src/dwarf/Gfind_proc_info-lsb.c -+++ b/src/dwarf/Gfind_proc_info-lsb.c -@@ -119,7 +119,7 @@ load_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local) - } - - *bufsize = shdr->sh_size; -- *buf = malloc (*bufsize); -+ GET_MEMORY(*buf, *bufsize); - - memcpy(*buf, shdr->sh_offset + ei.image, *bufsize); - -@@ -208,7 +208,7 @@ locate_debug_info (unw_addr_space_t as, unw_word_t addr, const char *dlname, - - if (!err) - { -- fdesc = malloc (sizeof (struct unw_debug_frame_list)); -+ GET_MEMORY(fdesc, sizeof (struct unw_debug_frame_list)); - - fdesc->start = start; - fdesc->end = end; --- -1.8.3.1 - diff --git a/libunwind-1.3.1.tar.gz b/libunwind-1.3.1.tar.gz deleted file mode 100644 index 00a954204eb45204919ce36db4f2f0966f43d96d..0000000000000000000000000000000000000000 Binary files a/libunwind-1.3.1.tar.gz and /dev/null differ diff --git a/libunwind-1.4.0.tar.gz b/libunwind-1.4.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..b99b6c6c24ec2c957792dce11401f0fe6bd6a38d Binary files /dev/null and b/libunwind-1.4.0.tar.gz differ diff --git a/libunwind.spec b/libunwind.spec index 128e991c326f9dd11c4d5d724fcde5dcaf7cf3e7..22c199ed7c1d1122ed8baa8afe0042b2c05f5225 100644 --- a/libunwind.spec +++ b/libunwind.spec @@ -1,21 +1,11 @@ Name: libunwind -Version: 1.3.1 -Release: 3 +Version: 1.4.0 +Release: 1 Summary: Libunwind provides a C ABI to determine the call-chain of a program License: BSD URL: http://savannah.nongnu.org/projects/libunwind Source: http://download-mirror.savannah.gnu.org/releases/libunwind/libunwind-%{version}.tar.gz -Patch6000: Don-t-check-if-the-memory-is-in-core-64.patch -Patch6001: dwarf-do-not-allocate-in-load_debug_frame-72.patch -Patch6002: Cleanup-remove-unused-variable.patch -Patch6003: Fix-race-conditions-in-validate_mem-via-atomics.patch -Patch6004: Optionally-use-a-thread-local-cache-for-valid-memory.patch -Patch6005: Also-define-NLGA-when-we-build-with-atomic-ops-80.patch -Patch6006: aarch-v2-aarch64-PLT-entry-recognition-fixes-86.patch -Patch6007: dwarf-Add-missing-opcodes-to-the-operands-table-in-G.patch -Patch6008: dwarf-Push-correct-CFA-onto-stack-for-dwarf-expressi.patch - ExclusiveArch: aarch64 %{ix86} x86_64 BuildRequires: automake libtool autoconf texlive-latex2man @@ -93,6 +83,12 @@ make check || true %{_mandir}/*/* %changelog +* Sat Mar 30 2020 wenzhanli - 1.4.0-1 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:update version 1.4.0 + * Sun Jan 12 2020 openEuler Buildteam - 1.3.1-3 - remove useless patch