[Lldb-commits] [lldb] [lldb][Docs] Add Guarded Control Stack to AArch64 Linux page (PR #117860)
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 27 01:47:14 PST 2024
https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/117860
The meat of this is how we execute expressions and deal with the aftermath. For most users this will never be a concern, so it functions more as a design doc than anything else.
>From 4838ed0ef8a62041981e61a8d405251bb32c147d Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 27 Aug 2024 15:22:10 +0100
Subject: [PATCH] [lldb][Docs] Add Guarded Control Stack to AArch64 Linux page
The meat of this is how we execute expressions and deal with the
aftermath. For most users this will never be a concern, so it
functions more as a design doc than anything else.
---
lldb/docs/use/aarch64-linux.md | 51 ++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/lldb/docs/use/aarch64-linux.md b/lldb/docs/use/aarch64-linux.md
index 393838dc0bb4f5..425336ddd81e2f 100644
--- a/lldb/docs/use/aarch64-linux.md
+++ b/lldb/docs/use/aarch64-linux.md
@@ -229,3 +229,54 @@ bytes.
`zt0`'s value and whether it is active or not will be saved prior to
expression evaluation and restored afterwards.
+
+## Guarded Control Stack Extension (GCS)
+
+GCS support includes the following new registers:
+
+* `gcs_features_enabled`
+* `gcs_features_locked`
+* `gcspr_el0`
+
+These map to the registers ptrace provides. The first two have had a `gcs_`
+prefix added as their names are too generic without it.
+
+When the GCS is enabled the kernel allocates a memory region for it. This region
+has a special attribute that LLDB will detect and presents like this:
+```
+ (lldb) memory region --all
+ <...>
+ [0x0000fffff7a00000-0x0000fffff7e00000) rw-
+ shadow stack: yes
+ [0x0000fffff7e00000-0x0000fffff7e10000) ---
+```
+
+`shadow stack` is a generic term used in the kernel for secure stack
+extensions like GCS.
+
+### Expression Evaluation
+
+To execute an expression, LLDB must push the return address of the expression
+wrapper (usually the entry point of the program) to the Guarded Control Stack.
+It does this by decrementing `gcspr_el0` and writing to the location that
+`gcspr_el0` then points to (instead of using the GCS push instructions).
+
+After an expression finishes, LLDB will restore the contents of all 3 registers,
+apart from the enable bit of `gcs_features_enabled`.
+
+This is because there are limits on how often and from where you can set this
+value. We cannot enable GCS from ptrace at all and it is expected that a process
+that has enabled GCS then disabled it, will not enable it again. The simplest
+choice was to not restore the enable bit at all. It's up to the user or
+program to manage that value.
+
+The return address that was pushed onto the Guarded Control Stack will be left
+in place. As will any values that were pushed to the stack by functions run
+during the expresison.
+
+When the process resumes, `gcspr_el0` will be pointing to the original entry
+on the stack. So the other values will have no effect and likely be overwritten
+by future function calls.
+
+LLDB does not track and restore changes to general memory during expressions,
+so not restoring the GCS contents fits with the current behaviour.
More information about the lldb-commits
mailing list