vmbase: Define Bionic TLS from Rust

Move the definition of __bionic_tls to Rust and generalize accessing it
through the TPIDR_EL0 in vmbase::bionic, reducing the amount of ASM we
have and giving typed accesses to the TLS from Rust.

Use the linker script to now define __stack_chk_guard at an offset from
__bionic_tls, which can't be done from Rust.

Note that TPIDR_EL0 can't be configured from rust_entry because the
compiler will dereference it during function entry to access
__stack_chk_guard and Rust doesn't support LLVM's
__attribute__((no_stack_protector)).

Test: atest DebugPolicyHostTests#testNoAdbInDebugPolicy_withDebugLevelNone_boots
Test: atest rialto_test vmbase_example.integration_test
Change-Id: Ife1e43a972758bff1cace87d80319465bb643e6d
diff --git a/vmbase/src/bionic.rs b/vmbase/src/bionic.rs
index 5af9ebc..2ce0e83 100644
--- a/vmbase/src/bionic.rs
+++ b/vmbase/src/bionic.rs
@@ -23,9 +23,36 @@
 
 use crate::console;
 use crate::eprintln;
+use crate::read_sysreg;
 
 const EOF: c_int = -1;
 
+/// Bionic thread-local storage.
+#[repr(C)]
+pub struct Tls {
+    /// Unused.
+    _unused: [u8; 40],
+    /// Use by the compiler as stack canary value.
+    pub stack_guard: u64,
+}
+
+/// Bionic TLS.
+///
+/// Provides the TLS used by Bionic code. This is unique as vmbase only supports one thread.
+///
+/// Note that the linker script re-exports __bionic_tls.stack_guard as __stack_chk_guard for
+/// compatibility with non-Bionic LLVM.
+#[link_section = ".data.stack_protector"]
+#[export_name = "__bionic_tls"]
+pub static mut TLS: Tls = Tls { _unused: [0; 40], stack_guard: 0 };
+
+/// Gets a reference to the TLS from the dedicated system register.
+pub fn __get_tls() -> &'static mut Tls {
+    let tpidr = read_sysreg!("tpidr_el0");
+    // SAFETY: The register is currently only written to once, from entry.S, with a valid value.
+    unsafe { &mut *(tpidr as *mut Tls) }
+}
+
 #[no_mangle]
 extern "C" fn __stack_chk_fail() -> ! {
     panic!("stack guard check failed");
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index e490faa..3d2b1c2 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -21,14 +21,14 @@
 extern crate alloc;
 
 pub mod arch;
-mod bionic;
+pub mod bionic;
 pub mod console;
 mod entry;
 pub mod fdt;
 pub mod heap;
 mod hvc;
 pub mod layout;
-mod linker;
+pub mod linker;
 pub mod logger;
 pub mod memory;
 pub mod power;