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