Author: David Spickett Date: 2025-01-28T11:38:58Z New Revision: 6d0dd3d5c41e5b564714de9226c0623012538051
URL: https://github.com/llvm/llvm-project/commit/6d0dd3d5c41e5b564714de9226c0623012538051 DIFF: https://github.com/llvm/llvm-project/commit/6d0dd3d5c41e5b564714de9226c0623012538051.diff LOG: [lldb][Docs] Add Guarded Control Stack to AArch64 Linux page (#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. Added: Modified: lldb/docs/use/aarch64-linux.md Removed: ################################################################################ diff --git a/lldb/docs/use/aarch64-linux.md b/lldb/docs/use/aarch64-linux.md index 393838dc0bb4f5..164d25cef6721e 100644 --- a/lldb/docs/use/aarch64-linux.md +++ b/lldb/docs/use/aarch64-linux.md @@ -229,3 +229,64 @@ 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 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 when GCS is enabled, 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 now pointed to by `gcspr_el0` (instead of using the +GCS push instructions). + +After an expression finishes, LLDB will restore the contents of all 3 +GCS 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 +bit. + +GCS cannot be enabled from ptrace and it is expected that a process which +has enabled and then disabled GCS, will not enable it again. The simplest +choice was to not restore the enable bit at all. It is up to the user or +program to manage that bit. + +The return address that LLDB 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 expression. + +When the process resumes, `gcspr_el0` will be pointing to the original entry +on the guarded control 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. + +Note that if GCS is disabled and an expression enables it, LLDB will not +be able to setup the return address and it is up to that expression to do that +if it wants to return to LLDB correctly. + +If it does not do this, the expression will fail and although most process +state will be restored, GCS will be left enabled. Which means that the program +is very unlikely to be able to progress. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits