1 //===-- NativeRegisterContextLinux_arm.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 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
11 
12 #include "NativeRegisterContextLinux_arm.h"
13 
14 #include "lldb/Core/DataBufferHeap.h"
15 #include "lldb/Core/Error.h"
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/RegisterValue.h"
18 
19 #include "Plugins/Process/Linux/Procfs.h"
20 #include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
21 
22 #include <elf.h>
23 #include <sys/socket.h>
24 
25 #define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))
26 
27 #ifndef PTRACE_GETVFPREGS
28   #define PTRACE_GETVFPREGS 27
29   #define PTRACE_SETVFPREGS 28
30 #endif
31 #ifndef PTRACE_GETHBPREGS
32   #define PTRACE_GETHBPREGS 29
33   #define PTRACE_SETHBPREGS 30
34 #endif
35 #if !defined(PTRACE_TYPE_ARG3)
36   #define PTRACE_TYPE_ARG3 void *
37 #endif
38 #if !defined(PTRACE_TYPE_ARG4)
39   #define PTRACE_TYPE_ARG4 void *
40 #endif
41 
42 using namespace lldb;
43 using namespace lldb_private;
44 using namespace lldb_private::process_linux;
45 
46 // arm general purpose registers.
47 static const uint32_t g_gpr_regnums_arm[] =
48 {
49     gpr_r0_arm,
50     gpr_r1_arm,
51     gpr_r2_arm,
52     gpr_r3_arm,
53     gpr_r4_arm,
54     gpr_r5_arm,
55     gpr_r6_arm,
56     gpr_r7_arm,
57     gpr_r8_arm,
58     gpr_r9_arm,
59     gpr_r10_arm,
60     gpr_r11_arm,
61     gpr_r12_arm,
62     gpr_sp_arm,
63     gpr_lr_arm,
64     gpr_pc_arm,
65     gpr_cpsr_arm,
66     LLDB_INVALID_REGNUM // register sets need to end with this flag
67 };
68 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
69               "g_gpr_regnums_arm has wrong number of register infos");
70 
71 // arm floating point registers.
72 static const uint32_t g_fpu_regnums_arm[] =
73 {
74     fpu_s0_arm,
75     fpu_s1_arm,
76     fpu_s2_arm,
77     fpu_s3_arm,
78     fpu_s4_arm,
79     fpu_s5_arm,
80     fpu_s6_arm,
81     fpu_s7_arm,
82     fpu_s8_arm,
83     fpu_s9_arm,
84     fpu_s10_arm,
85     fpu_s11_arm,
86     fpu_s12_arm,
87     fpu_s13_arm,
88     fpu_s14_arm,
89     fpu_s15_arm,
90     fpu_s16_arm,
91     fpu_s17_arm,
92     fpu_s18_arm,
93     fpu_s19_arm,
94     fpu_s20_arm,
95     fpu_s21_arm,
96     fpu_s22_arm,
97     fpu_s23_arm,
98     fpu_s24_arm,
99     fpu_s25_arm,
100     fpu_s26_arm,
101     fpu_s27_arm,
102     fpu_s28_arm,
103     fpu_s29_arm,
104     fpu_s30_arm,
105     fpu_s31_arm,
106     fpu_fpscr_arm,
107     fpu_d0_arm,
108     fpu_d1_arm,
109     fpu_d2_arm,
110     fpu_d3_arm,
111     fpu_d4_arm,
112     fpu_d5_arm,
113     fpu_d6_arm,
114     fpu_d7_arm,
115     fpu_d8_arm,
116     fpu_d9_arm,
117     fpu_d10_arm,
118     fpu_d11_arm,
119     fpu_d12_arm,
120     fpu_d13_arm,
121     fpu_d14_arm,
122     fpu_d15_arm,
123     fpu_d16_arm,
124     fpu_d17_arm,
125     fpu_d18_arm,
126     fpu_d19_arm,
127     fpu_d20_arm,
128     fpu_d21_arm,
129     fpu_d22_arm,
130     fpu_d23_arm,
131     fpu_d24_arm,
132     fpu_d25_arm,
133     fpu_d26_arm,
134     fpu_d27_arm,
135     fpu_d28_arm,
136     fpu_d29_arm,
137     fpu_d30_arm,
138     fpu_d31_arm,
139     fpu_q0_arm,
140     fpu_q1_arm,
141     fpu_q2_arm,
142     fpu_q3_arm,
143     fpu_q4_arm,
144     fpu_q5_arm,
145     fpu_q6_arm,
146     fpu_q7_arm,
147     fpu_q8_arm,
148     fpu_q9_arm,
149     fpu_q10_arm,
150     fpu_q11_arm,
151     fpu_q12_arm,
152     fpu_q13_arm,
153     fpu_q14_arm,
154     fpu_q15_arm,
155     LLDB_INVALID_REGNUM // register sets need to end with this flag
156 };
157 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
158               "g_fpu_regnums_arm has wrong number of register infos");
159 
160 namespace {
161     // Number of register sets provided by this context.
162     enum
163     {
164         k_num_register_sets = 2
165     };
166 }
167 
168 // Register sets for arm.
169 static const RegisterSet
170 g_reg_sets_arm[k_num_register_sets] =
171 {
172     { "General Purpose Registers",  "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
173     { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
174 };
175 
176 #if defined(__arm__)
177 
178 NativeRegisterContextLinux*
179 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
180                                                                  NativeThreadProtocol &native_thread,
181                                                                  uint32_t concrete_frame_idx)
182 {
183     return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx);
184 }
185 
186 #endif // defined(__arm__)
187 
188 NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (const ArchSpec& target_arch,
189                                                                 NativeThreadProtocol &native_thread,
190                                                                 uint32_t concrete_frame_idx) :
191     NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm(target_arch))
192 {
193     switch (target_arch.GetMachine())
194     {
195         case llvm::Triple::arm:
196             m_reg_info.num_registers     = k_num_registers_arm;
197             m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
198             m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
199             m_reg_info.last_gpr          = k_last_gpr_arm;
200             m_reg_info.first_fpr         = k_first_fpr_arm;
201             m_reg_info.last_fpr          = k_last_fpr_arm;
202             m_reg_info.first_fpr_v       = fpu_s0_arm;
203             m_reg_info.last_fpr_v        = fpu_s31_arm;
204             m_reg_info.gpr_flags         = gpr_cpsr_arm;
205             break;
206         default:
207             assert(false && "Unhandled target architecture.");
208             break;
209     }
210 
211     ::memset(&m_fpr, 0, sizeof (m_fpr));
212     ::memset(&m_gpr_arm, 0, sizeof (m_gpr_arm));
213     ::memset(&m_hwp_regs, 0, sizeof (m_hwp_regs));
214 
215     // 16 is just a maximum value, query hardware for actual watchpoint count
216     m_max_hwp_supported = 16;
217     m_max_hbp_supported = 16;
218     m_refresh_hwdebug_info = true;
219 }
220 
221 uint32_t
222 NativeRegisterContextLinux_arm::GetRegisterSetCount () const
223 {
224     return k_num_register_sets;
225 }
226 
227 uint32_t
228 NativeRegisterContextLinux_arm::GetUserRegisterCount() const
229 {
230     uint32_t count = 0;
231     for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
232         count += g_reg_sets_arm[set_index].num_registers;
233     return count;
234 }
235 
236 const RegisterSet *
237 NativeRegisterContextLinux_arm::GetRegisterSet (uint32_t set_index) const
238 {
239     if (set_index < k_num_register_sets)
240         return &g_reg_sets_arm[set_index];
241 
242     return nullptr;
243 }
244 
245 Error
246 NativeRegisterContextLinux_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
247 {
248     Error error;
249 
250     if (!reg_info)
251     {
252         error.SetErrorString ("reg_info NULL");
253         return error;
254     }
255 
256     const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
257 
258     if (IsFPR(reg))
259     {
260         error = ReadFPR();
261         if (error.Fail())
262             return error;
263     }
264     else
265     {
266         uint32_t full_reg = reg;
267         bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
268 
269         if (is_subreg)
270         {
271             // Read the full aligned 64-bit register.
272             full_reg = reg_info->invalidate_regs[0];
273         }
274 
275         error = ReadRegisterRaw(full_reg, reg_value);
276 
277         if (error.Success ())
278         {
279             // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
280             if (is_subreg && (reg_info->byte_offset & 0x1))
281                 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
282 
283             // If our return byte size was greater than the return value reg size, then
284             // use the type specified by reg_info rather than the uint64_t default
285             if (reg_value.GetByteSize() > reg_info->byte_size)
286                 reg_value.SetType(reg_info);
287         }
288         return error;
289     }
290 
291     // Get pointer to m_fpr variable and set the data from it.
292     uint32_t fpr_offset = CalculateFprOffset(reg_info);
293     assert (fpr_offset < sizeof m_fpr);
294     uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
295     switch (reg_info->byte_size)
296     {
297         case 2:
298             reg_value.SetUInt16(*(uint16_t *)src);
299             break;
300         case 4:
301             reg_value.SetUInt32(*(uint32_t *)src);
302             break;
303         case 8:
304             reg_value.SetUInt64(*(uint64_t *)src);
305             break;
306         case 16:
307             reg_value.SetBytes(src, 16, GetByteOrder());
308             break;
309         default:
310             assert(false && "Unhandled data size.");
311             error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size);
312             break;
313     }
314 
315     return error;
316 }
317 
318 Error
319 NativeRegisterContextLinux_arm::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
320 {
321     if (!reg_info)
322         return Error ("reg_info NULL");
323 
324     const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
325     if (reg_index == LLDB_INVALID_REGNUM)
326         return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>");
327 
328     if (IsGPR(reg_index))
329         return WriteRegisterRaw(reg_index, reg_value);
330 
331     if (IsFPR(reg_index))
332     {
333         // Get pointer to m_fpr variable and set the data to it.
334         uint32_t fpr_offset = CalculateFprOffset(reg_info);
335         assert (fpr_offset < sizeof m_fpr);
336         uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
337         switch (reg_info->byte_size)
338         {
339             case 2:
340                 *(uint16_t *)dst = reg_value.GetAsUInt16();
341                 break;
342             case 4:
343                 *(uint32_t *)dst = reg_value.GetAsUInt32();
344                 break;
345             case 8:
346                 *(uint64_t *)dst = reg_value.GetAsUInt64();
347                 break;
348             default:
349                 assert(false && "Unhandled data size.");
350                 return Error ("unhandled register data size %" PRIu32, reg_info->byte_size);
351         }
352 
353         Error error = WriteFPR();
354         if (error.Fail())
355             return error;
356 
357         return Error ();
358     }
359 
360     return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown");
361 }
362 
363 Error
364 NativeRegisterContextLinux_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
365 {
366     Error error;
367 
368     data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
369     if (!data_sp)
370         return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, (uint64_t)REG_CONTEXT_SIZE);
371 
372     error = ReadGPR();
373     if (error.Fail())
374         return error;
375 
376     error = ReadFPR();
377     if (error.Fail())
378         return error;
379 
380     uint8_t *dst = data_sp->GetBytes ();
381     if (dst == nullptr)
382     {
383         error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", (uint64_t)REG_CONTEXT_SIZE);
384         return error;
385     }
386 
387     ::memcpy (dst, &m_gpr_arm, GetGPRSize());
388     dst += GetGPRSize();
389     ::memcpy (dst, &m_fpr, sizeof(m_fpr));
390 
391     return error;
392 }
393 
394 Error
395 NativeRegisterContextLinux_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
396 {
397     Error error;
398 
399     if (!data_sp)
400     {
401         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__);
402         return error;
403     }
404 
405     if (data_sp->GetByteSize () != REG_CONTEXT_SIZE)
406     {
407         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize ());
408         return error;
409     }
410 
411 
412     uint8_t *src = data_sp->GetBytes ();
413     if (src == nullptr)
414     {
415         error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__);
416         return error;
417     }
418     ::memcpy (&m_gpr_arm, src, GetRegisterInfoInterface ().GetGPRSize ());
419 
420     error = WriteGPR();
421     if (error.Fail())
422         return error;
423 
424     src += GetRegisterInfoInterface ().GetGPRSize ();
425     ::memcpy (&m_fpr, src, sizeof(m_fpr));
426 
427     error = WriteFPR();
428     if (error.Fail())
429         return error;
430 
431     return error;
432 }
433 
434 bool
435 NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const
436 {
437     return reg <= m_reg_info.last_gpr;   // GPR's come first.
438 }
439 
440 bool
441 NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const
442 {
443     return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
444 }
445 
446 uint32_t
447 NativeRegisterContextLinux_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
448 {
449     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
450 
451     if (log)
452         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
453 
454     Error error;
455 
456     // Read hardware breakpoint and watchpoint information.
457     error = ReadHardwareDebugInfo ();
458 
459     if (error.Fail())
460         return LLDB_INVALID_INDEX32;
461 
462     uint32_t control_value = 0, bp_index = 0;
463 
464     // Check if size has a valid hardware breakpoint length.
465     // Thumb instructions are 2-bytes but we have no way here to determine
466     // if target address is a thumb or arm instruction.
467     // TODO: Add support for setting thumb mode hardware breakpoints
468     if (size != 4 && size != 2)
469         return LLDB_INVALID_INDEX32;
470 
471     // Setup control value
472     // Make the byte_mask into a valid Byte Address Select mask
473     control_value = 0xfu << 5;
474 
475     // Enable this breakpoint and make it stop in privileged or user mode;
476     control_value |= 7;
477 
478     // Make sure bits 1:0 are clear in our address
479     // This should be different once we support thumb here.
480     addr &= ~((lldb::addr_t)3);
481 
482     // Iterate over stored hardware breakpoints
483     // Find a free bp_index or update reference count if duplicate.
484     bp_index = LLDB_INVALID_INDEX32;
485 
486     for (uint32_t i = 0; i < m_max_hbp_supported; i++)
487     {
488         if ((m_hbr_regs[i].control & 1) == 0)
489         {
490             bp_index = i;  // Mark last free slot
491         }
492         else if (m_hbr_regs[i].address == addr && m_hbr_regs[i].control == control_value)
493         {
494             bp_index = i;  // Mark duplicate index
495             break;  // Stop searching here
496         }
497     }
498 
499      if (bp_index == LLDB_INVALID_INDEX32)
500          return LLDB_INVALID_INDEX32;
501 
502     // Add new or update existing breakpoint
503     if ((m_hbr_regs[bp_index].control & 1) == 0)
504     {
505         m_hbr_regs[bp_index].address = addr;
506         m_hbr_regs[bp_index].control = control_value;
507         m_hbr_regs[bp_index].refcount = 1;
508 
509         // PTRACE call to set corresponding hardware breakpoint register.
510         error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index);
511 
512         if (error.Fail())
513         {
514             m_hbr_regs[bp_index].address = 0;
515             m_hbr_regs[bp_index].control &= ~1;
516             m_hbr_regs[bp_index].refcount = 0;
517 
518             return LLDB_INVALID_INDEX32;
519         }
520     }
521     else
522         m_hbr_regs[bp_index].refcount++;
523 
524     return bp_index;
525 }
526 
527 bool
528 NativeRegisterContextLinux_arm::ClearHardwareBreakpoint (uint32_t hw_idx)
529 {
530     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
531 
532     if (log)
533         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
534 
535     Error error;
536 
537     // Read hardware breakpoint and watchpoint information.
538     error = ReadHardwareDebugInfo ();
539 
540     if (error.Fail())
541         return false;
542 
543     if (hw_idx >= m_max_hbp_supported)
544         return false;
545 
546     // Update reference count if multiple references.
547     if (m_hbr_regs[hw_idx].refcount > 1)
548     {
549         m_hbr_regs[hw_idx].refcount--;
550         return true;
551     }
552     else if (m_hbr_regs[hw_idx].refcount == 1)
553     {
554         // Create a backup we can revert to in case of failure.
555         lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
556         uint32_t tempControl = m_hbr_regs[hw_idx].control;
557         uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
558 
559         m_hbr_regs[hw_idx].control &= ~1;
560         m_hbr_regs[hw_idx].address = 0;
561         m_hbr_regs[hw_idx].refcount = 0;
562 
563         // PTRACE call to clear corresponding hardware breakpoint register.
564         WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
565 
566         if (error.Fail())
567         {
568             m_hbr_regs[hw_idx].control = tempControl;
569             m_hbr_regs[hw_idx].address = tempAddr;
570             m_hbr_regs[hw_idx].refcount = tempRefCount;
571 
572             return false;
573         }
574 
575         return true;
576     }
577 
578     return false;
579 }
580 
581 uint32_t
582 NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints ()
583 {
584     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
585 
586     if (log)
587         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
588 
589     Error error;
590 
591     // Read hardware breakpoint and watchpoint information.
592     error = ReadHardwareDebugInfo ();
593 
594     if (error.Fail())
595         return 0;
596 
597     return m_max_hwp_supported;
598 }
599 
600 uint32_t
601 NativeRegisterContextLinux_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags)
602 {
603     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
604 
605     if (log)
606         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
607 
608     Error error;
609 
610     // Read hardware breakpoint and watchpoint information.
611     error = ReadHardwareDebugInfo ();
612 
613     if (error.Fail())
614         return LLDB_INVALID_INDEX32;
615 
616     uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
617     lldb::addr_t real_addr = addr;
618 
619     // Check if we are setting watchpoint other than read/write/access
620     // Also update watchpoint flag to match Arm write-read bit configuration.
621     switch (watch_flags)
622     {
623         case 1:
624             watch_flags = 2;
625             break;
626         case 2:
627             watch_flags = 1;
628             break;
629         case 3:
630             break;
631         default:
632             return LLDB_INVALID_INDEX32;
633     }
634 
635     // Can't watch zero bytes
636     // Can't watch more than 4 bytes per WVR/WCR pair
637 
638     if (size == 0 || size > 4)
639         return LLDB_INVALID_INDEX32;
640 
641     // Check 4-byte alignment for hardware watchpoint target address.
642     // Below is a hack to recalculate address and size in order to
643     // make sure we can watch non 4-byte alligned addresses as well.
644     if (addr & 0x03)
645     {
646         uint8_t watch_mask = (addr & 0x03) + size;
647 
648         if (watch_mask > 0x04)
649             return LLDB_INVALID_INDEX32;
650         else if (watch_mask <= 0x02)
651             size = 2;
652         else if (watch_mask <= 0x04)
653             size = 4;
654 
655         addr = addr & (~0x03);
656     }
657 
658 	// We can only watch up to four bytes that follow a 4 byte aligned address
659     // per watchpoint register pair, so make sure we can properly encode this.
660     addr_word_offset = addr % 4;
661     byte_mask = ((1u << size) - 1u) << addr_word_offset;
662 
663     // Check if we need multiple watchpoint register
664     if (byte_mask > 0xfu)
665         return LLDB_INVALID_INDEX32;
666 
667     // Setup control value
668     // Make the byte_mask into a valid Byte Address Select mask
669     control_value = byte_mask << 5;
670 
671     //Turn on appropriate watchpoint flags read or write
672     control_value |= (watch_flags << 3);
673 
674     // Enable this watchpoint and make it stop in privileged or user mode;
675     control_value |= 7;
676 
677     // Make sure bits 1:0 are clear in our address
678     addr &= ~((lldb::addr_t)3);
679 
680     // Iterate over stored watchpoints
681     // Find a free wp_index or update reference count if duplicate.
682     wp_index = LLDB_INVALID_INDEX32;
683     for (uint32_t i = 0; i < m_max_hwp_supported; i++)
684     {
685         if ((m_hwp_regs[i].control & 1) == 0)
686         {
687             wp_index = i; // Mark last free slot
688         }
689         else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value)
690         {
691             wp_index = i; // Mark duplicate index
692             break; // Stop searching here
693         }
694     }
695 
696      if (wp_index == LLDB_INVALID_INDEX32)
697         return LLDB_INVALID_INDEX32;
698 
699     // Add new or update existing watchpoint
700     if ((m_hwp_regs[wp_index].control & 1) == 0)
701     {
702         // Update watchpoint in local cache
703         m_hwp_regs[wp_index].real_addr = real_addr;
704         m_hwp_regs[wp_index].address = addr;
705         m_hwp_regs[wp_index].control = control_value;
706         m_hwp_regs[wp_index].refcount = 1;
707 
708         // PTRACE call to set corresponding watchpoint register.
709         error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
710 
711         if (error.Fail())
712         {
713             m_hwp_regs[wp_index].address = 0;
714             m_hwp_regs[wp_index].control &= ~1;
715             m_hwp_regs[wp_index].refcount = 0;
716 
717             return LLDB_INVALID_INDEX32;
718         }
719     }
720     else
721         m_hwp_regs[wp_index].refcount++;
722 
723     return wp_index;
724 }
725 
726 bool
727 NativeRegisterContextLinux_arm::ClearHardwareWatchpoint (uint32_t wp_index)
728 {
729     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
730 
731     if (log)
732         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
733 
734     Error error;
735 
736     // Read hardware breakpoint and watchpoint information.
737     error = ReadHardwareDebugInfo ();
738 
739     if (error.Fail())
740         return false;
741 
742     if (wp_index >= m_max_hwp_supported)
743         return false;
744 
745     // Update reference count if multiple references.
746     if (m_hwp_regs[wp_index].refcount > 1)
747     {
748         m_hwp_regs[wp_index].refcount--;
749         return true;
750     }
751     else if (m_hwp_regs[wp_index].refcount == 1)
752     {
753         // Create a backup we can revert to in case of failure.
754         lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
755         uint32_t tempControl = m_hwp_regs[wp_index].control;
756         uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
757 
758         // Update watchpoint in local cache
759         m_hwp_regs[wp_index].control &= ~1;
760         m_hwp_regs[wp_index].address = 0;
761         m_hwp_regs[wp_index].refcount = 0;
762 
763         // Ptrace call to update hardware debug registers
764         error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
765 
766         if (error.Fail())
767         {
768             m_hwp_regs[wp_index].control = tempControl;
769             m_hwp_regs[wp_index].address = tempAddr;
770             m_hwp_regs[wp_index].refcount = tempRefCount;
771 
772             return false;
773         }
774 
775         return true;
776     }
777 
778     return false;
779 }
780 
781 Error
782 NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints ()
783 {
784     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
785 
786     if (log)
787         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
788 
789     Error error;
790 
791     // Read hardware breakpoint and watchpoint information.
792     error = ReadHardwareDebugInfo ();
793 
794     if (error.Fail())
795         return error;
796 
797     lldb::addr_t tempAddr = 0;
798     uint32_t tempControl = 0, tempRefCount = 0;
799 
800     for (uint32_t i = 0; i < m_max_hwp_supported; i++)
801     {
802         if (m_hwp_regs[i].control & 0x01)
803         {
804             // Create a backup we can revert to in case of failure.
805             tempAddr = m_hwp_regs[i].address;
806             tempControl = m_hwp_regs[i].control;
807             tempRefCount = m_hwp_regs[i].refcount;
808 
809             // Clear watchpoints in local cache
810             m_hwp_regs[i].control &= ~1;
811             m_hwp_regs[i].address = 0;
812             m_hwp_regs[i].refcount = 0;
813 
814             // Ptrace call to update hardware debug registers
815             error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
816 
817             if (error.Fail())
818             {
819                 m_hwp_regs[i].control = tempControl;
820                 m_hwp_regs[i].address = tempAddr;
821                 m_hwp_regs[i].refcount = tempRefCount;
822 
823                 return error;
824             }
825         }
826     }
827 
828     return Error();
829 }
830 
831 uint32_t
832 NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index)
833 {
834     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
835 
836     if (log)
837         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
838 
839     switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f)
840     {
841         case 0x01:
842             return 1;
843         case 0x03:
844             return 2;
845         case 0x07:
846             return 3;
847         case 0x0f:
848             return 4;
849         default:
850             return 0;
851     }
852 }
853 bool
854 NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index)
855 {
856     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
857 
858     if (log)
859         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
860 
861     if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
862         return true;
863     else
864         return false;
865 }
866 
867 Error
868 NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
869 {
870     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
871 
872     if (log)
873         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
874 
875     uint32_t watch_size;
876     lldb::addr_t watch_addr;
877 
878     for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index)
879     {
880         watch_size = GetWatchpointSize (wp_index);
881         watch_addr = m_hwp_regs[wp_index].address;
882 
883         if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
884             && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
885         {
886             m_hwp_regs[wp_index].hit_addr = trap_addr;
887             return Error();
888         }
889     }
890 
891     wp_index = LLDB_INVALID_INDEX32;
892     return Error();
893 }
894 
895 lldb::addr_t
896 NativeRegisterContextLinux_arm::GetWatchpointAddress (uint32_t wp_index)
897 {
898     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
899 
900     if (log)
901         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
902 
903     if (wp_index >= m_max_hwp_supported)
904         return LLDB_INVALID_ADDRESS;
905 
906     if (WatchpointIsEnabled(wp_index))
907         return m_hwp_regs[wp_index].real_addr;
908     else
909         return LLDB_INVALID_ADDRESS;
910 }
911 
912 lldb::addr_t
913 NativeRegisterContextLinux_arm::GetWatchpointHitAddress (uint32_t wp_index)
914 {
915     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
916 
917     if (log)
918         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
919 
920     if (wp_index >= m_max_hwp_supported)
921         return LLDB_INVALID_ADDRESS;
922 
923     if (WatchpointIsEnabled(wp_index))
924         return m_hwp_regs[wp_index].hit_addr;
925     else
926         return LLDB_INVALID_ADDRESS;
927 }
928 
929 Error
930 NativeRegisterContextLinux_arm::ReadHardwareDebugInfo()
931 {
932     Error error;
933 
934     if (!m_refresh_hwdebug_info)
935     {
936         return Error();
937     }
938 
939     unsigned int cap_val;
940 
941     error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), nullptr, &cap_val, sizeof(unsigned int));
942 
943     if (error.Fail())
944         return error;
945 
946     m_max_hwp_supported = (cap_val >> 8) & 0xff;
947     m_max_hbp_supported = cap_val & 0xff;
948     m_refresh_hwdebug_info = false;
949 
950     return error;
951 }
952 
953 Error
954 NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_index)
955 {
956     Error error;
957 
958     lldb::addr_t *addr_buf;
959     uint32_t *ctrl_buf;
960 
961     if (hwbType == eDREGTypeWATCH)
962     {
963         addr_buf = &m_hwp_regs[hwb_index].address;
964         ctrl_buf = &m_hwp_regs[hwb_index].control;
965 
966         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
967                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 1),
968                 addr_buf, sizeof(unsigned int));
969 
970         if (error.Fail())
971             return error;
972 
973         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
974                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 2),
975                 ctrl_buf, sizeof(unsigned int));
976     }
977     else
978     {
979         addr_buf = &m_hwp_regs[hwb_index].address;
980         ctrl_buf = &m_hwp_regs[hwb_index].control;
981 
982         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
983                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 1),
984                 addr_buf, sizeof(unsigned int));
985 
986         if (error.Fail())
987             return error;
988 
989         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
990                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 2),
991                 ctrl_buf, sizeof(unsigned int));
992 
993     }
994 
995     return error;
996 }
997 
998 uint32_t
999 NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info) const
1000 {
1001     return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
1002 }
1003 
1004 Error
1005 NativeRegisterContextLinux_arm::DoReadRegisterValue(uint32_t offset,
1006                                                     const char* reg_name,
1007                                                     uint32_t size,
1008                                                     RegisterValue &value)
1009 {
1010     // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android devices (always return
1011     // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR register set instead.
1012     // This approach is about 4 times slower but the performance overhead is negligible in
1013     // comparision to processing time in lldb-server.
1014     assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
1015     if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
1016         return Error("Register isn't fit into the size of the GPR area");
1017 
1018     Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
1019     if (error.Fail())
1020         return error;
1021 
1022     value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
1023     return Error();
1024 }
1025 
1026 Error
1027 NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset,
1028                                                      const char* reg_name,
1029                                                      const RegisterValue &value)
1030 {
1031     // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android devices (always return
1032     // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify
1033     // the requested register and write it back. This approach is about 4 times slower but the
1034     // performance overhead is negligible in comparision to processing time in lldb-server.
1035     assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
1036     if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
1037         return Error("Register isn't fit into the size of the GPR area");
1038 
1039     Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
1040     if (error.Fail())
1041         return error;
1042 
1043     uint32_t reg_value = value.GetAsUInt32();
1044     // As precaution for an undefined behavior encountered while setting PC we
1045     // will clear thumb bit of new PC if we are already in thumb mode; that is
1046     // CPSR thumb mode bit is set.
1047     if (offset / sizeof(uint32_t) == gpr_pc_arm)
1048     {
1049         // Check if we are already in thumb mode and
1050         // thumb bit of current PC is read out to be zero and
1051         // thumb bit of next PC is read out to be one.
1052         if ((m_gpr_arm[gpr_cpsr_arm] &  0x20) &&
1053             !(m_gpr_arm[gpr_pc_arm] &  0x01) &&
1054             (value.GetAsUInt32() & 0x01))
1055         {
1056             reg_value &= (~1ull);
1057         }
1058     }
1059 
1060     m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
1061     return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
1062 }
1063 
1064 Error
1065 NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size)
1066 {
1067 #ifdef __arm__
1068     return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
1069 #else // __aarch64__
1070     struct iovec ioVec;
1071     ioVec.iov_base = buf;
1072     ioVec.iov_len = buf_size;
1073 
1074     return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
1075 #endif // __arm__
1076 }
1077 
1078 Error
1079 NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size)
1080 {
1081 #ifdef __arm__
1082     return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
1083 #else // __aarch64__
1084     struct iovec ioVec;
1085     ioVec.iov_base = buf;
1086     ioVec.iov_len = buf_size;
1087 
1088     return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
1089 #endif // __arm__
1090 }
1091 
1092 Error
1093 NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size)
1094 {
1095 #ifdef __arm__
1096     return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS,
1097                                              m_thread.GetID(),
1098                                              nullptr,
1099                                              buf,
1100                                              buf_size);
1101 #else // __aarch64__
1102     struct iovec ioVec;
1103     ioVec.iov_base = buf;
1104     ioVec.iov_len = buf_size;
1105 
1106     return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
1107 #endif // __arm__
1108 }
1109 
1110 Error
1111 NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size)
1112 {
1113 #ifdef __arm__
1114     return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS,
1115                                              m_thread.GetID(),
1116                                              nullptr,
1117                                              buf,
1118                                              buf_size);
1119 #else // __aarch64__
1120     struct iovec ioVec;
1121     ioVec.iov_base = buf;
1122     ioVec.iov_len = buf_size;
1123 
1124     return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
1125 #endif // __arm__
1126 }
1127 
1128 #endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
1129