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/example/src/main.rs b/vmbase/example/src/main.rs
index 849302d..8aa9f04 100644
--- a/vmbase/example/src/main.rs
+++ b/vmbase/example/src/main.rs
@@ -23,7 +23,7 @@
 
 extern crate alloc;
 
-use crate::layout::{bionic_tls, boot_stack_range, print_addresses, DEVICE_REGION};
+use crate::layout::{boot_stack_range, print_addresses, DEVICE_REGION};
 use crate::pci::{check_pci, get_bar_region};
 use aarch64_paging::paging::MemoryRegion;
 use aarch64_paging::MapError;
@@ -32,9 +32,9 @@
 use libfdt::Fdt;
 use log::{debug, error, info, trace, warn, LevelFilter};
 use vmbase::{
-    configure_heap, cstr,
-    layout::{dtb_range, rodata_range, scratch_range, stack_chk_guard, text_range},
-    logger, main,
+    bionic, configure_heap, cstr,
+    layout::{dtb_range, rodata_range, scratch_range, text_range},
+    linker, logger, main,
     memory::{PageTable, SIZE_64KB},
 };
 
@@ -105,10 +105,18 @@
 }
 
 fn check_stack_guard() {
-    const BIONIC_TLS_STACK_GRD_OFF: usize = 40;
-
     info!("Testing stack guard");
-    assert_eq!(bionic_tls(BIONIC_TLS_STACK_GRD_OFF), stack_chk_guard());
+    // SAFETY: No concurrency issue should occur when running these tests.
+    let stack_guard = unsafe { bionic::TLS.stack_guard };
+    assert_ne!(stack_guard, 0);
+    // Check that the TLS and guard are properly accessible from the dedicated register.
+    assert_eq!(stack_guard, bionic::__get_tls().stack_guard);
+    // Check that the LLVM __stack_chk_guard alias is also properly set up.
+    assert_eq!(
+        stack_guard,
+        // SAFETY: No concurrency issue should occur when running these tests.
+        unsafe { linker::__stack_chk_guard },
+    );
 }
 
 fn check_data() {