vmbase: Support LLVM and Bionic stack guard
C code compiled with the Android toolchain has stack guard checks
enabled. So as to avoid having to recompile every target with
-fno-stack-guard, instead add the expected symbols to vmbase.
This means we need __stack_chk_guard variable containing the canary
(used by all libc implementations [1]) and a thread-local storage containing
another copy of the canary at offset 40 (Bionic only [2]).
If the instrumentation detects an error, it calls __stack_chk_fail.
Provide an implementation that simply panics.
[1] bionic/tests/stack_protector_test.cpp
[2] https://reviews.llvm.org/D18632
Bug: 237372981
Test: atest vmbase_example.integration_test
Change-Id: I00de7c75aef6a57a73667df6983a12b01fbe9e51
diff --git a/vmbase/entry.S b/vmbase/entry.S
index 490c2f3..75ab90b 100644
--- a/vmbase/entry.S
+++ b/vmbase/entry.S
@@ -73,6 +73,14 @@
.set .Lsctlrval, .L_SCTLR_ELx_M | .L_SCTLR_ELx_C | .L_SCTLR_ELx_SA | .L_SCTLR_EL1_ITD | .L_SCTLR_EL1_SED
.set .Lsctlrval, .Lsctlrval | .L_SCTLR_ELx_I | .L_SCTLR_EL1_SPAN | .L_SCTLR_EL1_RES1 | .L_SCTLR_EL1_WXN
+/* Bionic-compatible stack protector */
+.section .data.stack_protector, "aw"
+__bionic_tls:
+ .zero 40
+.global __stack_chk_guard
+__stack_chk_guard:
+ .quad 0x23d6d3f3c3b84098 /* TODO: randomize */
+
/**
* This is a generic entry point for an image. It carries out the operations required to prepare the
* loaded image to be run. Specifically, it zeroes the bss section using registers x25 and above,
@@ -150,6 +158,10 @@
adr x30, vector_table_el1
msr vbar_el1, x30
+ /* Set up Bionic-compatible thread-local storage. */
+ adr_l x30, __bionic_tls
+ msr tpidr_el0, x30
+
/* Call into Rust code. */
bl rust_entry