summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/nonclangable.conf1
-rw-r--r--recipes-devtools/valgrind/valgrind/builtin_setjmp.patch125
-rw-r--r--recipes-devtools/valgrind/valgrind_%.bbappend2
3 files changed, 127 insertions, 1 deletions
diff --git a/conf/nonclangable.conf b/conf/nonclangable.conf
index 0e43036..3f392ff 100644
--- a/conf/nonclangable.conf
+++ b/conf/nonclangable.conf
@@ -74,7 +74,6 @@ TOOLCHAIN_pn-syslinux = "gcc"
74TOOLCHAIN_pn-systemtap = "gcc" 74TOOLCHAIN_pn-systemtap = "gcc"
75# v4l-utils uses nested functions 75# v4l-utils uses nested functions
76TOOLCHAIN_pn-v4l-utils = "gcc" 76TOOLCHAIN_pn-v4l-utils = "gcc"
77TOOLCHAIN_pn-valgrind = "gcc"
78# uses C++ which clang does not like 77# uses C++ which clang does not like
79TOOLCHAIN_pn-wvstreams = "gcc" 78TOOLCHAIN_pn-wvstreams = "gcc"
80TOOLCHAIN_pn-wvdial = "gcc" 79TOOLCHAIN_pn-wvdial = "gcc"
diff --git a/recipes-devtools/valgrind/valgrind/builtin_setjmp.patch b/recipes-devtools/valgrind/valgrind/builtin_setjmp.patch
new file mode 100644
index 0000000..04b198d
--- /dev/null
+++ b/recipes-devtools/valgrind/valgrind/builtin_setjmp.patch
@@ -0,0 +1,125 @@
1commit cebc9a058d2048e8233ee3eeb510e19b8772909f
2Author: Benoit Jacob <benoitjacob@google.com>
3Date: Wed May 29 21:15:53 2019 -0400
4
5 Implement VG_MINIMAL_SETJMP in inline assembly on Android/arm64
6 because __builtin_setjmp is not implemented in current clang
7 toolchains in current Android NDK.
8
9diff --git a/include/pub_tool_libcsetjmp.h b/include/pub_tool_libcsetjmp.h
10index 681450cef..ccdf295df 100644
11--- a/include/pub_tool_libcsetjmp.h
12+++ b/include/pub_tool_libcsetjmp.h
13@@ -126,6 +126,111 @@ UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
14 __attribute__((noreturn))
15 void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
16
17+#elif defined __aarch64__
18+
19+// __builtin_setjmp is not implemented by the standard C library
20+// used on Android in current llvm-based toolchains as of NDK r19.
21+//
22+// Here is a custom implementation of Valgrind's "minimal" setjmp
23+// interface. Per the comment at the top of this file, we only need
24+// to save integer registers.
25+//
26+// Per the Procedure Call Standard for the ARM 64-bit Architecture
27+// document,
28+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
29+// Section 5.1.1. General-purpose registers:
30+// >
31+// > A subroutine invocation must preserve the contents of the
32+// > registers r19-r29 and SP."
33+//
34+// We also need to save and restore r30, the link register, i.e.
35+// the default destination that a 'ret' instruction branches to.
36+//
37+// Note that this document is phrased in terms of 'r' registers
38+// (e.g. "r30") because it aims to be agnostic as to A64 vs A32
39+// instruction sets, but here we are targeting the A64 instruction
40+// set, so we are dealing with 'x' registers.
41+
42+
43+#define VG_MINIMAL_JMP_BUF(_name) UWord _name [13]
44+
45+__attribute__((returns_twice))
46+inline UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env))
47+{
48+ asm volatile(
49+ // x9 is the first of the regular temporary registers
50+ // per the above-mentioned Procedule Call Standard document.
51+ // Use it as temporary to hold the value of SP, since str does
52+ // not accept SP as operand.
53+ " mov x9, sp \n"
54+ // Store the general-purpose registers that we need to save
55+ // per the above discussion.
56+ // Note that x30 is the link register.
57+ " stp x19, x20, [%[_env], 0] \n"
58+ " stp x21, x22, [%[_env], 0x10] \n"
59+ " stp x23, x24, [%[_env], 0x20] \n"
60+ " stp x25, x26, [%[_env], 0x30] \n"
61+ " stp x27, x28, [%[_env], 0x40] \n"
62+ " stp x29, x30, [%[_env], 0x50] \n"
63+ // Store the value of SP.
64+ " str x9, [%[_env], 0x60] \n"
65+ :
66+ // No outputs
67+ :
68+ // Inputs
69+ [_env]"r"(_env)
70+ :
71+ // Clobbers.
72+ // We have used x9 as a temporary
73+ "x9",
74+ // We have written to memory locations
75+ "memory");
76+
77+ // Direct invokation of setjmp always returns 0.
78+ // The pseudo returning of the value 1 as a return from longjmp
79+ // is implemented in longjmp.
80+ return 0;
81+}
82+
83+__attribute__((noreturn))
84+inline void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env))
85+{
86+ asm volatile(
87+ // Loads to match the stores in the above setjmp implementation.
88+ " ldp x19, x20, [%[_env], 0] \n"
89+ " ldp x21, x22, [%[_env], 0x10] \n"
90+ " ldp x23, x24, [%[_env], 0x20] \n"
91+ " ldp x25, x26, [%[_env], 0x30] \n"
92+ " ldp x27, x28, [%[_env], 0x40] \n"
93+ " ldp x29, x30, [%[_env], 0x50] \n"
94+ " ldr x9, [%[_env], 0x60] \n"
95+ " mov sp, x9 \n"
96+ // return as setjmp for the second time, returning 1.
97+ // Since we have loaded the link register x30 from the saved buffer
98+ // that was set by the above setjmp implementation, the 'ret' instruction
99+ // here is going to return to where setjmp was called.
100+ // Per the setjmp/longjmp contract, that pseudo second returning
101+ // of setjmp should return the value 1.
102+ // x0 is holds the integer return value.
103+ " mov x0, 1 \n"
104+ " ret \n"
105+ :
106+ // No outputs
107+ :
108+ // Inputs
109+ [_env]"r"(_env)
110+ :
111+ // Clobbers.
112+ // We have used x9 as a temporary
113+ "x9");
114+
115+ // This statement is unreachable because the above asm statement
116+ // unconditionally does a 'ret' instruction. The purpose of this
117+ // statement is to silence clang warnings about this function returning
118+ // while having the 'noreturn' attribute.
119+ __builtin_unreachable();
120+}
121+
122 #else
123
124 /* The default implementation. */
125
diff --git a/recipes-devtools/valgrind/valgrind_%.bbappend b/recipes-devtools/valgrind/valgrind_%.bbappend
new file mode 100644
index 0000000..def33ce
--- /dev/null
+++ b/recipes-devtools/valgrind/valgrind_%.bbappend
@@ -0,0 +1,2 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
2SRC_URI_append = " file://builtin_setjmp.patch"