diff options
Diffstat (limited to 'meta/recipes-support/libunwind/libunwind/linux-musl.patch')
-rw-r--r-- | meta/recipes-support/libunwind/libunwind/linux-musl.patch | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/meta/recipes-support/libunwind/libunwind/linux-musl.patch b/meta/recipes-support/libunwind/libunwind/linux-musl.patch new file mode 100644 index 00000000000..f155cafb519 --- /dev/null +++ b/meta/recipes-support/libunwind/libunwind/linux-musl.patch @@ -0,0 +1,152 @@ +From 75fe438e4adaa1666b39c4b08e22c1eb947b6986 Mon Sep 17 00:00:00 2001 +From: "Stephen M. Webb" <stephen.webb@bregmasoft.ca> +Date: Fri, 29 Dec 2023 10:24:03 -0500 +Subject: [PATCH] Add explicit support for linux-musl targets + +- added musl target CI builds to CI-unix.yml +- added config-time check for libucontext +- added better detection of NULL IP in x86_64 unw_step() because musl does not + follow the de facto x86_64 ABI conventions for main program entry + +Upstream-Status: Backport [75fe438e4adaa1666b39c4b08e22c1eb947b6986] +Signed-off-by: Ross Burton <ross.burton@arm.com> +--- + .github/workflows/CI-unix.yml | 66 ++++++++++++++++++++++++++++++++--- + configure.ac | 1 + + src/x86_64/Gstep.c | 63 ++++++++++++++++++++------------- + 3 files changed, 101 insertions(+), 29 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 8cde58af..406f3773 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -64,6 +64,7 @@ AC_SEARCH_LIBS([_Unwind_Resume], [gcc_s gcc], + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" + AC_SEARCH_LIBS([__uc_get_grs], [uca]) ++AC_SEARCH_LIBS([getcontext], [ucontext]) + + dnl Checks for library functions. + AC_CHECK_FUNCS(dl_iterate_phdr dl_phdr_removals_counter dlmodinfo getunwind \ +diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c +index 72ebbd96..1c33e149 100644 +--- a/src/x86_64/Gstep.c ++++ b/src/x86_64/Gstep.c +@@ -111,7 +111,8 @@ unw_step (unw_cursor_t *cursor) + code. */ + + unw_word_t invalid_prev_rip = 0; +- unw_word_t prev_ip = c->dwarf.ip, prev_cfa = c->dwarf.cfa; ++ unw_word_t prev_ip = c->dwarf.ip; ++ unw_word_t prev_cfa = c->dwarf.cfa; + struct dwarf_loc rbp_loc = DWARF_NULL_LOC, rsp_loc = DWARF_NULL_LOC, rip_loc = DWARF_NULL_LOC; + + /* We could get here because of missing/bad unwind information. +@@ -149,8 +150,9 @@ unw_step (unw_cursor_t *cursor) + c->dwarf.loc[RIP] = DWARF_LOC (c->dwarf.cfa, 0); + c->dwarf.cfa += 8; + } +- else if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])) ++ else if (prev_ip == 0 || (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]))) + { ++ Debug (2, "End of call chain detected\n"); + for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) + c->dwarf.loc[i] = DWARF_NULL_LOC; + } +@@ -167,7 +169,7 @@ unw_step (unw_cursor_t *cursor) + } + + unw_word_t not_used; +- invalid_prev_rip = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, prev_ip), ¬_used); ++ invalid_prev_rip = dwarf_get (&c->dwarf, DWARF_MEM_LOC (c->dwarf, prev_ip), ¬_used); + + if (!rbp && invalid_prev_rip == 0) + { +@@ -187,43 +189,55 @@ unw_step (unw_cursor_t *cursor) + int rip_fixup_success = 0; + if (invalid_prev_rip != 0) + { +- Debug (2, "Previous RIP 0x%lx was invalid, attempting fixup\n", prev_ip); ++ Debug (2, "Previous RIP %#010lx was invalid, attempting fixup\n", prev_ip); + unw_word_t rsp; + ret = dwarf_get (&c->dwarf, c->dwarf.loc[RSP], &rsp); ++ Debug (2, "get rsp %#010lx returned %d\n", rsp, ret); + + /*Test to see if what we think is the previous RIP is valid*/ + unw_word_t new_ip = 0; + if (dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) == 0) + { +- Debug (2, "RSP 0x%lx looks valid\n", rsp); +- if ((ret = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used)) == 0) ++ Debug (2, "RSP %#010lx (%#010lx) looks valid\n", rsp, new_ip); ++ if (new_ip == 0x00000000) + { +- Debug (2, "new_ip 0x%lx looks valid\n", new_ip); ++ Debug (2, "End of call chain detected\n"); + rip_fixup_success = 1; +- c->frame_info.cfa_reg_offset = 8; +- c->frame_info.cfa_reg_rsp = -1; +- c->frame_info.rbp_cfa_offset = -1; +- c->frame_info.rsp_cfa_offset = -1; +- c->frame_info.frame_type = UNW_X86_64_FRAME_OTHER; +- /* +- * The call should have pushed RIP to the stack +- * and since there was no preamble RSP hasn't been +- * touched so RIP should be at RSP. +- */ +- c->dwarf.cfa += 8; +- /* Optimised x64 binaries don't use RBP it seems? */ +- rbp_loc = c->dwarf.loc[RBP]; +- rsp_loc = DWARF_VAL_LOC (c, rsp + 8); +- rip_loc = DWARF_LOC (rsp, 0); ++ rbp_loc = DWARF_NULL_LOC; ++ rsp_loc = DWARF_NULL_LOC; ++ rip_loc = DWARF_NULL_LOC; + } + else + { +- Debug (2, "new_ip 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used) != 0\n", new_ip); ++ if ((ret = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), ¬_used)) == 0) ++ { ++ Debug (2, "new_ip %#010lx looks valid\n", new_ip); ++ rip_fixup_success = 1; ++ c->frame_info.cfa_reg_offset = 8; ++ c->frame_info.cfa_reg_rsp = -1; ++ c->frame_info.rbp_cfa_offset = -1; ++ c->frame_info.rsp_cfa_offset = -1; ++ c->frame_info.frame_type = UNW_X86_64_FRAME_OTHER; ++ /* ++ * The call should have pushed RIP to the stack ++ * and since there was no preamble RSP hasn't been ++ * touched so RIP should be at RSP. ++ */ ++ c->dwarf.cfa += 8; ++ /* Optimised x64 binaries don't use RBP it seems? */ ++ rbp_loc = c->dwarf.loc[RBP]; ++ rsp_loc = DWARF_VAL_LOC (c, rsp + 8); ++ rip_loc = DWARF_LOC (rsp, 0); ++ } ++ else ++ { ++ Debug (2, "new_ip %#010lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip_addr), &new_ip) != 0\n", new_ip); ++ } + } + } + else + { +- Debug (2, "rsp 0x%lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip) != 0\n", rsp); ++ Debug (2, "rsp %#010lx dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, rsp), &new_ip_addr) != 0\n", rsp); + } + } + /* +@@ -260,7 +274,6 @@ unw_step (unw_cursor_t *cursor) + c->frame_info.cfa_reg_offset = 16; + c->frame_info.rbp_cfa_offset = -16; + c->dwarf.cfa += 16; +- + } + } + /* Mark all registers unsaved */ +-- +2.34.1 + |