@@ -101,14 +101,21 @@ static Status PushToLinuxGuardedControlStack(addr_t return_addr,
101
101
Status error;
102
102
size_t wrote = thread.GetProcess ()->WriteMemory (gcspr_el0, &return_addr,
103
103
sizeof (return_addr), error);
104
- if ((wrote != sizeof (return_addr) || error.Fail ()))
104
+ if ((wrote != sizeof (return_addr) || error.Fail ())) {
105
+ // When PrepareTrivialCall fails, the register context is not restored,
106
+ // unlike when an expression fails to execute. This is arguably a bug,
107
+ // see https://github.com/llvm/llvm-project/issues/124269.
108
+ // For now we are handling this here specifically. We can assume this
109
+ // write will work as the one to decrement the register did.
110
+ reg_ctx->WriteRegisterFromUnsigned (gcspr_el0_info, gcspr_el0 + 8 );
105
111
return Status (" Failed to write new Guarded Control Stack entry." );
112
+ }
106
113
107
114
Log *log = GetLog (LLDBLog::Expressions);
108
115
LLDB_LOGF (log,
109
- " Pushed return address 0x%" PRIx64 " to Guarded Control Stack. "
116
+ " Pushed return address 0x%" PRIx64 " to Guarded Control Stack. "
110
117
" gcspr_el0 was 0%" PRIx64 " , is now 0x%" PRIx64 " ." ,
111
- return_addr, gcspr_el0 + 8 , gcspr_el0);
118
+ return_addr, gcspr_el0 - 8 , gcspr_el0);
112
119
113
120
// gcspr_el0 will be restored to the original value by lldb-server after
114
121
// the call has finished, which serves as the "pop".
@@ -143,6 +150,18 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
143
150
if (args.size () > 8 )
144
151
return false ;
145
152
153
+ // Do this first, as it's got the most chance of failing (though still very
154
+ // low).
155
+ if (GetProcessSP ()->GetTarget ().GetArchitecture ().GetTriple ().isOSLinux ()) {
156
+ Status err = PushToLinuxGuardedControlStack (return_addr, reg_ctx, thread);
157
+ // If we could not manage the GCS, the expression will certainly fail,
158
+ // and if we just carried on, that failure would be a lot more cryptic.
159
+ if (err.Fail ()) {
160
+ LLDB_LOGF (log, " Failed to setup Guarded Call Stack: %s" , err.AsCString ());
161
+ return false ;
162
+ }
163
+ }
164
+
146
165
for (size_t i = 0 ; i < args.size (); ++i) {
147
166
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo (
148
167
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
@@ -159,16 +178,6 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
159
178
return_addr))
160
179
return false ;
161
180
162
- if (GetProcessSP ()->GetTarget ().GetArchitecture ().GetTriple ().isOSLinux ()) {
163
- Status err = PushToLinuxGuardedControlStack (return_addr, reg_ctx, thread);
164
- // If we could not manage the GCS, the expression will certainly fail,
165
- // and if we just carried on, that failure would be a lot more cryptic.
166
- if (err.Fail ()) {
167
- LLDB_LOGF (log, " Failed to setup Guarded Call Stack: %s" , err.AsCString ());
168
- return false ;
169
- }
170
- }
171
-
172
181
// Set "sp" to the requested value
173
182
if (!reg_ctx->WriteRegisterFromUnsigned (
174
183
reg_ctx->GetRegisterInfo (eRegisterKindGeneric,
0 commit comments