summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/libunwind/libunwind/linux-musl.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-support/libunwind/libunwind/linux-musl.patch')
-rw-r--r--meta/recipes-support/libunwind/libunwind/linux-musl.patch152
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), &not_used);
++ invalid_prev_rip = dwarf_get (&c->dwarf, DWARF_MEM_LOC (c->dwarf, prev_ip), &not_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), &not_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), &not_used) != 0\n", new_ip);
++ if ((ret = dwarf_get(&c->dwarf, DWARF_MEM_LOC(c->dwarf, new_ip), &not_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
+