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 LLDB_INVALID_INDEX32;
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 
618     // Check if we are setting watchpoint other than read/write/access
619     // Also update watchpoint flag to match Arm write-read bit configuration.
620     switch (watch_flags)
621     {
622         case 1:
623             watch_flags = 2;
624             break;
625         case 2:
626             watch_flags = 1;
627             break;
628         case 3:
629             break;
630         default:
631             return LLDB_INVALID_INDEX32;
632     }
633 
634     // Can't watch zero bytes
635     // Can't watch more than 4 bytes per WVR/WCR pair
636 
637     if (size == 0 || size > 4)
638         return LLDB_INVALID_INDEX32;
639 
640     // We can only watch up to four bytes that follow a 4 byte aligned address
641     // per watchpoint register pair, so make sure we can properly encode this.
642     addr_word_offset = addr % 4;
643     byte_mask = ((1u << size) - 1u) << addr_word_offset;
644 
645     // Check if we need multiple watchpoint register
646     if (byte_mask > 0xfu)
647         return LLDB_INVALID_INDEX32;
648 
649     // Setup control value
650     // Make the byte_mask into a valid Byte Address Select mask
651     control_value = byte_mask << 5;
652 
653     //Turn on appropriate watchpoint flags read or write
654     control_value |= (watch_flags << 3);
655 
656     // Enable this watchpoint and make it stop in privileged or user mode;
657     control_value |= 7;
658 
659     // Make sure bits 1:0 are clear in our address
660     addr &= ~((lldb::addr_t)3);
661 
662     // Iterate over stored watchpoints
663     // Find a free wp_index or update reference count if duplicate.
664     wp_index = LLDB_INVALID_INDEX32;
665     for (uint32_t i = 0; i < m_max_hwp_supported; i++)
666     {
667         if ((m_hwp_regs[i].control & 1) == 0)
668         {
669             wp_index = i; // Mark last free slot
670         }
671         else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value)
672         {
673             wp_index = i; // Mark duplicate index
674             break; // Stop searching here
675         }
676     }
677 
678      if (wp_index == LLDB_INVALID_INDEX32)
679         return LLDB_INVALID_INDEX32;
680 
681     // Add new or update existing watchpoint
682     if ((m_hwp_regs[wp_index].control & 1) == 0)
683     {
684         // Update watchpoint in local cache
685         m_hwp_regs[wp_index].address = addr;
686         m_hwp_regs[wp_index].control = control_value;
687         m_hwp_regs[wp_index].refcount = 1;
688 
689         // PTRACE call to set corresponding watchpoint register.
690         error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
691 
692         if (error.Fail())
693         {
694             m_hwp_regs[wp_index].address = 0;
695             m_hwp_regs[wp_index].control &= ~1;
696             m_hwp_regs[wp_index].refcount = 0;
697 
698             return LLDB_INVALID_INDEX32;
699         }
700     }
701     else
702         m_hwp_regs[wp_index].refcount++;
703 
704     return wp_index;
705 }
706 
707 bool
708 NativeRegisterContextLinux_arm::ClearHardwareWatchpoint (uint32_t wp_index)
709 {
710     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
711 
712     if (log)
713         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
714 
715     Error error;
716 
717     // Read hardware breakpoint and watchpoint information.
718     error = ReadHardwareDebugInfo ();
719 
720     if (error.Fail())
721         return false;
722 
723     if (wp_index >= m_max_hwp_supported)
724         return false;
725 
726     // Update reference count if multiple references.
727     if (m_hwp_regs[wp_index].refcount > 1)
728     {
729         m_hwp_regs[wp_index].refcount--;
730         return true;
731     }
732     else if (m_hwp_regs[wp_index].refcount == 1)
733     {
734         // Create a backup we can revert to in case of failure.
735         lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
736         uint32_t tempControl = m_hwp_regs[wp_index].control;
737         uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
738 
739         // Update watchpoint in local cache
740         m_hwp_regs[wp_index].control &= ~1;
741         m_hwp_regs[wp_index].address = 0;
742         m_hwp_regs[wp_index].refcount = 0;
743 
744         // Ptrace call to update hardware debug registers
745         error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
746 
747         if (error.Fail())
748         {
749             m_hwp_regs[wp_index].control = tempControl;
750             m_hwp_regs[wp_index].address = tempAddr;
751             m_hwp_regs[wp_index].refcount = tempRefCount;
752 
753             return false;
754         }
755 
756         return true;
757     }
758 
759     return false;
760 }
761 
762 Error
763 NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints ()
764 {
765     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
766 
767     if (log)
768         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
769 
770     Error error;
771 
772     // Read hardware breakpoint and watchpoint information.
773     error = ReadHardwareDebugInfo ();
774 
775     if (error.Fail())
776         return error;
777 
778     lldb::addr_t tempAddr = 0;
779     uint32_t tempControl = 0, tempRefCount = 0;
780 
781     for (uint32_t i = 0; i < m_max_hwp_supported; i++)
782     {
783         if (m_hwp_regs[i].control & 0x01)
784         {
785             // Create a backup we can revert to in case of failure.
786             tempAddr = m_hwp_regs[i].address;
787             tempControl = m_hwp_regs[i].control;
788             tempRefCount = m_hwp_regs[i].refcount;
789 
790             // Clear watchpoints in local cache
791             m_hwp_regs[i].control &= ~1;
792             m_hwp_regs[i].address = 0;
793             m_hwp_regs[i].refcount = 0;
794 
795             // Ptrace call to update hardware debug registers
796             error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
797 
798             if (error.Fail())
799             {
800                 m_hwp_regs[i].control = tempControl;
801                 m_hwp_regs[i].address = tempAddr;
802                 m_hwp_regs[i].refcount = tempRefCount;
803 
804                 return error;
805             }
806         }
807     }
808 
809     return Error();
810 }
811 
812 uint32_t
813 NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index)
814 {
815     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
816 
817     if (log)
818         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
819 
820     switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f)
821     {
822         case 0x01:
823             return 1;
824         case 0x03:
825             return 2;
826         case 0x07:
827             return 3;
828         case 0x0f:
829             return 4;
830         default:
831             return 0;
832     }
833 }
834 bool
835 NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index)
836 {
837     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
838 
839     if (log)
840         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
841 
842     if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
843         return true;
844     else
845         return false;
846 }
847 
848 Error
849 NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
850 {
851     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
852 
853     if (log)
854         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
855 
856     uint32_t watch_size;
857     lldb::addr_t watch_addr;
858 
859     for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index)
860     {
861         watch_size = GetWatchpointSize (wp_index);
862         watch_addr = m_hwp_regs[wp_index].address;
863 
864         if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index)
865             && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size)
866         {
867             return Error();
868         }
869     }
870 
871     wp_index = LLDB_INVALID_INDEX32;
872     return Error();
873 }
874 
875 lldb::addr_t
876 NativeRegisterContextLinux_arm::GetWatchpointAddress (uint32_t wp_index)
877 {
878     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
879 
880     if (log)
881         log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
882 
883     if (wp_index >= m_max_hwp_supported)
884         return LLDB_INVALID_ADDRESS;
885 
886     if (WatchpointIsEnabled(wp_index))
887         return m_hwp_regs[wp_index].address;
888     else
889         return LLDB_INVALID_ADDRESS;
890 }
891 
892 Error
893 NativeRegisterContextLinux_arm::ReadHardwareDebugInfo()
894 {
895     Error error;
896 
897     if (!m_refresh_hwdebug_info)
898     {
899         return Error();
900     }
901 
902     unsigned int cap_val;
903 
904     error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), nullptr, &cap_val, sizeof(unsigned int));
905 
906     if (error.Fail())
907         return error;
908 
909     m_max_hwp_supported = (cap_val >> 8) & 0xff;
910     m_max_hbp_supported = cap_val & 0xff;
911     m_refresh_hwdebug_info = false;
912 
913     return error;
914 }
915 
916 Error
917 NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_index)
918 {
919     Error error;
920 
921     lldb::addr_t *addr_buf;
922     uint32_t *ctrl_buf;
923 
924     if (hwbType == eDREGTypeWATCH)
925     {
926         addr_buf = &m_hwp_regs[hwb_index].address;
927         ctrl_buf = &m_hwp_regs[hwb_index].control;
928 
929         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
930                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 1),
931                 addr_buf, sizeof(unsigned int));
932 
933         if (error.Fail())
934             return error;
935 
936         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
937                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 2),
938                 ctrl_buf, sizeof(unsigned int));
939     }
940     else
941     {
942         addr_buf = &m_hwp_regs[hwb_index].address;
943         ctrl_buf = &m_hwp_regs[hwb_index].control;
944 
945         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
946                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 1),
947                 addr_buf, sizeof(unsigned int));
948 
949         if (error.Fail())
950             return error;
951 
952         error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS,
953                 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 2),
954                 ctrl_buf, sizeof(unsigned int));
955 
956     }
957 
958     return error;
959 }
960 
961 uint32_t
962 NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info) const
963 {
964     return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
965 }
966 
967 Error
968 NativeRegisterContextLinux_arm::DoReadRegisterValue(uint32_t offset,
969                                                     const char* reg_name,
970                                                     uint32_t size,
971                                                     RegisterValue &value)
972 {
973     // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android devices (always return
974     // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR register set instead.
975     // This approach is about 4 times slower but the performance overhead is negligible in
976     // comparision to processing time in lldb-server.
977     assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
978     if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
979         return Error("Register isn't fit into the size of the GPR area");
980 
981     Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
982     if (error.Fail())
983         return error;
984 
985     value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
986     return Error();
987 }
988 
989 Error
990 NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset,
991                                                      const char* reg_name,
992                                                      const RegisterValue &value)
993 {
994     // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android devices (always return
995     // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify
996     // the requested register and write it back. This approach is about 4 times slower but the
997     // performance overhead is negligible in comparision to processing time in lldb-server.
998     assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
999     if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
1000         return Error("Register isn't fit into the size of the GPR area");
1001 
1002     Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
1003     if (error.Fail())
1004         return error;
1005 
1006     uint32_t reg_value = value.GetAsUInt32();
1007     // As precaution for an undefined behavior encountered while setting PC we
1008     // will clear thumb bit of new PC if we are already in thumb mode; that is
1009     // CPSR thumb mode bit is set.
1010     if (offset / sizeof(uint32_t) == gpr_pc_arm)
1011     {
1012         // Check if we are already in thumb mode and
1013         // thumb bit of current PC is read out to be zero and
1014         // thumb bit of next PC is read out to be one.
1015         if ((m_gpr_arm[gpr_cpsr_arm] &  0x20) &&
1016             !(m_gpr_arm[gpr_pc_arm] &  0x01) &&
1017             (value.GetAsUInt32() & 0x01))
1018         {
1019             reg_value &= (~1ull);
1020         }
1021     }
1022 
1023     m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
1024     return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
1025 }
1026 
1027 Error
1028 NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size)
1029 {
1030 #ifdef __arm__
1031     return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
1032 #else // __aarch64__
1033     struct iovec ioVec;
1034     ioVec.iov_base = buf;
1035     ioVec.iov_len = buf_size;
1036 
1037     return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
1038 #endif // __arm__
1039 }
1040 
1041 Error
1042 NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size)
1043 {
1044 #ifdef __arm__
1045     return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
1046 #else // __aarch64__
1047     struct iovec ioVec;
1048     ioVec.iov_base = buf;
1049     ioVec.iov_len = buf_size;
1050 
1051     return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
1052 #endif // __arm__
1053 }
1054 
1055 Error
1056 NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size)
1057 {
1058 #ifdef __arm__
1059     return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS,
1060                                              m_thread.GetID(),
1061                                              nullptr,
1062                                              buf,
1063                                              buf_size);
1064 #else // __aarch64__
1065     struct iovec ioVec;
1066     ioVec.iov_base = buf;
1067     ioVec.iov_len = buf_size;
1068 
1069     return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
1070 #endif // __arm__
1071 }
1072 
1073 Error
1074 NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size)
1075 {
1076 #ifdef __arm__
1077     return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS,
1078                                              m_thread.GetID(),
1079                                              nullptr,
1080                                              buf,
1081                                              buf_size);
1082 #else // __aarch64__
1083     struct iovec ioVec;
1084     ioVec.iov_base = buf;
1085     ioVec.iov_len = buf_size;
1086 
1087     return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
1088 #endif // __arm__
1089 }
1090 
1091 #endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
1092