@@ -229,3 +229,54 @@ bytes.
229229
230230` zt0 ` 's value and whether it is active or not will be saved prior to
231231expression evaluation and restored afterwards.
232+
233+ ## Guarded Control Stack Extension (GCS)
234+
235+ GCS support includes the following new registers:
236+
237+ * ` gcs_features_enabled `
238+ * ` gcs_features_locked `
239+ * ` gcspr_el0 `
240+
241+ These map to the registers ptrace provides. The first two have had a ` gcs_ `
242+ prefix added as their names are too generic without it.
243+
244+ When the GCS is enabled the kernel allocates a memory region for it. This region
245+ has a special attribute that LLDB will detect and presents like this:
246+ ```
247+ (lldb) memory region --all
248+ <...>
249+ [0x0000fffff7a00000-0x0000fffff7e00000) rw-
250+ shadow stack: yes
251+ [0x0000fffff7e00000-0x0000fffff7e10000) ---
252+ ```
253+
254+ ` shadow stack ` is a generic term used in the kernel for secure stack
255+ extensions like GCS.
256+
257+ ### Expression Evaluation
258+
259+ To execute an expression, LLDB must push the return address of the expression
260+ wrapper (usually the entry point of the program) to the Guarded Control Stack.
261+ It does this by decrementing ` gcspr_el0 ` and writing to the location that
262+ ` gcspr_el0 ` then points to (instead of using the GCS push instructions).
263+
264+ After an expression finishes, LLDB will restore the contents of all 3 registers,
265+ apart from the enable bit of ` gcs_features_enabled ` .
266+
267+ This is because there are limits on how often and from where you can set this
268+ value. We cannot enable GCS from ptrace at all and it is expected that a process
269+ that has enabled GCS then disabled it, will not enable it again. The simplest
270+ choice was to not restore the enable bit at all. It's up to the user or
271+ program to manage that value.
272+
273+ The return address that was pushed onto the Guarded Control Stack will be left
274+ in place. As will any values that were pushed to the stack by functions run
275+ during the expresison.
276+
277+ When the process resumes, ` gcspr_el0 ` will be pointing to the original entry
278+ on the stack. So the other values will have no effect and likely be overwritten
279+ by future function calls.
280+
281+ LLDB does not track and restore changes to general memory during expressions,
282+ so not restoring the GCS contents fits with the current behaviour.
0 commit comments