1 //===-- NativeRegisterContext.cpp -------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Host/common/NativeRegisterContext.h"
11
12 #include "lldb/Core/Log.h"
13 #include "lldb/Core/RegisterValue.h"
14
15 #include "lldb/Host/common/NativeProcessProtocol.h"
16 #include "lldb/Host/common/NativeThreadProtocol.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
NativeRegisterContext(NativeThreadProtocol & thread,uint32_t concrete_frame_idx)21 NativeRegisterContext::NativeRegisterContext (NativeThreadProtocol &thread, uint32_t concrete_frame_idx) :
22 m_thread (thread),
23 m_concrete_frame_idx (concrete_frame_idx)
24 {
25 }
26
27 //----------------------------------------------------------------------
28 // Destructor
29 //----------------------------------------------------------------------
~NativeRegisterContext()30 NativeRegisterContext::~NativeRegisterContext()
31 {
32 }
33
34 // FIXME revisit invalidation, process stop ids, etc. Right now we don't
35 // support caching in NativeRegisterContext. We can do this later by
36 // utilizing NativeProcessProtocol::GetStopID () and adding a stop id to
37 // NativeRegisterContext.
38
39 // void
40 // NativeRegisterContext::InvalidateIfNeeded (bool force)
41 // {
42 // ProcessSP process_sp (m_thread.GetProcess());
43 // bool invalidate = force;
44 // uint32_t process_stop_id = UINT32_MAX;
45
46 // if (process_sp)
47 // process_stop_id = process_sp->GetStopID();
48 // else
49 // invalidate = true;
50
51 // if (!invalidate)
52 // invalidate = process_stop_id != GetStopID();
53
54 // if (invalidate)
55 // {
56 // InvalidateAllRegisters ();
57 // SetStopID (process_stop_id);
58 // }
59 // }
60
61
62 const RegisterInfo *
GetRegisterInfoByName(const char * reg_name,uint32_t start_idx)63 NativeRegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
64 {
65 if (reg_name && reg_name[0])
66 {
67 const uint32_t num_registers = GetRegisterCount();
68 for (uint32_t reg = start_idx; reg < num_registers; ++reg)
69 {
70 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
71
72 if ((reg_info->name != nullptr && ::strcasecmp (reg_info->name, reg_name) == 0) ||
73 (reg_info->alt_name != nullptr && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
74 {
75 return reg_info;
76 }
77 }
78 }
79 return nullptr;
80 }
81
82 const RegisterInfo *
GetRegisterInfo(uint32_t kind,uint32_t num)83 NativeRegisterContext::GetRegisterInfo (uint32_t kind, uint32_t num)
84 {
85 const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
86 if (reg_num == LLDB_INVALID_REGNUM)
87 return nullptr;
88 return GetRegisterInfoAtIndex (reg_num);
89 }
90
91 const char *
GetRegisterName(uint32_t reg)92 NativeRegisterContext::GetRegisterName (uint32_t reg)
93 {
94 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
95 if (reg_info)
96 return reg_info->name;
97 return nullptr;
98 }
99
100 const char*
GetRegisterSetNameForRegisterAtIndex(uint32_t reg_index) const101 NativeRegisterContext::GetRegisterSetNameForRegisterAtIndex (uint32_t reg_index) const
102 {
103 const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
104 if (!reg_info)
105 return nullptr;
106
107 for (uint32_t set_index = 0; set_index < GetRegisterSetCount (); ++set_index)
108 {
109 const RegisterSet *const reg_set = GetRegisterSet (set_index);
110 if (!reg_set)
111 continue;
112
113 for (uint32_t reg_num_index = 0; reg_num_index < reg_set->num_registers; ++reg_num_index)
114 {
115 const uint32_t reg_num = reg_set->registers[reg_num_index];
116 // FIXME double check we're checking the right register kind here.
117 if (reg_info->kinds[RegisterKind::eRegisterKindLLDB] == reg_num)
118 {
119 // The given register is a member of this register set. Return the register set name.
120 return reg_set->name;
121 }
122 }
123 }
124
125 // Didn't find it.
126 return nullptr;
127 }
128
129 lldb::addr_t
GetPC(lldb::addr_t fail_value)130 NativeRegisterContext::GetPC (lldb::addr_t fail_value)
131 {
132 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
133
134 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
135 if (log)
136 log->Printf ("NativeRegisterContext::%s using reg index %" PRIu32 " (default %" PRIu64 ")", __FUNCTION__, reg, fail_value);
137
138 const uint64_t retval = ReadRegisterAsUnsigned (reg, fail_value);
139
140 if (log)
141 log->Printf ("NativeRegisterContext::%s " PRIu32 " retval %" PRIu64, __FUNCTION__, retval);
142
143 return retval;
144 }
145
146 lldb::addr_t
GetPCfromBreakpointLocation(lldb::addr_t fail_value)147 NativeRegisterContext::GetPCfromBreakpointLocation (lldb::addr_t fail_value)
148 {
149 return GetPC (fail_value);
150 }
151
152 Error
SetPC(lldb::addr_t pc)153 NativeRegisterContext::SetPC (lldb::addr_t pc)
154 {
155 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
156 return WriteRegisterFromUnsigned (reg, pc);
157 }
158
159 lldb::addr_t
GetSP(lldb::addr_t fail_value)160 NativeRegisterContext::GetSP (lldb::addr_t fail_value)
161 {
162 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
163 return ReadRegisterAsUnsigned (reg, fail_value);
164 }
165
166 Error
SetSP(lldb::addr_t sp)167 NativeRegisterContext::SetSP (lldb::addr_t sp)
168 {
169 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
170 return WriteRegisterFromUnsigned (reg, sp);
171 }
172
173 lldb::addr_t
GetFP(lldb::addr_t fail_value)174 NativeRegisterContext::GetFP (lldb::addr_t fail_value)
175 {
176 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
177 return ReadRegisterAsUnsigned (reg, fail_value);
178 }
179
180 Error
SetFP(lldb::addr_t fp)181 NativeRegisterContext::SetFP (lldb::addr_t fp)
182 {
183 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
184 return WriteRegisterFromUnsigned (reg, fp);
185 }
186
187 lldb::addr_t
GetReturnAddress(lldb::addr_t fail_value)188 NativeRegisterContext::GetReturnAddress (lldb::addr_t fail_value)
189 {
190 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
191 return ReadRegisterAsUnsigned (reg, fail_value);
192 }
193
194 lldb::addr_t
GetFlags(lldb::addr_t fail_value)195 NativeRegisterContext::GetFlags (lldb::addr_t fail_value)
196 {
197 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
198 return ReadRegisterAsUnsigned (reg, fail_value);
199 }
200
201
202 lldb::addr_t
ReadRegisterAsUnsigned(uint32_t reg,lldb::addr_t fail_value)203 NativeRegisterContext::ReadRegisterAsUnsigned (uint32_t reg, lldb::addr_t fail_value)
204 {
205 if (reg != LLDB_INVALID_REGNUM)
206 return ReadRegisterAsUnsigned (GetRegisterInfoAtIndex (reg), fail_value);
207 return fail_value;
208 }
209
210 uint64_t
ReadRegisterAsUnsigned(const RegisterInfo * reg_info,lldb::addr_t fail_value)211 NativeRegisterContext::ReadRegisterAsUnsigned (const RegisterInfo *reg_info, lldb::addr_t fail_value)
212 {
213 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
214
215 if (reg_info)
216 {
217 RegisterValue value;
218 Error error = ReadRegister (reg_info, value);
219 if (error.Success ())
220 {
221 if (log)
222 log->Printf ("NativeRegisterContext::%s ReadRegister() succeeded, value %" PRIu64, __FUNCTION__, value.GetAsUInt64());
223 return value.GetAsUInt64();
224 }
225 else
226 {
227 if (log)
228 log->Printf ("NativeRegisterContext::%s ReadRegister() failed, error %s", __FUNCTION__, error.AsCString ());
229 }
230 }
231 else
232 {
233 if (log)
234 log->Printf ("NativeRegisterContext::%s ReadRegister() null reg_info", __FUNCTION__);
235 }
236 return fail_value;
237 }
238
239 Error
WriteRegisterFromUnsigned(uint32_t reg,uint64_t uval)240 NativeRegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval)
241 {
242 if (reg == LLDB_INVALID_REGNUM)
243 return Error ("NativeRegisterContext::%s (): reg is invalid", __FUNCTION__);
244 return WriteRegisterFromUnsigned (GetRegisterInfoAtIndex (reg), uval);
245 }
246
247 Error
WriteRegisterFromUnsigned(const RegisterInfo * reg_info,uint64_t uval)248 NativeRegisterContext::WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval)
249 {
250 assert (reg_info);
251 if (!reg_info)
252 return Error ("reg_info is nullptr");
253
254 RegisterValue value;
255 if (!value.SetUInt(uval, reg_info->byte_size))
256 return Error ("RegisterValue::SetUInt () failed");
257
258 return WriteRegister (reg_info, value);
259 }
260
261 lldb::tid_t
GetThreadID() const262 NativeRegisterContext::GetThreadID() const
263 {
264 return m_thread.GetID();
265 }
266
267 uint32_t
NumSupportedHardwareBreakpoints()268 NativeRegisterContext::NumSupportedHardwareBreakpoints ()
269 {
270 return 0;
271 }
272
273 uint32_t
SetHardwareBreakpoint(lldb::addr_t addr,size_t size)274 NativeRegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
275 {
276 return LLDB_INVALID_INDEX32;
277 }
278
279 bool
ClearHardwareBreakpoint(uint32_t hw_idx)280 NativeRegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx)
281 {
282 return false;
283 }
284
285
286 uint32_t
NumSupportedHardwareWatchpoints()287 NativeRegisterContext::NumSupportedHardwareWatchpoints ()
288 {
289 return 0;
290 }
291
292 uint32_t
SetHardwareWatchpoint(lldb::addr_t addr,size_t size,uint32_t watch_flags)293 NativeRegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags)
294 {
295 return LLDB_INVALID_INDEX32;
296 }
297
298 bool
ClearHardwareWatchpoint(uint32_t hw_index)299 NativeRegisterContext::ClearHardwareWatchpoint (uint32_t hw_index)
300 {
301 return false;
302 }
303
304 Error
ClearAllHardwareWatchpoints()305 NativeRegisterContext::ClearAllHardwareWatchpoints ()
306 {
307 return Error ("not implemented");
308 }
309
310 Error
IsWatchpointHit(uint32_t wp_index,bool & is_hit)311 NativeRegisterContext::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
312 {
313 is_hit = false;
314 return Error ("not implemented");
315 }
316
317 Error
GetWatchpointHitIndex(uint32_t & wp_index,lldb::addr_t trap_addr)318 NativeRegisterContext::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
319 {
320 wp_index = LLDB_INVALID_INDEX32;
321 return Error ("not implemented");
322 }
323
324 Error
IsWatchpointVacant(uint32_t wp_index,bool & is_vacant)325 NativeRegisterContext::IsWatchpointVacant (uint32_t wp_index, bool &is_vacant)
326 {
327 is_vacant = false;
328 return Error ("not implemented");
329 }
330
331 lldb::addr_t
GetWatchpointAddress(uint32_t wp_index)332 NativeRegisterContext::GetWatchpointAddress (uint32_t wp_index)
333 {
334 return LLDB_INVALID_ADDRESS;
335 }
336
337 lldb::addr_t
GetWatchpointHitAddress(uint32_t wp_index)338 NativeRegisterContext::GetWatchpointHitAddress (uint32_t wp_index)
339 {
340 return LLDB_INVALID_ADDRESS;
341 }
342
343 bool
HardwareSingleStep(bool enable)344 NativeRegisterContext::HardwareSingleStep (bool enable)
345 {
346 return false;
347 }
348
349 Error
ReadRegisterValueFromMemory(const RegisterInfo * reg_info,lldb::addr_t src_addr,size_t src_len,RegisterValue & reg_value)350 NativeRegisterContext::ReadRegisterValueFromMemory (
351 const RegisterInfo *reg_info,
352 lldb::addr_t src_addr,
353 size_t src_len,
354 RegisterValue ®_value)
355 {
356 Error error;
357 if (reg_info == nullptr)
358 {
359 error.SetErrorString ("invalid register info argument.");
360 return error;
361 }
362
363
364 // Moving from addr into a register
365 //
366 // Case 1: src_len == dst_len
367 //
368 // |AABBCCDD| Address contents
369 // |AABBCCDD| Register contents
370 //
371 // Case 2: src_len > dst_len
372 //
373 // Error! (The register should always be big enough to hold the data)
374 //
375 // Case 3: src_len < dst_len
376 //
377 // |AABB| Address contents
378 // |AABB0000| Register contents [on little-endian hardware]
379 // |0000AABB| Register contents [on big-endian hardware]
380 if (src_len > RegisterValue::kMaxRegisterByteSize)
381 {
382 error.SetErrorString ("register too small to receive memory data");
383 return error;
384 }
385
386 const size_t dst_len = reg_info->byte_size;
387
388 if (src_len > dst_len)
389 {
390 error.SetErrorStringWithFormat("%" PRIu64 " bytes is too big to store in register %s (%" PRIu64 " bytes)",
391 static_cast<uint64_t>(src_len), reg_info->name, static_cast<uint64_t>(dst_len));
392 return error;
393 }
394
395 NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
396 if (!process_sp)
397 {
398 error.SetErrorString("invalid process");
399 return error;
400 }
401
402 uint8_t src[RegisterValue::kMaxRegisterByteSize];
403
404 // Read the memory
405 size_t bytes_read;
406 error = process_sp->ReadMemory (src_addr, src, src_len, bytes_read);
407 if (error.Fail ())
408 return error;
409
410 // Make sure the memory read succeeded...
411 if (bytes_read != src_len)
412 {
413 // This might happen if we read _some_ bytes but not all
414 error.SetErrorStringWithFormat("read %" PRIu64 " of %" PRIu64 " bytes",
415 static_cast<uint64_t>(bytes_read), static_cast<uint64_t>(src_len));
416 return error;
417 }
418
419 // We now have a memory buffer that contains the part or all of the register
420 // value. Set the register value using this memory data.
421 // TODO: we might need to add a parameter to this function in case the byte
422 // order of the memory data doesn't match the process. For now we are assuming
423 // they are the same.
424 lldb::ByteOrder byte_order;
425 if (!process_sp->GetByteOrder (byte_order))
426 {
427 error.SetErrorString ( "NativeProcessProtocol::GetByteOrder () failed");
428 return error;
429 }
430
431 reg_value.SetFromMemoryData (
432 reg_info,
433 src,
434 src_len,
435 byte_order,
436 error);
437
438 return error;
439 }
440
441 Error
WriteRegisterValueToMemory(const RegisterInfo * reg_info,lldb::addr_t dst_addr,size_t dst_len,const RegisterValue & reg_value)442 NativeRegisterContext::WriteRegisterValueToMemory (
443 const RegisterInfo *reg_info,
444 lldb::addr_t dst_addr,
445 size_t dst_len,
446 const RegisterValue ®_value)
447 {
448
449 uint8_t dst[RegisterValue::kMaxRegisterByteSize];
450
451 Error error;
452
453 NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
454 if (process_sp)
455 {
456
457 // TODO: we might need to add a parameter to this function in case the byte
458 // order of the memory data doesn't match the process. For now we are assuming
459 // they are the same.
460 lldb::ByteOrder byte_order;
461 if (!process_sp->GetByteOrder (byte_order))
462 return Error ("NativeProcessProtocol::GetByteOrder () failed");
463
464 const size_t bytes_copied = reg_value.GetAsMemoryData (
465 reg_info,
466 dst,
467 dst_len,
468 byte_order,
469 error);
470
471 if (error.Success())
472 {
473 if (bytes_copied == 0)
474 {
475 error.SetErrorString("byte copy failed.");
476 }
477 else
478 {
479 size_t bytes_written;
480 error = process_sp->WriteMemory(dst_addr, dst, bytes_copied, bytes_written);
481 if (error.Fail ())
482 return error;
483
484 if (bytes_written != bytes_copied)
485 {
486 // This might happen if we read _some_ bytes but not all
487 error.SetErrorStringWithFormat("only wrote %" PRIu64 " of %" PRIu64 " bytes",
488 static_cast<uint64_t>(bytes_written), static_cast<uint64_t>(bytes_copied));
489 }
490 }
491 }
492 }
493 else
494 error.SetErrorString("invalid process");
495
496 return error;
497 }
498
499 uint32_t
ConvertRegisterKindToRegisterNumber(uint32_t kind,uint32_t num) const500 NativeRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
501 {
502 const uint32_t num_regs = GetRegisterCount();
503
504 assert (kind < kNumRegisterKinds);
505 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
506 {
507 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
508
509 if (reg_info->kinds[kind] == num)
510 return reg_idx;
511 }
512
513 return LLDB_INVALID_REGNUM;
514 }
515
516
517