summaryrefslogtreecommitdiffstats
path: root/compiler-rt/test/shadowcallstack/libc_support.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/test/shadowcallstack/libc_support.h')
-rw-r--r--compiler-rt/test/shadowcallstack/libc_support.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/compiler-rt/test/shadowcallstack/libc_support.h b/compiler-rt/test/shadowcallstack/libc_support.h
new file mode 100644
index 00000000000..5d89aab645a
--- /dev/null
+++ b/compiler-rt/test/shadowcallstack/libc_support.h
@@ -0,0 +1,41 @@
+// This header provides replacements for certain libc functions. It is necessary
+// in order to safely run the tests on aarch64, because the system libc might
+// not have been compiled with -ffixed-x18.
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __aarch64__
+
+size_t scs_strlen(const char *p) {
+ size_t retval = 0;
+ while (*p++)
+ retval++;
+ return retval;
+}
+
+// We mark this function as noinline to make sure that its callers do not
+// become leaf functions as a result of inlining. This is because we want to
+// make sure that we generate the correct code for non-leaf functions.
+
+__attribute__((noinline)) void scs_fputs_stdout(const char *p) {
+ __asm__ __volatile__(
+ "mov x0, #1\n" // stdout
+ "mov x1, %0\n"
+ "mov x2, %1\n"
+ "mov x8, #64\n" // write
+ "svc #0\n" ::"r"(p),
+ "r"(scs_strlen(p))
+ : "x0", "x1", "x2", "x8");
+}
+
+#else
+
+__attribute__((noinline)) void scs_fputs_stdout(const char *p) {
+ fputs(p, stdout);
+}
+
+#endif
OpenPOWER on IntegriCloud