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.spick...@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. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits