1 //===-- NativeRegisterContext.cpp -----------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Host/common/NativeRegisterContext.h"
10 #include "lldb/Utility/LLDBLog.h"
11 #include "lldb/Utility/RegisterValue.h"
13 #include "lldb/Host/PosixApi.h"
14 #include "lldb/Host/common/NativeProcessProtocol.h"
15 #include "lldb/Host/common/NativeThreadProtocol.h"
18 using namespace lldb_private
;
20 NativeRegisterContext::NativeRegisterContext(NativeThreadProtocol
&thread
)
24 NativeRegisterContext::~NativeRegisterContext() = default;
26 // FIXME revisit invalidation, process stop ids, etc. Right now we don't
27 // support caching in NativeRegisterContext. We can do this later by utilizing
28 // NativeProcessProtocol::GetStopID () and adding a stop id to
29 // NativeRegisterContext.
32 // NativeRegisterContext::InvalidateIfNeeded (bool force) {
33 // ProcessSP process_sp (m_thread.GetProcess());
34 // bool invalidate = force;
35 // uint32_t process_stop_id = UINT32_MAX;
38 // process_stop_id = process_sp->GetStopID();
43 // invalidate = process_stop_id != GetStopID();
47 // InvalidateAllRegisters ();
48 // SetStopID (process_stop_id);
53 NativeRegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name
,
58 // Generic register names take precedence over specific register names.
59 // For example, on x86 we want "sp" to refer to the complete RSP/ESP register
60 // rather than the 16-bit SP pseudo-register.
61 uint32_t generic_reg
= Args::StringToGenericRegister(reg_name
);
62 if (generic_reg
!= LLDB_INVALID_REGNUM
) {
63 const RegisterInfo
*reg_info
=
64 GetRegisterInfo(eRegisterKindGeneric
, generic_reg
);
69 const uint32_t num_registers
= GetRegisterCount();
70 for (uint32_t reg
= start_idx
; reg
< num_registers
; ++reg
) {
71 const RegisterInfo
*reg_info
= GetRegisterInfoAtIndex(reg
);
73 if (reg_name
.equals_insensitive(reg_info
->name
) ||
74 reg_name
.equals_insensitive(reg_info
->alt_name
))
81 const RegisterInfo
*NativeRegisterContext::GetRegisterInfo(uint32_t kind
,
83 const uint32_t reg_num
= ConvertRegisterKindToRegisterNumber(kind
, num
);
84 if (reg_num
== LLDB_INVALID_REGNUM
)
86 return GetRegisterInfoAtIndex(reg_num
);
89 const char *NativeRegisterContext::GetRegisterName(uint32_t reg
) {
90 const RegisterInfo
*reg_info
= GetRegisterInfoAtIndex(reg
);
92 return reg_info
->name
;
96 const char *NativeRegisterContext::GetRegisterSetNameForRegisterAtIndex(
97 uint32_t reg_index
) const {
98 const RegisterInfo
*const reg_info
= GetRegisterInfoAtIndex(reg_index
);
102 for (uint32_t set_index
= 0; set_index
< GetRegisterSetCount(); ++set_index
) {
103 const RegisterSet
*const reg_set
= GetRegisterSet(set_index
);
107 for (uint32_t reg_num_index
= 0; reg_num_index
< reg_set
->num_registers
;
109 const uint32_t reg_num
= reg_set
->registers
[reg_num_index
];
110 // FIXME double check we're checking the right register kind here.
111 if (reg_info
->kinds
[RegisterKind::eRegisterKindLLDB
] == reg_num
) {
112 // The given register is a member of this register set. Return the
113 // register set name.
114 return reg_set
->name
;
123 lldb::addr_t
NativeRegisterContext::GetPC(lldb::addr_t fail_value
) {
124 Log
*log
= GetLog(LLDBLog::Thread
);
126 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
127 LLDB_REGNUM_GENERIC_PC
);
129 "NativeRegisterContext::%s using reg index %" PRIu32
130 " (default %" PRIu64
")",
131 __FUNCTION__
, reg
, fail_value
);
133 const uint64_t retval
= ReadRegisterAsUnsigned(reg
, fail_value
);
135 LLDB_LOGF(log
, "NativeRegisterContext::%s " PRIu32
" retval %" PRIu64
,
136 __FUNCTION__
, retval
);
142 NativeRegisterContext::GetPCfromBreakpointLocation(lldb::addr_t fail_value
) {
143 return GetPC(fail_value
);
146 Status
NativeRegisterContext::SetPC(lldb::addr_t pc
) {
147 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
148 LLDB_REGNUM_GENERIC_PC
);
149 return WriteRegisterFromUnsigned(reg
, pc
);
152 lldb::addr_t
NativeRegisterContext::GetSP(lldb::addr_t fail_value
) {
153 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
154 LLDB_REGNUM_GENERIC_SP
);
155 return ReadRegisterAsUnsigned(reg
, fail_value
);
158 Status
NativeRegisterContext::SetSP(lldb::addr_t sp
) {
159 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
160 LLDB_REGNUM_GENERIC_SP
);
161 return WriteRegisterFromUnsigned(reg
, sp
);
164 lldb::addr_t
NativeRegisterContext::GetFP(lldb::addr_t fail_value
) {
165 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
166 LLDB_REGNUM_GENERIC_FP
);
167 return ReadRegisterAsUnsigned(reg
, fail_value
);
170 Status
NativeRegisterContext::SetFP(lldb::addr_t fp
) {
171 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
172 LLDB_REGNUM_GENERIC_FP
);
173 return WriteRegisterFromUnsigned(reg
, fp
);
176 lldb::addr_t
NativeRegisterContext::GetReturnAddress(lldb::addr_t fail_value
) {
177 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
178 LLDB_REGNUM_GENERIC_RA
);
179 return ReadRegisterAsUnsigned(reg
, fail_value
);
182 lldb::addr_t
NativeRegisterContext::GetFlags(lldb::addr_t fail_value
) {
183 uint32_t reg
= ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
,
184 LLDB_REGNUM_GENERIC_FLAGS
);
185 return ReadRegisterAsUnsigned(reg
, fail_value
);
189 NativeRegisterContext::ReadRegisterAsUnsigned(uint32_t reg
,
190 lldb::addr_t fail_value
) {
191 if (reg
!= LLDB_INVALID_REGNUM
)
192 return ReadRegisterAsUnsigned(GetRegisterInfoAtIndex(reg
), fail_value
);
197 NativeRegisterContext::ReadRegisterAsUnsigned(const RegisterInfo
*reg_info
,
198 lldb::addr_t fail_value
) {
199 Log
*log
= GetLog(LLDBLog::Thread
);
203 Status error
= ReadRegister(reg_info
, value
);
204 if (error
.Success()) {
206 "NativeRegisterContext::%s ReadRegister() succeeded, value "
208 __FUNCTION__
, value
.GetAsUInt64());
209 return value
.GetAsUInt64();
212 "NativeRegisterContext::%s ReadRegister() failed, error %s",
213 __FUNCTION__
, error
.AsCString());
216 LLDB_LOGF(log
, "NativeRegisterContext::%s ReadRegister() null reg_info",
222 Status
NativeRegisterContext::WriteRegisterFromUnsigned(uint32_t reg
,
224 if (reg
== LLDB_INVALID_REGNUM
)
225 return Status("NativeRegisterContext::%s (): reg is invalid", __FUNCTION__
);
226 return WriteRegisterFromUnsigned(GetRegisterInfoAtIndex(reg
), uval
);
230 NativeRegisterContext::WriteRegisterFromUnsigned(const RegisterInfo
*reg_info
,
234 return Status("reg_info is nullptr");
237 if (!value
.SetUInt(uval
, reg_info
->byte_size
))
238 return Status("RegisterValue::SetUInt () failed");
240 return WriteRegister(reg_info
, value
);
243 lldb::tid_t
NativeRegisterContext::GetThreadID() const {
244 return m_thread
.GetID();
247 uint32_t NativeRegisterContext::NumSupportedHardwareBreakpoints() { return 0; }
249 uint32_t NativeRegisterContext::SetHardwareBreakpoint(lldb::addr_t addr
,
251 return LLDB_INVALID_INDEX32
;
254 Status
NativeRegisterContext::ClearAllHardwareBreakpoints() {
255 return Status("not implemented");
258 bool NativeRegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx
) {
262 Status
NativeRegisterContext::GetHardwareBreakHitIndex(uint32_t &bp_index
,
263 lldb::addr_t trap_addr
) {
264 bp_index
= LLDB_INVALID_INDEX32
;
265 return Status("not implemented");
268 uint32_t NativeRegisterContext::NumSupportedHardwareWatchpoints() { return 0; }
270 uint32_t NativeRegisterContext::SetHardwareWatchpoint(lldb::addr_t addr
,
272 uint32_t watch_flags
) {
273 return LLDB_INVALID_INDEX32
;
276 bool NativeRegisterContext::ClearHardwareWatchpoint(uint32_t hw_index
) {
280 Status
NativeRegisterContext::ClearWatchpointHit(uint32_t hw_index
) {
281 return Status("not implemented");
284 Status
NativeRegisterContext::ClearAllHardwareWatchpoints() {
285 return Status("not implemented");
288 Status
NativeRegisterContext::IsWatchpointHit(uint32_t wp_index
, bool &is_hit
) {
290 return Status("not implemented");
293 Status
NativeRegisterContext::GetWatchpointHitIndex(uint32_t &wp_index
,
294 lldb::addr_t trap_addr
) {
295 wp_index
= LLDB_INVALID_INDEX32
;
296 return Status("not implemented");
299 Status
NativeRegisterContext::IsWatchpointVacant(uint32_t wp_index
,
302 return Status("not implemented");
305 lldb::addr_t
NativeRegisterContext::GetWatchpointAddress(uint32_t wp_index
) {
306 return LLDB_INVALID_ADDRESS
;
309 lldb::addr_t
NativeRegisterContext::GetWatchpointHitAddress(uint32_t wp_index
) {
310 return LLDB_INVALID_ADDRESS
;
313 bool NativeRegisterContext::HardwareSingleStep(bool enable
) { return false; }
315 Status
NativeRegisterContext::ReadRegisterValueFromMemory(
316 const RegisterInfo
*reg_info
, lldb::addr_t src_addr
, size_t src_len
,
317 RegisterValue
®_value
) {
319 if (reg_info
== nullptr) {
320 error
.SetErrorString("invalid register info argument.");
324 // Moving from addr into a register
326 // Case 1: src_len == dst_len
328 // |AABBCCDD| Address contents
329 // |AABBCCDD| Register contents
331 // Case 2: src_len > dst_len
333 // Status! (The register should always be big enough to hold the data)
335 // Case 3: src_len < dst_len
337 // |AABB| Address contents
338 // |AABB0000| Register contents [on little-endian hardware]
339 // |0000AABB| Register contents [on big-endian hardware]
340 if (src_len
> RegisterValue::kMaxRegisterByteSize
) {
341 error
.SetErrorString("register too small to receive memory data");
345 const size_t dst_len
= reg_info
->byte_size
;
347 if (src_len
> dst_len
) {
348 error
.SetErrorStringWithFormat(
349 "%" PRIu64
" bytes is too big to store in register %s (%" PRIu64
351 static_cast<uint64_t>(src_len
), reg_info
->name
,
352 static_cast<uint64_t>(dst_len
));
356 NativeProcessProtocol
&process
= m_thread
.GetProcess();
357 uint8_t src
[RegisterValue::kMaxRegisterByteSize
];
361 error
= process
.ReadMemory(src_addr
, src
, src_len
, bytes_read
);
365 // Make sure the memory read succeeded...
366 if (bytes_read
!= src_len
) {
367 // This might happen if we read _some_ bytes but not all
368 error
.SetErrorStringWithFormat("read %" PRIu64
" of %" PRIu64
" bytes",
369 static_cast<uint64_t>(bytes_read
),
370 static_cast<uint64_t>(src_len
));
374 // We now have a memory buffer that contains the part or all of the register
375 // value. Set the register value using this memory data.
376 // TODO: we might need to add a parameter to this function in case the byte
377 // order of the memory data doesn't match the process. For now we are
378 // assuming they are the same.
379 reg_value
.SetFromMemoryData(reg_info
, src
, src_len
, process
.GetByteOrder(),
385 Status
NativeRegisterContext::WriteRegisterValueToMemory(
386 const RegisterInfo
*reg_info
, lldb::addr_t dst_addr
, size_t dst_len
,
387 const RegisterValue
®_value
) {
389 uint8_t dst
[RegisterValue::kMaxRegisterByteSize
];
393 NativeProcessProtocol
&process
= m_thread
.GetProcess();
395 // TODO: we might need to add a parameter to this function in case the byte
396 // order of the memory data doesn't match the process. For now we are
397 // assuming they are the same.
398 const size_t bytes_copied
= reg_value
.GetAsMemoryData(
399 reg_info
, dst
, dst_len
, process
.GetByteOrder(), error
);
401 if (error
.Success()) {
402 if (bytes_copied
== 0) {
403 error
.SetErrorString("byte copy failed.");
405 size_t bytes_written
;
406 error
= process
.WriteMemory(dst_addr
, dst
, bytes_copied
, bytes_written
);
410 if (bytes_written
!= bytes_copied
) {
411 // This might happen if we read _some_ bytes but not all
412 error
.SetErrorStringWithFormat("only wrote %" PRIu64
" of %" PRIu64
414 static_cast<uint64_t>(bytes_written
),
415 static_cast<uint64_t>(bytes_copied
));
424 NativeRegisterContext::ConvertRegisterKindToRegisterNumber(uint32_t kind
,
425 uint32_t num
) const {
426 const uint32_t num_regs
= GetRegisterCount();
428 assert(kind
< kNumRegisterKinds
);
429 for (uint32_t reg_idx
= 0; reg_idx
< num_regs
; ++reg_idx
) {
430 const RegisterInfo
*reg_info
= GetRegisterInfoAtIndex(reg_idx
);
432 if (reg_info
->kinds
[kind
] == num
)
436 return LLDB_INVALID_REGNUM
;
439 std::vector
<uint32_t>
440 NativeRegisterContext::GetExpeditedRegisters(ExpeditedRegs expType
) const {
441 if (expType
== ExpeditedRegs::Minimal
) {
442 // Expedite only a minimum set of important generic registers.
443 static const uint32_t k_expedited_registers
[] = {
444 LLDB_REGNUM_GENERIC_PC
, LLDB_REGNUM_GENERIC_SP
, LLDB_REGNUM_GENERIC_FP
,
445 LLDB_REGNUM_GENERIC_RA
};
447 std::vector
<uint32_t> expedited_reg_nums
;
448 for (uint32_t gen_reg
: k_expedited_registers
) {
450 ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric
, gen_reg
);
451 if (reg_num
== LLDB_INVALID_REGNUM
)
452 continue; // Target does not support the given register.
454 expedited_reg_nums
.push_back(reg_num
);
457 return expedited_reg_nums
;
460 if (GetRegisterSetCount() > 0 && expType
== ExpeditedRegs::Full
)
461 return std::vector
<uint32_t>(GetRegisterSet(0)->registers
,
462 GetRegisterSet(0)->registers
+
463 GetRegisterSet(0)->num_registers
);
465 return std::vector
<uint32_t>();