@@ -94,6 +94,39 @@ static lldb::addr_t ReadFlags(NativeRegisterContext ®siter_context) {
94
94
LLDB_INVALID_ADDRESS);
95
95
}
96
96
97
+ static int GetSoftwareWatchpointSize (const ArchSpec &arch,
98
+ lldb::addr_t next_flags) {
99
+ if (arch.GetMachine () == llvm::Triple::arm) {
100
+ if (next_flags & 0x20 )
101
+ // Thumb mode
102
+ return 2 ;
103
+ else
104
+ // Arm mode
105
+ return 4 ;
106
+ }
107
+ if (arch.IsMIPS () || arch.GetTriple ().isPPC64 () ||
108
+ arch.GetTriple ().isRISCV () || arch.GetTriple ().isLoongArch ())
109
+ return 4 ;
110
+ return 0 ;
111
+ }
112
+
113
+ static Status SetSoftwareBreakPointOnPC (const ArchSpec &arch, lldb::addr_t pc,
114
+ lldb::addr_t next_flags,
115
+ NativeProcessProtocol &process) {
116
+ int size_hint = GetSoftwareWatchpointSize (arch, next_flags);
117
+ Status error;
118
+ error = process.SetBreakpoint (pc, size_hint, /* hardware=*/ false );
119
+
120
+ // If setting the breakpoint fails because pc is out of the address
121
+ // space, ignore it and let the debugee segfault.
122
+ if (error.GetError () == EIO || error.GetError () == EFAULT) {
123
+ return Status ();
124
+ } else if (error.Fail ())
125
+ return error;
126
+
127
+ return Status ();
128
+ }
129
+
97
130
Status NativeProcessSoftwareSingleStep::SetupSoftwareSingleStepping (
98
131
NativeThreadProtocol &thread) {
99
132
Status error;
@@ -115,8 +148,23 @@ Status NativeProcessSoftwareSingleStep::SetupSoftwareSingleStepping(
115
148
emulator_up->SetWriteMemCallback (&WriteMemoryCallback);
116
149
emulator_up->SetWriteRegCallback (&WriteRegisterCallback);
117
150
118
- if (!emulator_up->ReadInstruction ())
119
- return Status (" Read instruction failed!" );
151
+ if (!emulator_up->ReadInstruction ()) {
152
+ // try to get at least the size of next instruction to set breakpoint.
153
+ auto instrSizeOpt = emulator_up->GetLastInstrSize ();
154
+ if (!instrSizeOpt)
155
+ return Status (" Read instruction failed!" );
156
+ bool success = false ;
157
+ auto pc = emulator_up->ReadRegisterUnsigned (eRegisterKindGeneric,
158
+ LLDB_REGNUM_GENERIC_PC,
159
+ LLDB_INVALID_ADDRESS, &success);
160
+ if (!success)
161
+ return Status (" Reading pc failed!" );
162
+ lldb::addr_t next_pc = pc + *instrSizeOpt;
163
+ auto Result =
164
+ SetSoftwareBreakPointOnPC (arch, next_pc, /* next_flags */ 0x0 , process);
165
+ m_threads_stepping_with_breakpoint.insert ({thread.GetID (), next_pc});
166
+ return Result;
167
+ }
120
168
121
169
bool emulation_result =
122
170
emulator_up->EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
@@ -157,29 +205,7 @@ Status NativeProcessSoftwareSingleStep::SetupSoftwareSingleStepping(
157
205
// modifying the PC but we don't know how.
158
206
return Status (" Instruction emulation failed unexpectedly." );
159
207
}
160
-
161
- int size_hint = 0 ;
162
- if (arch.GetMachine () == llvm::Triple::arm) {
163
- if (next_flags & 0x20 ) {
164
- // Thumb mode
165
- size_hint = 2 ;
166
- } else {
167
- // Arm mode
168
- size_hint = 4 ;
169
- }
170
- } else if (arch.IsMIPS () || arch.GetTriple ().isPPC64 () ||
171
- arch.GetTriple ().isRISCV () || arch.GetTriple ().isLoongArch ())
172
- size_hint = 4 ;
173
- error = process.SetBreakpoint (next_pc, size_hint, /* hardware=*/ false );
174
-
175
- // If setting the breakpoint fails because next_pc is out of the address
176
- // space, ignore it and let the debugee segfault.
177
- if (error.GetError () == EIO || error.GetError () == EFAULT) {
178
- return Status ();
179
- } else if (error.Fail ())
180
- return error;
181
-
208
+ auto Result = SetSoftwareBreakPointOnPC (arch, next_pc, next_flags, process);
182
209
m_threads_stepping_with_breakpoint.insert ({thread.GetID (), next_pc});
183
-
184
- return Status ();
210
+ return Result;
185
211
}
0 commit comments