1 //===-- RegisterContext.cpp -------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Target/RegisterContext.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/Value.h"
12 #include "lldb/Expression/DWARFExpression.h"
13 #include "lldb/Target/ExecutionContext.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Target/StackFrame.h"
16 #include "lldb/Target/Target.h"
17 #include "lldb/Target/Thread.h"
18 #include "lldb/Utility/DataExtractor.h"
19 #include "lldb/Utility/Endian.h"
20 #include "lldb/Utility/RegisterValue.h"
21 #include "lldb/Utility/Scalar.h"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
RegisterContext(Thread & thread,uint32_t concrete_frame_idx)26 RegisterContext::RegisterContext(Thread &thread, uint32_t concrete_frame_idx)
27 : m_thread(thread), m_concrete_frame_idx(concrete_frame_idx),
28 m_stop_id(thread.GetProcess()->GetStopID()) {}
29
30 RegisterContext::~RegisterContext() = default;
31
InvalidateIfNeeded(bool force)32 void RegisterContext::InvalidateIfNeeded(bool force) {
33 ProcessSP process_sp(m_thread.GetProcess());
34 bool invalidate = force;
35 uint32_t process_stop_id = UINT32_MAX;
36
37 if (process_sp)
38 process_stop_id = process_sp->GetStopID();
39 else
40 invalidate = true;
41
42 if (!invalidate)
43 invalidate = process_stop_id != GetStopID();
44
45 if (invalidate) {
46 InvalidateAllRegisters();
47 SetStopID(process_stop_id);
48 }
49 }
50
51 const RegisterInfo *
GetRegisterInfoByName(llvm::StringRef reg_name,uint32_t start_idx)52 RegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name,
53 uint32_t start_idx) {
54 if (reg_name.empty())
55 return nullptr;
56
57 const uint32_t num_registers = GetRegisterCount();
58 for (uint32_t reg = start_idx; reg < num_registers; ++reg) {
59 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
60
61 if (reg_name.equals_lower(reg_info->name) ||
62 reg_name.equals_lower(reg_info->alt_name))
63 return reg_info;
64 }
65 return nullptr;
66 }
67
68 uint32_t
UpdateDynamicRegisterSize(const lldb_private::ArchSpec & arch,RegisterInfo * reg_info)69 RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch,
70 RegisterInfo *reg_info) {
71 ExecutionContext exe_ctx(CalculateThread());
72
73 // In MIPS, the floating point registers size is depends on FR bit of SR
74 // register. if SR.FR == 1 then all floating point registers are 64 bits.
75 // else they are all 32 bits.
76
77 int expr_result;
78 uint32_t addr_size = arch.GetAddressByteSize();
79 const uint8_t *dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes;
80 const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
81
82 DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len,
83 arch.GetByteOrder(), addr_size);
84 ModuleSP opcode_ctx;
85 DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr);
86 Value result;
87 Status error;
88 if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
89 eRegisterKindDWARF, nullptr, nullptr, result,
90 &error)) {
91 expr_result = result.GetScalar().SInt(-1);
92 switch (expr_result) {
93 case 0:
94 return 4;
95 case 1:
96 return 8;
97 default:
98 return reg_info->byte_size;
99 }
100 } else {
101 printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString());
102 return reg_info->byte_size;
103 }
104 }
105
GetRegisterInfo(lldb::RegisterKind kind,uint32_t num)106 const RegisterInfo *RegisterContext::GetRegisterInfo(lldb::RegisterKind kind,
107 uint32_t num) {
108 const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
109 if (reg_num == LLDB_INVALID_REGNUM)
110 return nullptr;
111 return GetRegisterInfoAtIndex(reg_num);
112 }
113
GetRegisterName(uint32_t reg)114 const char *RegisterContext::GetRegisterName(uint32_t reg) {
115 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
116 if (reg_info)
117 return reg_info->name;
118 return nullptr;
119 }
120
GetPC(uint64_t fail_value)121 uint64_t RegisterContext::GetPC(uint64_t fail_value) {
122 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
123 LLDB_REGNUM_GENERIC_PC);
124 uint64_t pc = ReadRegisterAsUnsigned(reg, fail_value);
125
126 if (pc != fail_value) {
127 TargetSP target_sp = m_thread.CalculateTarget();
128 if (target_sp) {
129 Target *target = target_sp.get();
130 if (target)
131 pc = target->GetOpcodeLoadAddress(pc, AddressClass::eCode);
132 }
133 }
134
135 return pc;
136 }
137
SetPC(uint64_t pc)138 bool RegisterContext::SetPC(uint64_t pc) {
139 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
140 LLDB_REGNUM_GENERIC_PC);
141 bool success = WriteRegisterFromUnsigned(reg, pc);
142 if (success) {
143 StackFrameSP frame_sp(
144 m_thread.GetFrameWithConcreteFrameIndex(m_concrete_frame_idx));
145 if (frame_sp)
146 frame_sp->ChangePC(pc);
147 else
148 m_thread.ClearStackFrames();
149 }
150 return success;
151 }
152
SetPC(Address addr)153 bool RegisterContext::SetPC(Address addr) {
154 TargetSP target_sp = m_thread.CalculateTarget();
155 Target *target = target_sp.get();
156
157 lldb::addr_t callAddr = addr.GetCallableLoadAddress(target);
158 if (callAddr == LLDB_INVALID_ADDRESS)
159 return false;
160
161 return SetPC(callAddr);
162 }
163
GetSP(uint64_t fail_value)164 uint64_t RegisterContext::GetSP(uint64_t fail_value) {
165 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
166 LLDB_REGNUM_GENERIC_SP);
167 return ReadRegisterAsUnsigned(reg, fail_value);
168 }
169
SetSP(uint64_t sp)170 bool RegisterContext::SetSP(uint64_t sp) {
171 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
172 LLDB_REGNUM_GENERIC_SP);
173 return WriteRegisterFromUnsigned(reg, sp);
174 }
175
GetFP(uint64_t fail_value)176 uint64_t RegisterContext::GetFP(uint64_t fail_value) {
177 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
178 LLDB_REGNUM_GENERIC_FP);
179 return ReadRegisterAsUnsigned(reg, fail_value);
180 }
181
SetFP(uint64_t fp)182 bool RegisterContext::SetFP(uint64_t fp) {
183 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
184 LLDB_REGNUM_GENERIC_FP);
185 return WriteRegisterFromUnsigned(reg, fp);
186 }
187
GetReturnAddress(uint64_t fail_value)188 uint64_t RegisterContext::GetReturnAddress(uint64_t fail_value) {
189 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
190 LLDB_REGNUM_GENERIC_RA);
191 return ReadRegisterAsUnsigned(reg, fail_value);
192 }
193
GetFlags(uint64_t fail_value)194 uint64_t RegisterContext::GetFlags(uint64_t fail_value) {
195 uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
196 LLDB_REGNUM_GENERIC_FLAGS);
197 return ReadRegisterAsUnsigned(reg, fail_value);
198 }
199
ReadRegisterAsUnsigned(uint32_t reg,uint64_t fail_value)200 uint64_t RegisterContext::ReadRegisterAsUnsigned(uint32_t reg,
201 uint64_t fail_value) {
202 if (reg != LLDB_INVALID_REGNUM)
203 return ReadRegisterAsUnsigned(GetRegisterInfoAtIndex(reg), fail_value);
204 return fail_value;
205 }
206
ReadRegisterAsUnsigned(const RegisterInfo * reg_info,uint64_t fail_value)207 uint64_t RegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,
208 uint64_t fail_value) {
209 if (reg_info) {
210 RegisterValue value;
211 if (ReadRegister(reg_info, value))
212 return value.GetAsUInt64();
213 }
214 return fail_value;
215 }
216
WriteRegisterFromUnsigned(uint32_t reg,uint64_t uval)217 bool RegisterContext::WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval) {
218 if (reg == LLDB_INVALID_REGNUM)
219 return false;
220 return WriteRegisterFromUnsigned(GetRegisterInfoAtIndex(reg), uval);
221 }
222
WriteRegisterFromUnsigned(const RegisterInfo * reg_info,uint64_t uval)223 bool RegisterContext::WriteRegisterFromUnsigned(const RegisterInfo *reg_info,
224 uint64_t uval) {
225 if (reg_info) {
226 RegisterValue value;
227 if (value.SetUInt(uval, reg_info->byte_size))
228 return WriteRegister(reg_info, value);
229 }
230 return false;
231 }
232
CopyFromRegisterContext(lldb::RegisterContextSP context)233 bool RegisterContext::CopyFromRegisterContext(lldb::RegisterContextSP context) {
234 uint32_t num_register_sets = context->GetRegisterSetCount();
235 // We don't know that two threads have the same register context, so require
236 // the threads to be the same.
237 if (context->GetThreadID() != GetThreadID())
238 return false;
239
240 if (num_register_sets != GetRegisterSetCount())
241 return false;
242
243 RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();
244
245 for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx) {
246 const RegisterSet *const reg_set = GetRegisterSet(set_idx);
247
248 const uint32_t num_registers = reg_set->num_registers;
249 for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) {
250 const uint32_t reg = reg_set->registers[reg_idx];
251 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
252 if (!reg_info || reg_info->value_regs)
253 continue;
254 RegisterValue reg_value;
255
256 // If we can reconstruct the register from the frame we are copying from,
257 // then do so, otherwise use the value from frame 0.
258 if (context->ReadRegister(reg_info, reg_value)) {
259 WriteRegister(reg_info, reg_value);
260 } else if (frame_zero_context->ReadRegister(reg_info, reg_value)) {
261 WriteRegister(reg_info, reg_value);
262 }
263 }
264 }
265 return true;
266 }
267
GetThreadID() const268 lldb::tid_t RegisterContext::GetThreadID() const { return m_thread.GetID(); }
269
NumSupportedHardwareBreakpoints()270 uint32_t RegisterContext::NumSupportedHardwareBreakpoints() { return 0; }
271
SetHardwareBreakpoint(lldb::addr_t addr,size_t size)272 uint32_t RegisterContext::SetHardwareBreakpoint(lldb::addr_t addr,
273 size_t size) {
274 return LLDB_INVALID_INDEX32;
275 }
276
ClearHardwareBreakpoint(uint32_t hw_idx)277 bool RegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx) { return false; }
278
NumSupportedHardwareWatchpoints()279 uint32_t RegisterContext::NumSupportedHardwareWatchpoints() { return 0; }
280
SetHardwareWatchpoint(lldb::addr_t addr,size_t size,bool read,bool write)281 uint32_t RegisterContext::SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
282 bool read, bool write) {
283 return LLDB_INVALID_INDEX32;
284 }
285
ClearHardwareWatchpoint(uint32_t hw_index)286 bool RegisterContext::ClearHardwareWatchpoint(uint32_t hw_index) {
287 return false;
288 }
289
HardwareSingleStep(bool enable)290 bool RegisterContext::HardwareSingleStep(bool enable) { return false; }
291
ReadRegisterValueFromMemory(const RegisterInfo * reg_info,lldb::addr_t src_addr,uint32_t src_len,RegisterValue & reg_value)292 Status RegisterContext::ReadRegisterValueFromMemory(
293 const RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len,
294 RegisterValue ®_value) {
295 Status error;
296 if (reg_info == nullptr) {
297 error.SetErrorString("invalid register info argument.");
298 return error;
299 }
300
301 // Moving from addr into a register
302 //
303 // Case 1: src_len == dst_len
304 //
305 // |AABBCCDD| Address contents
306 // |AABBCCDD| Register contents
307 //
308 // Case 2: src_len > dst_len
309 //
310 // Status! (The register should always be big enough to hold the data)
311 //
312 // Case 3: src_len < dst_len
313 //
314 // |AABB| Address contents
315 // |AABB0000| Register contents [on little-endian hardware]
316 // |0000AABB| Register contents [on big-endian hardware]
317 if (src_len > RegisterValue::kMaxRegisterByteSize) {
318 error.SetErrorString("register too small to receive memory data");
319 return error;
320 }
321
322 const uint32_t dst_len = reg_info->byte_size;
323
324 if (src_len > dst_len) {
325 error.SetErrorStringWithFormat(
326 "%u bytes is too big to store in register %s (%u bytes)", src_len,
327 reg_info->name, dst_len);
328 return error;
329 }
330
331 ProcessSP process_sp(m_thread.GetProcess());
332 if (process_sp) {
333 uint8_t src[RegisterValue::kMaxRegisterByteSize];
334
335 // Read the memory
336 const uint32_t bytes_read =
337 process_sp->ReadMemory(src_addr, src, src_len, error);
338
339 // Make sure the memory read succeeded...
340 if (bytes_read != src_len) {
341 if (error.Success()) {
342 // This might happen if we read _some_ bytes but not all
343 error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read,
344 src_len);
345 }
346 return error;
347 }
348
349 // We now have a memory buffer that contains the part or all of the
350 // register value. Set the register value using this memory data.
351 // TODO: we might need to add a parameter to this function in case the byte
352 // order of the memory data doesn't match the process. For now we are
353 // assuming they are the same.
354 reg_value.SetFromMemoryData(reg_info, src, src_len,
355 process_sp->GetByteOrder(), error);
356 } else
357 error.SetErrorString("invalid process");
358
359 return error;
360 }
361
WriteRegisterValueToMemory(const RegisterInfo * reg_info,lldb::addr_t dst_addr,uint32_t dst_len,const RegisterValue & reg_value)362 Status RegisterContext::WriteRegisterValueToMemory(
363 const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len,
364 const RegisterValue ®_value) {
365 uint8_t dst[RegisterValue::kMaxRegisterByteSize];
366
367 Status error;
368
369 ProcessSP process_sp(m_thread.GetProcess());
370 if (process_sp) {
371
372 // TODO: we might need to add a parameter to this function in case the byte
373 // order of the memory data doesn't match the process. For now we are
374 // assuming they are the same.
375
376 const uint32_t bytes_copied = reg_value.GetAsMemoryData(
377 reg_info, dst, dst_len, process_sp->GetByteOrder(), error);
378
379 if (error.Success()) {
380 if (bytes_copied == 0) {
381 error.SetErrorString("byte copy failed.");
382 } else {
383 const uint32_t bytes_written =
384 process_sp->WriteMemory(dst_addr, dst, bytes_copied, error);
385 if (bytes_written != bytes_copied) {
386 if (error.Success()) {
387 // This might happen if we read _some_ bytes but not all
388 error.SetErrorStringWithFormat("only wrote %u of %u bytes",
389 bytes_written, bytes_copied);
390 }
391 }
392 }
393 }
394 } else
395 error.SetErrorString("invalid process");
396
397 return error;
398 }
399
ReadAllRegisterValues(lldb_private::RegisterCheckpoint & reg_checkpoint)400 bool RegisterContext::ReadAllRegisterValues(
401 lldb_private::RegisterCheckpoint ®_checkpoint) {
402 return ReadAllRegisterValues(reg_checkpoint.GetData());
403 }
404
WriteAllRegisterValues(const lldb_private::RegisterCheckpoint & reg_checkpoint)405 bool RegisterContext::WriteAllRegisterValues(
406 const lldb_private::RegisterCheckpoint ®_checkpoint) {
407 return WriteAllRegisterValues(reg_checkpoint.GetData());
408 }
409
CalculateTarget()410 TargetSP RegisterContext::CalculateTarget() {
411 return m_thread.CalculateTarget();
412 }
413
CalculateProcess()414 ProcessSP RegisterContext::CalculateProcess() {
415 return m_thread.CalculateProcess();
416 }
417
CalculateThread()418 ThreadSP RegisterContext::CalculateThread() {
419 return m_thread.shared_from_this();
420 }
421
CalculateStackFrame()422 StackFrameSP RegisterContext::CalculateStackFrame() {
423 // Register contexts might belong to many frames if we have inlined functions
424 // inside a frame since all inlined functions share the same registers, so we
425 // can't definitively say which frame we come from...
426 return StackFrameSP();
427 }
428
CalculateExecutionContext(ExecutionContext & exe_ctx)429 void RegisterContext::CalculateExecutionContext(ExecutionContext &exe_ctx) {
430 m_thread.CalculateExecutionContext(exe_ctx);
431 }
432
ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,uint32_t source_regnum,lldb::RegisterKind target_rk,uint32_t & target_regnum)433 bool RegisterContext::ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,
434 uint32_t source_regnum,
435 lldb::RegisterKind target_rk,
436 uint32_t &target_regnum) {
437 const uint32_t num_registers = GetRegisterCount();
438 for (uint32_t reg = 0; reg < num_registers; ++reg) {
439 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
440
441 if (reg_info->kinds[source_rk] == source_regnum) {
442 target_regnum = reg_info->kinds[target_rk];
443 return (target_regnum != LLDB_INVALID_REGNUM);
444 }
445 }
446 return false;
447 }
448