DNBArchImpl.cpp revision 34e71efd963d7422974739519abe4223909200a3
1//===-- DNBArchImpl.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//  Created by Greg Clayton on 6/25/07.
11//
12//===----------------------------------------------------------------------===//
13
14#if defined (__arm__)
15
16#include "MacOSX/arm/DNBArchImpl.h"
17#include "MacOSX/MachProcess.h"
18#include "MacOSX/MachThread.h"
19#include "DNBBreakpoint.h"
20#include "DNBLog.h"
21#include "DNBRegisterInfo.h"
22#include "DNB.h"
23#include "ARM_GCC_Registers.h"
24#include "ARM_DWARF_Registers.h"
25
26#include <sys/sysctl.h>
27
28// BCR address match type
29#define BCR_M_IMVA_MATCH        ((uint32_t)(0u << 21))
30#define BCR_M_CONTEXT_ID_MATCH  ((uint32_t)(1u << 21))
31#define BCR_M_IMVA_MISMATCH     ((uint32_t)(2u << 21))
32#define BCR_M_RESERVED          ((uint32_t)(3u << 21))
33
34// Link a BVR/BCR or WVR/WCR pair to another
35#define E_ENABLE_LINKING        ((uint32_t)(1u << 20))
36
37// Byte Address Select
38#define BAS_IMVA_PLUS_0         ((uint32_t)(1u << 5))
39#define BAS_IMVA_PLUS_1         ((uint32_t)(1u << 6))
40#define BAS_IMVA_PLUS_2         ((uint32_t)(1u << 7))
41#define BAS_IMVA_PLUS_3         ((uint32_t)(1u << 8))
42#define BAS_IMVA_0_1            ((uint32_t)(3u << 5))
43#define BAS_IMVA_2_3            ((uint32_t)(3u << 7))
44#define BAS_IMVA_ALL            ((uint32_t)(0xfu << 5))
45
46// Break only in priveleged or user mode
47#define S_RSVD                  ((uint32_t)(0u << 1))
48#define S_PRIV                  ((uint32_t)(1u << 1))
49#define S_USER                  ((uint32_t)(2u << 1))
50#define S_PRIV_USER             ((S_PRIV) | (S_USER))
51
52#define BCR_ENABLE              ((uint32_t)(1u))
53#define WCR_ENABLE              ((uint32_t)(1u))
54
55// Watchpoint load/store
56#define WCR_LOAD                ((uint32_t)(1u << 3))
57#define WCR_STORE               ((uint32_t)(1u << 4))
58
59// Definitions for the Debug Status and Control Register fields:
60// [5:2] => Method of debug entry
61//#define WATCHPOINT_OCCURRED     ((uint32_t)(2u))
62// I'm seeing this, instead.
63#define WATCHPOINT_OCCURRED     ((uint32_t)(10u))
64
65static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
66static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
67
68// ARM constants used during decoding
69#define REG_RD          0
70#define LDM_REGLIST     1
71#define PC_REG          15
72#define PC_REGLIST_BIT  0x8000
73
74// ARM conditions
75#define COND_EQ     0x0
76#define COND_NE     0x1
77#define COND_CS     0x2
78#define COND_HS     0x2
79#define COND_CC     0x3
80#define COND_LO     0x3
81#define COND_MI     0x4
82#define COND_PL     0x5
83#define COND_VS     0x6
84#define COND_VC     0x7
85#define COND_HI     0x8
86#define COND_LS     0x9
87#define COND_GE     0xA
88#define COND_LT     0xB
89#define COND_GT     0xC
90#define COND_LE     0xD
91#define COND_AL     0xE
92#define COND_UNCOND 0xF
93
94#define MASK_CPSR_T (1u << 5)
95#define MASK_CPSR_J (1u << 24)
96
97#define MNEMONIC_STRING_SIZE 32
98#define OPERAND_STRING_SIZE 128
99
100
101void
102DNBArchMachARM::Initialize()
103{
104    DNBArchPluginInfo arch_plugin_info =
105    {
106        CPU_TYPE_ARM,
107        DNBArchMachARM::Create,
108        DNBArchMachARM::GetRegisterSetInfo,
109        DNBArchMachARM::SoftwareBreakpointOpcode
110    };
111
112    // Register this arch plug-in with the main protocol class
113    DNBArchProtocol::RegisterArchPlugin (arch_plugin_info);
114}
115
116
117DNBArchProtocol *
118DNBArchMachARM::Create (MachThread *thread)
119{
120    DNBArchMachARM *obj = new DNBArchMachARM (thread);
121
122    // When new thread comes along, it tries to inherit from the global debug state, if it is valid.
123    if (Valid_Global_Debug_State)
124    {
125        obj->m_state.dbg = Global_Debug_State;
126        kern_return_t kret = obj->SetDBGState();
127        DNBLogThreadedIf(LOG_WATCHPOINTS,
128                         "DNBArchMachARM::Create() Inherit and SetDBGState() => 0x%8.8x.", kret);
129    }
130    return obj;
131}
132
133const uint8_t * const
134DNBArchMachARM::SoftwareBreakpointOpcode (nub_size_t byte_size)
135{
136    switch (byte_size)
137    {
138    case 2: return g_thumb_breakpooint_opcode;
139    case 4: return g_arm_breakpoint_opcode;
140    }
141    return NULL;
142}
143
144uint32_t
145DNBArchMachARM::GetCPUType()
146{
147    return CPU_TYPE_ARM;
148}
149
150uint64_t
151DNBArchMachARM::GetPC(uint64_t failValue)
152{
153    // Get program counter
154    if (GetGPRState(false) == KERN_SUCCESS)
155        return m_state.context.gpr.__pc;
156    return failValue;
157}
158
159kern_return_t
160DNBArchMachARM::SetPC(uint64_t value)
161{
162    // Get program counter
163    kern_return_t err = GetGPRState(false);
164    if (err == KERN_SUCCESS)
165    {
166        m_state.context.gpr.__pc = value;
167        err = SetGPRState();
168    }
169    return err == KERN_SUCCESS;
170}
171
172uint64_t
173DNBArchMachARM::GetSP(uint64_t failValue)
174{
175    // Get stack pointer
176    if (GetGPRState(false) == KERN_SUCCESS)
177        return m_state.context.gpr.__sp;
178    return failValue;
179}
180
181kern_return_t
182DNBArchMachARM::GetGPRState(bool force)
183{
184    int set = e_regSetGPR;
185    // Check if we have valid cached registers
186    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
187        return KERN_SUCCESS;
188
189    // Read the registers from our thread
190    mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT;
191    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count);
192    uint32_t *r = &m_state.context.gpr.__r[0];
193    DNBLogThreadedIf(LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x",
194                     m_thread->ThreadID(),
195                     ARM_THREAD_STATE,
196                     ARM_THREAD_STATE_COUNT,
197                     kret,
198                     count,
199                     r[0],
200                     r[1],
201                     r[2],
202                     r[3],
203                     r[4],
204                     r[5],
205                     r[6],
206                     r[7],
207                     r[8],
208                     r[9],
209                     r[10],
210                     r[11],
211                     r[12],
212                     r[13],
213                     r[14],
214                     r[15],
215                     r[16]);
216    m_state.SetError(set, Read, kret);
217    return kret;
218}
219
220kern_return_t
221DNBArchMachARM::GetVFPState(bool force)
222{
223    int set = e_regSetVFP;
224    // Check if we have valid cached registers
225    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
226        return KERN_SUCCESS;
227
228    // Read the registers from our thread
229    mach_msg_type_number_t count = ARM_VFP_STATE_COUNT;
230    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
231    if (DNBLogEnabledForAny (LOG_THREAD))
232    {
233        uint32_t *r = &m_state.context.vfp.__r[0];
234        DNBLogThreaded ("thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)",
235                        m_thread->ThreadID(),
236                        ARM_THREAD_STATE,
237                        ARM_THREAD_STATE_COUNT,
238                        kret,
239                        count);
240        DNBLogThreaded("   s0=%8.8x  s1=%8.8x  s2=%8.8x  s3=%8.8x  s4=%8.8x  s5=%8.8x  s6=%8.8x  s7=%8.8x",r[ 0],r[ 1],r[ 2],r[ 3],r[ 4],r[ 5],r[ 6],r[ 7]);
241        DNBLogThreaded("   s8=%8.8x  s9=%8.8x s10=%8.8x s11=%8.8x s12=%8.8x s13=%8.8x s14=%8.8x s15=%8.8x",r[ 8],r[ 9],r[10],r[11],r[12],r[13],r[14],r[15]);
242        DNBLogThreaded("  s16=%8.8x s17=%8.8x s18=%8.8x s19=%8.8x s20=%8.8x s21=%8.8x s22=%8.8x s23=%8.8x",r[16],r[17],r[18],r[19],r[20],r[21],r[22],r[23]);
243        DNBLogThreaded("  s24=%8.8x s25=%8.8x s26=%8.8x s27=%8.8x s28=%8.8x s29=%8.8x s30=%8.8x s31=%8.8x",r[24],r[25],r[26],r[27],r[28],r[29],r[30],r[31]);
244        DNBLogThreaded("  s32=%8.8x s33=%8.8x s34=%8.8x s35=%8.8x s36=%8.8x s37=%8.8x s38=%8.8x s39=%8.8x",r[32],r[33],r[34],r[35],r[36],r[37],r[38],r[39]);
245        DNBLogThreaded("  s40=%8.8x s41=%8.8x s42=%8.8x s43=%8.8x s44=%8.8x s45=%8.8x s46=%8.8x s47=%8.8x",r[40],r[41],r[42],r[43],r[44],r[45],r[46],r[47]);
246        DNBLogThreaded("  s48=%8.8x s49=%8.8x s50=%8.8x s51=%8.8x s52=%8.8x s53=%8.8x s54=%8.8x s55=%8.8x",r[48],r[49],r[50],r[51],r[52],r[53],r[54],r[55]);
247        DNBLogThreaded("  s56=%8.8x s57=%8.8x s58=%8.8x s59=%8.8x s60=%8.8x s61=%8.8x s62=%8.8x s63=%8.8x fpscr=%8.8x",r[56],r[57],r[58],r[59],r[60],r[61],r[62],r[63],r[64]);
248    }
249    m_state.SetError(set, Read, kret);
250    return kret;
251}
252
253kern_return_t
254DNBArchMachARM::GetEXCState(bool force)
255{
256    int set = e_regSetEXC;
257    // Check if we have valid cached registers
258    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
259        return KERN_SUCCESS;
260
261    // Read the registers from our thread
262    mach_msg_type_number_t count = ARM_EXCEPTION_STATE_COUNT;
263    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count);
264    m_state.SetError(set, Read, kret);
265    return kret;
266}
267
268static void
269DumpDBGState(const DNBArchMachARM::DBG& dbg)
270{
271    uint32_t i = 0;
272    for (i=0; i<16; i++) {
273        DNBLogThreadedIf(LOG_STEP, "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
274            i, i, dbg.__bvr[i], dbg.__bcr[i],
275            i, i, dbg.__wvr[i], dbg.__wcr[i]);
276    }
277}
278
279kern_return_t
280DNBArchMachARM::GetDBGState(bool force)
281{
282    int set = e_regSetDBG;
283
284    // Check if we have valid cached registers
285    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
286        return KERN_SUCCESS;
287
288    // Read the registers from our thread
289    mach_msg_type_number_t count = ARM_DEBUG_STATE_COUNT;
290    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count);
291    m_state.SetError(set, Read, kret);
292    return kret;
293}
294
295kern_return_t
296DNBArchMachARM::SetGPRState()
297{
298    int set = e_regSetGPR;
299    kern_return_t kret = ::thread_set_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT);
300    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
301    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
302    return kret;                                // Return the error code
303}
304
305kern_return_t
306DNBArchMachARM::SetVFPState()
307{
308    int set = e_regSetVFP;
309    kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT);
310    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
311    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
312    return kret;                                // Return the error code
313}
314
315kern_return_t
316DNBArchMachARM::SetEXCState()
317{
318    int set = e_regSetEXC;
319    kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT);
320    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
321    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
322    return kret;                                // Return the error code
323}
324
325kern_return_t
326DNBArchMachARM::SetDBGState()
327{
328    int set = e_regSetDBG;
329    kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
330    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
331    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
332    return kret;                                // Return the error code
333}
334
335void
336DNBArchMachARM::ThreadWillResume()
337{
338    // Do we need to step this thread? If so, let the mach thread tell us so.
339    if (m_thread->IsStepping())
340    {
341        // This is the primary thread, let the arch do anything it needs
342        if (NumSupportedHardwareBreakpoints() > 0)
343        {
344            if (EnableHardwareSingleStep(true) != KERN_SUCCESS)
345            {
346                DNBLogThreaded("DNBArchMachARM::ThreadWillResume() failed to enable hardware single step");
347            }
348        }
349        else
350        {
351            if (SetSingleStepSoftwareBreakpoints() != KERN_SUCCESS)
352            {
353                DNBLogThreaded("DNBArchMachARM::ThreadWillResume() failed to enable software single step");
354            }
355        }
356    }
357
358    // Disable the triggered watchpoint temporarily before we resume.
359    // Plus, we try to enable hardware single step to execute past the instruction which triggered our watchpoint.
360    if (m_watchpoint_did_occur)
361    {
362        if (m_watchpoint_hw_index >= 0)
363        {
364            kern_return_t kret = GetDBGState(false);
365            if (kret == KERN_SUCCESS && !IsWatchpointEnabled(m_state.dbg, m_watchpoint_hw_index)) {
366                // The watchpoint might have been disabled by the user.  We don't need to do anything at all
367                // to enable hardware single stepping.
368                m_watchpoint_did_occur = false;
369                m_watchpoint_hw_index = -1;
370                return;
371            }
372
373            DisableHardwareWatchpoint0(m_watchpoint_hw_index, true);
374            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() DisableHardwareWatchpoint(%d) called",
375                             m_watchpoint_hw_index);
376
377            // Enable hardware single step to move past the watchpoint-triggering instruction.
378            m_watchpoint_resume_single_step_enabled = (EnableHardwareSingleStep(true) == KERN_SUCCESS);
379
380            // If we are not able to enable single step to move past the watchpoint-triggering instruction,
381            // at least we should reset the two watchpoint member variables so that the next time around
382            // this callback function is invoked, the enclosing logical branch is skipped.
383            if (!m_watchpoint_resume_single_step_enabled) {
384                // Reset the two watchpoint member variables.
385                m_watchpoint_did_occur = false;
386                m_watchpoint_hw_index = -1;
387                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() failed to enable single step");
388            }
389            else
390                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() succeeded to enable single step");
391        }
392    }
393}
394
395bool
396DNBArchMachARM::ThreadDidStop()
397{
398    bool success = true;
399
400    m_state.InvalidateRegisterSetState (e_regSetALL);
401
402    if (m_watchpoint_resume_single_step_enabled)
403    {
404        // Great!  We now disable the hardware single step as well as re-enable the hardware watchpoint.
405        // See also ThreadWillResume().
406        if (EnableHardwareSingleStep(false) == KERN_SUCCESS)
407        {
408            if (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0)
409            {
410                EnableHardwareWatchpoint0(m_watchpoint_hw_index, true);
411                m_watchpoint_resume_single_step_enabled = false;
412                m_watchpoint_did_occur = false;
413                m_watchpoint_hw_index = -1;
414            }
415            else
416            {
417                DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0) does not hold!");
418            }
419        }
420        else
421        {
422            DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but unable to disable single step!");
423        }
424    }
425
426    // Are we stepping a single instruction?
427    if (GetGPRState(true) == KERN_SUCCESS)
428    {
429        // We are single stepping, was this the primary thread?
430        if (m_thread->IsStepping())
431        {
432            // Are we software single stepping?
433            if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id) || m_sw_single_step_itblock_break_count)
434            {
435                // Remove any software single stepping breakpoints that we have set
436
437                // Do we have a normal software single step breakpoint?
438                if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id))
439                {
440                    DNBLogThreadedIf(LOG_STEP, "%s: removing software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_break_id);
441                    success = m_thread->Process()->DisableBreakpoint(m_sw_single_step_break_id, true);
442                    m_sw_single_step_break_id = INVALID_NUB_BREAK_ID;
443                }
444
445                // Do we have any Thumb IT breakpoints?
446                if (m_sw_single_step_itblock_break_count > 0)
447                {
448                    // See if we hit one of our Thumb IT breakpoints?
449                    DNBBreakpoint *step_bp = m_thread->Process()->Breakpoints().FindByAddress(m_state.context.gpr.__pc);
450
451                    if (step_bp)
452                    {
453                        // We did hit our breakpoint, tell the breakpoint it was
454                        // hit so that it can run its callback routine and fixup
455                        // the PC.
456                        DNBLogThreadedIf(LOG_STEP, "%s: IT software single step breakpoint hit (breakID=%u)", __FUNCTION__, step_bp->GetID());
457                        step_bp->BreakpointHit(m_thread->Process()->ProcessID(), m_thread->ThreadID());
458                    }
459
460                    // Remove all Thumb IT breakpoints
461                    for (int i = 0; i < m_sw_single_step_itblock_break_count; i++)
462                    {
463                        if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
464                        {
465                            DNBLogThreadedIf(LOG_STEP, "%s: removing IT software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_itblock_break_id[i]);
466                            success = m_thread->Process()->DisableBreakpoint(m_sw_single_step_itblock_break_id[i], true);
467                            m_sw_single_step_itblock_break_id[i] = INVALID_NUB_BREAK_ID;
468                        }
469                    }
470                    m_sw_single_step_itblock_break_count = 0;
471
472#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
473
474                    // Decode instructions up to the current PC to ensure the internal decoder state is valid for the IT block
475                    // The decoder has to decode each instruction in the IT block even if it is not executed so that
476                    // the fields are correctly updated
477                    DecodeITBlockInstructions(m_state.context.gpr.__pc);
478#endif
479                }
480
481            }
482            else
483                success = EnableHardwareSingleStep(false) == KERN_SUCCESS;
484        }
485        else
486        {
487            // The MachThread will automatically restore the suspend count
488            // in ThreadDidStop(), so we don't need to do anything here if
489            // we weren't the primary thread the last time
490        }
491    }
492    return success;
493}
494
495bool
496DNBArchMachARM::NotifyException(MachException::Data& exc)
497{
498    switch (exc.exc_type)
499    {
500        default:
501            break;
502        case EXC_BREAKPOINT:
503            if (exc.exc_data.size() == 2 && exc.exc_data[0] == EXC_ARM_DA_DEBUG)
504            {
505                // exc_code = EXC_ARM_DA_DEBUG
506                //
507                // Check whether this corresponds to a watchpoint hit event.
508                // If yes, retrieve the exc_sub_code as the data break address.
509                if (!HasWatchpointOccurred())
510                    break;
511
512                // The data break address is passed as exc_data[1].
513                nub_addr_t addr = exc.exc_data[1];
514                // Find the hardware index with the side effect of possibly massaging the
515                // addr to return the starting address as seen from the debugger side.
516                uint32_t hw_index = GetHardwareWatchpointHit(addr);
517                if (hw_index != INVALID_NUB_HW_INDEX)
518                {
519                    m_watchpoint_did_occur = true;
520                    m_watchpoint_hw_index = hw_index;
521                    exc.exc_data[1] = addr;
522                    // Piggyback the hw_index in the exc.data.
523                    exc.exc_data.push_back(hw_index);
524                }
525
526                return true;
527            }
528            break;
529    }
530    return false;
531}
532
533bool
534DNBArchMachARM::StepNotComplete ()
535{
536    if (m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS)
537    {
538        kern_return_t kret = KERN_INVALID_ARGUMENT;
539        kret = GetGPRState(false);
540        if (kret == KERN_SUCCESS)
541        {
542            if (m_state.context.gpr.__pc == m_hw_single_chained_step_addr)
543            {
544                DNBLogThreadedIf(LOG_STEP, "Need to step some more at 0x%8.8x", m_hw_single_chained_step_addr);
545                return true;
546            }
547        }
548    }
549
550    m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
551    return false;
552}
553
554
555#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
556
557void
558DNBArchMachARM::DecodeITBlockInstructions(nub_addr_t curr_pc)
559
560{
561    uint16_t opcode16;
562    uint32_t opcode32;
563    nub_addr_t next_pc_in_itblock;
564    nub_addr_t pc_in_itblock = m_last_decode_pc;
565
566    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc);
567
568    // Decode IT block instruction from the instruction following the m_last_decoded_instruction at
569    // PC m_last_decode_pc upto and including the instruction at curr_pc
570    if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2)
571    {
572        opcode32 = opcode16;
573        pc_in_itblock += 2;
574        // Check for 32 bit thumb opcode and read the upper 16 bits if needed
575        if (((opcode32 & 0xE000) == 0xE000) && opcode32 & 0x1800)
576        {
577            // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for
578            // a 32 bit Thumb opcode
579            // Read bits 31:16 of a 32 bit Thumb opcode
580            if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2)
581            {
582                pc_in_itblock += 2;
583                // 32 bit thumb opcode
584                opcode32 = (opcode32 << 16) | opcode16;
585            }
586            else
587            {
588                DNBLogError("%s: Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8llx", __FUNCTION__, (uint64_t)pc_in_itblock);
589            }
590        }
591    }
592    else
593    {
594        DNBLogError("%s: Error reading 16-bit Thumb instruction at pc=0x%8.8x", __FUNCTION__, pc_in_itblock);
595    }
596
597    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc_in_itblock=0x%8.8x, curr_pc=0x%8.8x", __FUNCTION__, pc_in_itblock, curr_pc);
598
599    next_pc_in_itblock = pc_in_itblock;
600    while (next_pc_in_itblock <= curr_pc)
601    {
602        arm_error_t decodeError;
603
604        m_last_decode_pc = pc_in_itblock;
605        decodeError = DecodeInstructionUsingDisassembler(pc_in_itblock, m_state.context.gpr.__cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc_in_itblock);
606
607        pc_in_itblock = next_pc_in_itblock;
608        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: next_pc_in_itblock=0x%8.8x", __FUNCTION__, next_pc_in_itblock);
609    }
610}
611#endif
612
613// Set the single step bit in the processor status register.
614kern_return_t
615DNBArchMachARM::EnableHardwareSingleStep (bool enable)
616{
617    DNBError err;
618    DNBLogThreadedIf(LOG_STEP, "%s( enable = %d )", __FUNCTION__, enable);
619
620    err = GetGPRState(false);
621
622    if (err.Fail())
623    {
624        err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__);
625        return err.Error();
626    }
627
628    err = GetDBGState(false);
629
630    if (err.Fail())
631    {
632        err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__);
633        return err.Error();
634    }
635
636    const uint32_t i = 0;
637    if (enable)
638    {
639        m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
640
641        // Save our previous state
642        m_dbg_save = m_state.dbg;
643        // Set a breakpoint that will stop when the PC doesn't match the current one!
644        m_state.dbg.__bvr[i] = m_state.context.gpr.__pc & 0xFFFFFFFCu;      // Set the current PC as the breakpoint address
645        m_state.dbg.__bcr[i] = BCR_M_IMVA_MISMATCH |    // Stop on address mismatch
646                               S_USER |                 // Stop only in user mode
647                               BCR_ENABLE;              // Enable this breakpoint
648        if (m_state.context.gpr.__cpsr & 0x20)
649        {
650            // Thumb breakpoint
651            if (m_state.context.gpr.__pc & 2)
652                m_state.dbg.__bcr[i] |= BAS_IMVA_2_3;
653            else
654                m_state.dbg.__bcr[i] |= BAS_IMVA_0_1;
655
656            uint16_t opcode;
657            if (sizeof(opcode) == m_thread->Process()->Task().ReadMemory(m_state.context.gpr.__pc, sizeof(opcode), &opcode))
658            {
659                if (((opcode & 0xE000) == 0xE000) && opcode & 0x1800)
660                {
661                    // 32 bit thumb opcode...
662                    if (m_state.context.gpr.__pc & 2)
663                    {
664                        // We can't take care of a 32 bit thumb instruction single step
665                        // with just IVA mismatching. We will need to chain an extra
666                        // hardware single step in order to complete this single step...
667                        m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2;
668                    }
669                    else
670                    {
671                        // Extend the number of bits to ignore for the mismatch
672                        m_state.dbg.__bcr[i] |= BAS_IMVA_ALL;
673                    }
674                }
675            }
676        }
677        else
678        {
679            // ARM breakpoint
680            m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; // Stop when any address bits change
681        }
682
683        DNBLogThreadedIf(LOG_STEP, "%s: BVR%u=0x%8.8x  BCR%u=0x%8.8x", __FUNCTION__, i, m_state.dbg.__bvr[i], i, m_state.dbg.__bcr[i]);
684
685        for (uint32_t j=i+1; j<16; ++j)
686        {
687            // Disable all others
688            m_state.dbg.__bvr[j] = 0;
689            m_state.dbg.__bcr[j] = 0;
690        }
691    }
692    else
693    {
694        // Just restore the state we had before we did single stepping
695        m_state.dbg = m_dbg_save;
696    }
697
698    return SetDBGState();
699}
700
701// return 1 if bit "BIT" is set in "value"
702static inline uint32_t bit(uint32_t value, uint32_t bit)
703{
704    return (value >> bit) & 1u;
705}
706
707// return the bitfield "value[msbit:lsbit]".
708static inline uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit)
709{
710    assert(msbit >= lsbit);
711    uint32_t shift_left = sizeof(value) * 8 - 1 - msbit;
712    value <<= shift_left;           // shift anything above the msbit off of the unsigned edge
713    value >>= (shift_left + lsbit); // shift it back again down to the lsbit (including undoing any shift from above)
714    return value;                   // return our result
715}
716
717bool
718DNBArchMachARM::ConditionPassed(uint8_t condition, uint32_t cpsr)
719{
720    uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag
721    uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag
722    uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag
723    uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag
724
725    switch (condition) {
726        case COND_EQ: // (0x0)
727            if (cpsr_z == 1) return true;
728            break;
729        case COND_NE: // (0x1)
730            if (cpsr_z == 0) return true;
731            break;
732        case COND_CS: // (0x2)
733            if (cpsr_c == 1) return true;
734            break;
735        case COND_CC: // (0x3)
736            if (cpsr_c == 0) return true;
737            break;
738        case COND_MI: // (0x4)
739            if (cpsr_n == 1) return true;
740            break;
741        case COND_PL: // (0x5)
742            if (cpsr_n == 0) return true;
743            break;
744        case COND_VS: // (0x6)
745            if (cpsr_v == 1) return true;
746            break;
747        case COND_VC: // (0x7)
748            if (cpsr_v == 0) return true;
749            break;
750        case COND_HI: // (0x8)
751            if ((cpsr_c == 1) && (cpsr_z == 0)) return true;
752            break;
753        case COND_LS: // (0x9)
754            if ((cpsr_c == 0) || (cpsr_z == 1)) return true;
755            break;
756        case COND_GE: // (0xA)
757            if (cpsr_n == cpsr_v) return true;
758            break;
759        case COND_LT: // (0xB)
760            if (cpsr_n != cpsr_v) return true;
761            break;
762        case COND_GT: // (0xC)
763            if ((cpsr_z == 0) && (cpsr_n == cpsr_v)) return true;
764            break;
765        case COND_LE: // (0xD)
766            if ((cpsr_z == 1) || (cpsr_n != cpsr_v)) return true;
767            break;
768        default:
769            return true;
770            break;
771    }
772
773    return false;
774}
775
776#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
777
778bool
779DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t decodedInstruction, bool currentPCIsThumb, nub_addr_t *targetPC)
780{
781    nub_addr_t myTargetPC, addressWherePCLives;
782    pid_t mypid;
783
784    uint32_t cpsr_c = bit(m_state.context.gpr.__cpsr, 29); // Carry condition code flag
785
786    uint32_t firstOperand=0, secondOperand=0, shiftAmount=0, secondOperandAfterShift=0, immediateValue=0;
787    uint32_t halfwords=0, baseAddress=0, immediateOffset=0, addressOffsetFromRegister=0, addressOffsetFromRegisterAfterShift;
788    uint32_t baseAddressIndex=INVALID_NUB_HW_INDEX;
789    uint32_t firstOperandIndex=INVALID_NUB_HW_INDEX;
790    uint32_t secondOperandIndex=INVALID_NUB_HW_INDEX;
791    uint32_t addressOffsetFromRegisterIndex=INVALID_NUB_HW_INDEX;
792    uint32_t shiftRegisterIndex=INVALID_NUB_HW_INDEX;
793    uint16_t registerList16, registerList16NoPC;
794    uint8_t registerList8;
795    uint32_t numRegistersToLoad=0;
796
797    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: instruction->code=%d", __FUNCTION__, decodedInstruction.instruction->code);
798
799    // Get the following in this switch statement:
800    //   - firstOperand, secondOperand, immediateValue, shiftAmount: For arithmetic, logical and move instructions
801    //   - baseAddress, immediateOffset, shiftAmount: For LDR
802    //   - numRegistersToLoad: For LDM and POP instructions
803    switch (decodedInstruction.instruction->code)
804    {
805            // Arithmetic operations that can change the PC
806        case ARM_INST_ADC:
807        case ARM_INST_ADCS:
808        case ARM_INST_ADD:
809        case ARM_INST_ADDS:
810        case ARM_INST_AND:
811        case ARM_INST_ANDS:
812        case ARM_INST_ASR:
813        case ARM_INST_ASRS:
814        case ARM_INST_BIC:
815        case ARM_INST_BICS:
816        case ARM_INST_EOR:
817        case ARM_INST_EORS:
818        case ARM_INST_ORR:
819        case ARM_INST_ORRS:
820        case ARM_INST_RSB:
821        case ARM_INST_RSBS:
822        case ARM_INST_RSC:
823        case ARM_INST_RSCS:
824        case ARM_INST_SBC:
825        case ARM_INST_SBCS:
826        case ARM_INST_SUB:
827        case ARM_INST_SUBS:
828            switch (decodedInstruction.addressMode)
829            {
830                case ARM_ADDR_DATA_IMM:
831                    if (decodedInstruction.numOperands != 3)
832                    {
833                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
834                        return false;
835                    }
836
837                    if (decodedInstruction.op[0].value != PC_REG)
838                    {
839                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
840                        return false;
841                    }
842
843                    // Get firstOperand register value (at index=1)
844                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
845                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];
846
847                    // Get immediateValue (at index=2)
848                    immediateValue = decodedInstruction.op[2].value;
849
850                    break;
851
852                case ARM_ADDR_DATA_REG:
853                    if (decodedInstruction.numOperands != 3)
854                    {
855                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
856                        return false;
857                    }
858
859                    if (decodedInstruction.op[0].value != PC_REG)
860                    {
861                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
862                        return false;
863                    }
864
865                    // Get firstOperand register value (at index=1)
866                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
867                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];
868
869                    // Get secondOperand register value (at index=2)
870                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
871                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
872
873                    break;
874
875                case ARM_ADDR_DATA_SCALED_IMM:
876                    if (decodedInstruction.numOperands != 4)
877                    {
878                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
879                        return false;
880                    }
881
882                    if (decodedInstruction.op[0].value != PC_REG)
883                    {
884                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
885                        return false;
886                    }
887
888                    // Get firstOperand register value (at index=1)
889                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
890                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];
891
892                    // Get secondOperand register value (at index=2)
893                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
894                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
895
896                    // Get shiftAmount as immediate value (at index=3)
897                    shiftAmount = decodedInstruction.op[3].value;
898
899                    break;
900
901
902                case ARM_ADDR_DATA_SCALED_REG:
903                    if (decodedInstruction.numOperands != 4)
904                    {
905                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
906                        return false;
907                    }
908
909                    if (decodedInstruction.op[0].value != PC_REG)
910                    {
911                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
912                        return false;
913                    }
914
915                    // Get firstOperand register value (at index=1)
916                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
917                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];
918
919                    // Get secondOperand register value (at index=2)
920                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
921                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
922
923                    // Get shiftAmount from register (at index=3)
924                    shiftRegisterIndex = decodedInstruction.op[3].value; // second operand register index
925                    shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];
926
927                    break;
928
929                case THUMB_ADDR_HR_HR:
930                    if (decodedInstruction.numOperands != 2)
931                    {
932                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
933                        return false;
934                    }
935
936                    if (decodedInstruction.op[0].value != PC_REG)
937                    {
938                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
939                        return false;
940                    }
941
942                    // Get firstOperand register value (at index=0)
943                    firstOperandIndex = decodedInstruction.op[0].value; // first operand register index
944                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];
945
946                    // Get secondOperand register value (at index=1)
947                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
948                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
949
950                    break;
951
952                default:
953                    break;
954            }
955            break;
956
957            // Logical shifts and move operations that can change the PC
958        case ARM_INST_LSL:
959        case ARM_INST_LSLS:
960        case ARM_INST_LSR:
961        case ARM_INST_LSRS:
962        case ARM_INST_MOV:
963        case ARM_INST_MOVS:
964        case ARM_INST_MVN:
965        case ARM_INST_MVNS:
966        case ARM_INST_ROR:
967        case ARM_INST_RORS:
968        case ARM_INST_RRX:
969        case ARM_INST_RRXS:
970            // In these cases, the firstOperand is always 0, as if it does not exist
971            switch (decodedInstruction.addressMode)
972            {
973                case ARM_ADDR_DATA_IMM:
974                    if (decodedInstruction.numOperands != 2)
975                    {
976                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
977                        return false;
978                    }
979
980                    if (decodedInstruction.op[0].value != PC_REG)
981                    {
982                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
983                        return false;
984                    }
985
986                    // Get immediateValue (at index=1)
987                    immediateValue = decodedInstruction.op[1].value;
988
989                    break;
990
991                case ARM_ADDR_DATA_REG:
992                    if (decodedInstruction.numOperands != 2)
993                    {
994                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
995                        return false;
996                    }
997
998                    if (decodedInstruction.op[0].value != PC_REG)
999                    {
1000                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
1001                        return false;
1002                    }
1003
1004                    // Get secondOperand register value (at index=1)
1005                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
1006                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
1007
1008                    break;
1009
1010                case ARM_ADDR_DATA_SCALED_IMM:
1011                    if (decodedInstruction.numOperands != 3)
1012                    {
1013                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1014                        return false;
1015                    }
1016
1017                    if (decodedInstruction.op[0].value != PC_REG)
1018                    {
1019                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
1020                        return false;
1021                    }
1022
1023                    // Get secondOperand register value (at index=1)
1024                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
1025                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
1026
1027                    // Get shiftAmount as immediate value (at index=2)
1028                    shiftAmount = decodedInstruction.op[2].value;
1029
1030                    break;
1031
1032
1033                case ARM_ADDR_DATA_SCALED_REG:
1034                    if (decodedInstruction.numOperands != 3)
1035                    {
1036                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1037                        return false;
1038                    }
1039
1040                    if (decodedInstruction.op[0].value != PC_REG)
1041                    {
1042                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
1043                        return false;
1044                    }
1045
1046                    // Get secondOperand register value (at index=1)
1047                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
1048                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
1049
1050                    // Get shiftAmount from register (at index=2)
1051                    shiftRegisterIndex = decodedInstruction.op[2].value; // second operand register index
1052                    shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];
1053
1054                    break;
1055
1056                case THUMB_ADDR_HR_HR:
1057                    if (decodedInstruction.numOperands != 2)
1058                    {
1059                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1060                        return false;
1061                    }
1062
1063                    if (decodedInstruction.op[0].value != PC_REG)
1064                    {
1065                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
1066                        return false;
1067                    }
1068
1069                    // Get secondOperand register value (at index=1)
1070                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
1071                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];
1072
1073                    break;
1074
1075                default:
1076                    break;
1077            }
1078
1079            break;
1080
1081            // Simple branches, used to hop around within a routine
1082        case ARM_INST_B:
1083            *targetPC = decodedInstruction.targetPC; // Known targetPC
1084            return true;
1085            break;
1086
1087            // Branch-and-link, used to call ARM subroutines
1088        case ARM_INST_BL:
1089            *targetPC = decodedInstruction.targetPC; // Known targetPC
1090            return true;
1091            break;
1092
1093            // Branch-and-link with exchange, used to call opposite-mode subroutines
1094        case ARM_INST_BLX:
1095            if ((decodedInstruction.addressMode == ARM_ADDR_BRANCH_IMM) ||
1096                (decodedInstruction.addressMode == THUMB_ADDR_UNCOND))
1097            {
1098                *targetPC = decodedInstruction.targetPC; // Known targetPC
1099                return true;
1100            }
1101            else    // addressMode == ARM_ADDR_BRANCH_REG
1102            {
1103                // Unknown target unless we're branching to the PC itself,
1104                //  although this may not work properly with BLX
1105                if (decodedInstruction.op[REG_RD].value == PC_REG)
1106                {
1107                    // this should (almost) never happen
1108                    *targetPC = decodedInstruction.targetPC; // Known targetPC
1109                    return true;
1110                }
1111
1112                // Get the branch address and return
1113                if (decodedInstruction.numOperands != 1)
1114                {
1115                    DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1116                    return false;
1117                }
1118
1119                // Get branch address in register (at index=0)
1120                *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
1121                return true;
1122            }
1123            break;
1124
1125            // Branch with exchange, used to hop to opposite-mode code
1126            // Branch to Jazelle code, used to execute Java; included here since it
1127            //  acts just like BX unless the Jazelle unit is active and JPC is
1128            //  already loaded into it.
1129        case ARM_INST_BX:
1130        case ARM_INST_BXJ:
1131            // Unknown target unless we're branching to the PC itself,
1132            //  although this can never switch to Thumb mode and is
1133            //  therefore pretty much useless
1134            if (decodedInstruction.op[REG_RD].value == PC_REG)
1135            {
1136                // this should (almost) never happen
1137                *targetPC = decodedInstruction.targetPC; // Known targetPC
1138                return true;
1139            }
1140
1141            // Get the branch address and return
1142            if (decodedInstruction.numOperands != 1)
1143            {
1144                DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1145                return false;
1146            }
1147
1148            // Get branch address in register (at index=0)
1149            *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
1150            return true;
1151            break;
1152
1153            // Compare and branch on zero/non-zero (Thumb-16 only)
1154            // Unusual condition check built into the instruction
1155        case ARM_INST_CBZ:
1156        case ARM_INST_CBNZ:
1157            // Branch address is known at compile time
1158            // Get the branch address and return
1159            if (decodedInstruction.numOperands != 2)
1160            {
1161                DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1162                return false;
1163            }
1164
1165            // Get branch address as an immediate value (at index=1)
1166            *targetPC = decodedInstruction.op[1].value;
1167            return true;
1168            break;
1169
1170            // Load register can be used to load PC, usually with a function pointer
1171        case ARM_INST_LDR:
1172            if (decodedInstruction.op[REG_RD].value != PC_REG)
1173            {
1174                DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
1175                return false;
1176            }
1177            switch (decodedInstruction.addressMode)
1178            {
1179                case ARM_ADDR_LSWUB_IMM:
1180                case ARM_ADDR_LSWUB_IMM_PRE:
1181                case ARM_ADDR_LSWUB_IMM_POST:
1182                    if (decodedInstruction.numOperands != 3)
1183                    {
1184                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1185                        return false;
1186                    }
1187
1188                    // Get baseAddress from register (at index=1)
1189                    baseAddressIndex = decodedInstruction.op[1].value;
1190                    baseAddress = m_state.context.gpr.__r[baseAddressIndex];
1191
1192                    // Get immediateOffset (at index=2)
1193                    immediateOffset = decodedInstruction.op[2].value;
1194                    break;
1195
1196                case ARM_ADDR_LSWUB_REG:
1197                case ARM_ADDR_LSWUB_REG_PRE:
1198                case ARM_ADDR_LSWUB_REG_POST:
1199                    if (decodedInstruction.numOperands != 3)
1200                    {
1201                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1202                        return false;
1203                    }
1204
1205                    // Get baseAddress from register (at index=1)
1206                    baseAddressIndex = decodedInstruction.op[1].value;
1207                    baseAddress = m_state.context.gpr.__r[baseAddressIndex];
1208
1209                    // Get immediateOffset from register (at index=2)
1210                    addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
1211                    addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
1212
1213                    break;
1214
1215                case ARM_ADDR_LSWUB_SCALED:
1216                case ARM_ADDR_LSWUB_SCALED_PRE:
1217                case ARM_ADDR_LSWUB_SCALED_POST:
1218                    if (decodedInstruction.numOperands != 4)
1219                    {
1220                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1221                        return false;
1222                    }
1223
1224                    // Get baseAddress from register (at index=1)
1225                    baseAddressIndex = decodedInstruction.op[1].value;
1226                    baseAddress = m_state.context.gpr.__r[baseAddressIndex];
1227
1228                    // Get immediateOffset from register (at index=2)
1229                    addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
1230                    addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
1231
1232                    // Get shiftAmount (at index=3)
1233                    shiftAmount = decodedInstruction.op[3].value;
1234
1235                    break;
1236
1237                default:
1238                    break;
1239            }
1240            break;
1241
1242            // 32b load multiple operations can load the PC along with everything else,
1243            //  usually to return from a function call
1244        case ARM_INST_LDMDA:
1245        case ARM_INST_LDMDB:
1246        case ARM_INST_LDMIA:
1247        case ARM_INST_LDMIB:
1248            if (decodedInstruction.op[LDM_REGLIST].value & PC_REGLIST_BIT)
1249            {
1250                if (decodedInstruction.numOperands != 2)
1251                {
1252                    DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
1253                    return false;
1254                }
1255
1256                // Get baseAddress from register (at index=0)
1257                baseAddressIndex = decodedInstruction.op[0].value;
1258                baseAddress = m_state.context.gpr.__r[baseAddressIndex];
1259
1260                // Get registerList from register (at index=1)
1261                registerList16 = (uint16_t)decodedInstruction.op[1].value;
1262
1263                // Count number of registers to load in the multiple register list excluding the PC
1264                registerList16NoPC = registerList16&0x3FFF; // exclude the PC
1265                numRegistersToLoad=0;
1266                for (int i = 0; i < 16; i++)
1267                {
1268                    if (registerList16NoPC & 0x1) numRegistersToLoad++;
1269                    registerList16NoPC = registerList16NoPC >> 1;
1270                }
1271            }
1272            else
1273            {
1274                DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
1275                return false;
1276            }
1277            break;
1278
1279            // Normal 16-bit LD multiple can't touch R15, but POP can
1280        case ARM_INST_POP:  // Can also get the PC & updates SP
1281            // Get baseAddress from SP (at index=0)
1282            baseAddress = m_state.context.gpr.__sp;
1283
1284            if (decodedInstruction.thumb16b)
1285            {
1286                // Get registerList from register (at index=0)
1287                registerList8 = (uint8_t)decodedInstruction.op[0].value;
1288
1289                // Count number of registers to load in the multiple register list
1290                numRegistersToLoad=0;
1291                for (int i = 0; i < 8; i++)
1292                {
1293                    if (registerList8 & 0x1) numRegistersToLoad++;
1294                    registerList8 = registerList8 >> 1;
1295                }
1296            }
1297            else
1298            {
1299                // Get registerList from register (at index=0)
1300                registerList16 = (uint16_t)decodedInstruction.op[0].value;
1301
1302                // Count number of registers to load in the multiple register list excluding the PC
1303                registerList16NoPC = registerList16&0x3FFF; // exclude the PC
1304                numRegistersToLoad=0;
1305                for (int i = 0; i < 16; i++)
1306                {
1307                    if (registerList16NoPC & 0x1) numRegistersToLoad++;
1308                    registerList16NoPC = registerList16NoPC >> 1;
1309                }
1310            }
1311            break;
1312
1313            // 16b TBB and TBH instructions load a jump address from a table
1314        case ARM_INST_TBB:
1315        case ARM_INST_TBH:
1316            // Get baseAddress from register (at index=0)
1317            baseAddressIndex = decodedInstruction.op[0].value;
1318            baseAddress = m_state.context.gpr.__r[baseAddressIndex];
1319
1320            // Get immediateOffset from register (at index=1)
1321            addressOffsetFromRegisterIndex = decodedInstruction.op[1].value;
1322            addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
1323            break;
1324
1325            // ThumbEE branch-to-handler instructions: Jump to handlers at some offset
1326            //  from a special base pointer register (which is unknown at disassembly time)
1327        case ARM_INST_HB:
1328        case ARM_INST_HBP:
1329//          TODO: ARM_INST_HB, ARM_INST_HBP
1330            break;
1331
1332        case ARM_INST_HBL:
1333        case ARM_INST_HBLP:
1334//          TODO: ARM_INST_HBL, ARM_INST_HBLP
1335            break;
1336
1337            // Breakpoint and software interrupt jump to interrupt handler (always ARM)
1338        case ARM_INST_BKPT:
1339        case ARM_INST_SMC:
1340        case ARM_INST_SVC:
1341
1342            // Return from exception, obviously modifies PC [interrupt only!]
1343        case ARM_INST_RFEDA:
1344        case ARM_INST_RFEDB:
1345        case ARM_INST_RFEIA:
1346        case ARM_INST_RFEIB:
1347
1348            // Other instructions either can't change R15 or are "undefined" if you do,
1349            //  so no sane compiler should ever generate them & we don't care here.
1350            //  Also, R15 can only legally be used in a read-only manner for the
1351            //  various ARM addressing mode (to get PC-relative addressing of constants),
1352            //  but can NOT be used with any of the update modes.
1353        default:
1354            DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code);
1355            return false;
1356            break;
1357    }
1358
1359    // Adjust PC if PC is one of the input operands
1360    if (baseAddressIndex == PC_REG)
1361    {
1362        if (currentPCIsThumb)
1363            baseAddress += 4;
1364        else
1365            baseAddress += 8;
1366    }
1367
1368    if (firstOperandIndex == PC_REG)
1369    {
1370        if (currentPCIsThumb)
1371            firstOperand += 4;
1372        else
1373            firstOperand += 8;
1374    }
1375
1376    if (secondOperandIndex == PC_REG)
1377    {
1378        if (currentPCIsThumb)
1379            secondOperand += 4;
1380        else
1381            secondOperand += 8;
1382    }
1383
1384    if (addressOffsetFromRegisterIndex == PC_REG)
1385    {
1386        if (currentPCIsThumb)
1387            addressOffsetFromRegister += 4;
1388        else
1389            addressOffsetFromRegister += 8;
1390    }
1391
1392    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE,
1393        "%s: firstOperand=%8.8x, secondOperand=%8.8x, immediateValue = %d, shiftAmount = %d, baseAddress = %8.8x, addressOffsetFromRegister = %8.8x, immediateOffset = %d, numRegistersToLoad = %d",
1394        __FUNCTION__,
1395        firstOperand,
1396        secondOperand,
1397        immediateValue,
1398        shiftAmount,
1399        baseAddress,
1400        addressOffsetFromRegister,
1401        immediateOffset,
1402        numRegistersToLoad);
1403
1404
1405    // Calculate following values after applying shiftAmount:
1406    //   - immediateOffsetAfterShift, secondOperandAfterShift
1407
1408    switch (decodedInstruction.scaleMode)
1409    {
1410        case ARM_SCALE_NONE:
1411            addressOffsetFromRegisterAfterShift = addressOffsetFromRegister;
1412            secondOperandAfterShift = secondOperand;
1413            break;
1414
1415        case ARM_SCALE_LSL:             // Logical shift left
1416            addressOffsetFromRegisterAfterShift = addressOffsetFromRegister << shiftAmount;
1417            secondOperandAfterShift = secondOperand << shiftAmount;
1418            break;
1419
1420        case ARM_SCALE_LSR:             // Logical shift right
1421            addressOffsetFromRegisterAfterShift = addressOffsetFromRegister >> shiftAmount;
1422            secondOperandAfterShift = secondOperand >> shiftAmount;
1423            break;
1424
1425        case ARM_SCALE_ASR:             // Arithmetic shift right
1426            asm("mov %0, %1, asr %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount));
1427            asm("mov %0, %1, asr %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount));
1428            break;
1429
1430        case ARM_SCALE_ROR:             // Rotate right
1431            asm("mov %0, %1, ror %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount));
1432            asm("mov %0, %1, ror %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount));
1433            break;
1434
1435        case ARM_SCALE_RRX:             // Rotate right, pulling in carry (1-bit shift only)
1436            asm("mov %0, %1, rrx" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister));
1437            asm("mov %0, %1, rrx" : "=r" (secondOperandAfterShift) : "r" (secondOperand));
1438            break;
1439    }
1440
1441    // Emulate instruction to calculate targetPC
1442    // All branches are already handled in the first switch statement. A branch should not reach this switch
1443    switch (decodedInstruction.instruction->code)
1444    {
1445            // Arithmetic operations that can change the PC
1446        case ARM_INST_ADC:
1447        case ARM_INST_ADCS:
1448            // Add with Carry
1449            *targetPC = firstOperand + (secondOperandAfterShift + immediateValue) + cpsr_c;
1450            break;
1451
1452        case ARM_INST_ADD:
1453        case ARM_INST_ADDS:
1454            *targetPC = firstOperand + (secondOperandAfterShift + immediateValue);
1455            break;
1456
1457        case ARM_INST_AND:
1458        case ARM_INST_ANDS:
1459            *targetPC = firstOperand & (secondOperandAfterShift + immediateValue);
1460            break;
1461
1462        case ARM_INST_ASR:
1463        case ARM_INST_ASRS:
1464            asm("mov %0, %1, asr %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
1465            *targetPC = myTargetPC;
1466            break;
1467
1468        case ARM_INST_BIC:
1469        case ARM_INST_BICS:
1470            asm("bic %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
1471            *targetPC = myTargetPC;
1472            break;
1473
1474        case ARM_INST_EOR:
1475        case ARM_INST_EORS:
1476            asm("eor %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
1477            *targetPC = myTargetPC;
1478            break;
1479
1480        case ARM_INST_ORR:
1481        case ARM_INST_ORRS:
1482            asm("orr %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
1483            *targetPC = myTargetPC;
1484            break;
1485
1486        case ARM_INST_RSB:
1487        case ARM_INST_RSBS:
1488            asm("rsb %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
1489            *targetPC = myTargetPC;
1490            break;
1491
1492        case ARM_INST_RSC:
1493        case ARM_INST_RSCS:
1494            myTargetPC = secondOperandAfterShift - (firstOperand + !cpsr_c);
1495            *targetPC = myTargetPC;
1496            break;
1497
1498        case ARM_INST_SBC:
1499        case ARM_INST_SBCS:
1500            asm("sbc %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue  + !cpsr_c));
1501            *targetPC = myTargetPC;
1502            break;
1503
1504        case ARM_INST_SUB:
1505        case ARM_INST_SUBS:
1506            asm("sub %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
1507            *targetPC = myTargetPC;
1508            break;
1509
1510            // Logical shifts and move operations that can change the PC
1511        case ARM_INST_LSL:
1512        case ARM_INST_LSLS:
1513        case ARM_INST_LSR:
1514        case ARM_INST_LSRS:
1515        case ARM_INST_MOV:
1516        case ARM_INST_MOVS:
1517        case ARM_INST_ROR:
1518        case ARM_INST_RORS:
1519        case ARM_INST_RRX:
1520        case ARM_INST_RRXS:
1521            myTargetPC = secondOperandAfterShift + immediateValue;
1522            *targetPC = myTargetPC;
1523            break;
1524
1525        case ARM_INST_MVN:
1526        case ARM_INST_MVNS:
1527            myTargetPC = !(secondOperandAfterShift + immediateValue);
1528            *targetPC = myTargetPC;
1529            break;
1530
1531            // Load register can be used to load PC, usually with a function pointer
1532        case ARM_INST_LDR:
1533            switch (decodedInstruction.addressMode) {
1534                case ARM_ADDR_LSWUB_IMM_POST:
1535                case ARM_ADDR_LSWUB_REG_POST:
1536                case ARM_ADDR_LSWUB_SCALED_POST:
1537                    addressWherePCLives = baseAddress;
1538                    break;
1539
1540                case ARM_ADDR_LSWUB_IMM:
1541                case ARM_ADDR_LSWUB_REG:
1542                case ARM_ADDR_LSWUB_SCALED:
1543                case ARM_ADDR_LSWUB_IMM_PRE:
1544                case ARM_ADDR_LSWUB_REG_PRE:
1545                case ARM_ADDR_LSWUB_SCALED_PRE:
1546                    addressWherePCLives = baseAddress + (addressOffsetFromRegisterAfterShift + immediateOffset);
1547                    break;
1548
1549                default:
1550                    break;
1551            }
1552
1553            mypid = m_thread->ProcessID();
1554            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
1555            {
1556                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
1557                return false;
1558            }
1559
1560            *targetPC = myTargetPC;
1561            break;
1562
1563            // 32b load multiple operations can load the PC along with everything else,
1564            //  usually to return from a function call
1565        case ARM_INST_LDMDA:
1566            mypid = m_thread->ProcessID();
1567            addressWherePCLives = baseAddress;
1568            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
1569            {
1570                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
1571                return false;
1572            }
1573
1574            *targetPC = myTargetPC;
1575            break;
1576
1577        case ARM_INST_LDMDB:
1578            mypid = m_thread->ProcessID();
1579            addressWherePCLives = baseAddress - 4;
1580            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
1581            {
1582                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
1583                return false;
1584            }
1585
1586            *targetPC = myTargetPC;
1587            break;
1588
1589        case ARM_INST_LDMIB:
1590            mypid = m_thread->ProcessID();
1591            addressWherePCLives = baseAddress + numRegistersToLoad*4 + 4;
1592            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
1593            {
1594                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
1595                return false;
1596            }
1597
1598            *targetPC = myTargetPC;
1599            break;
1600
1601        case ARM_INST_LDMIA: // same as pop
1602            // Normal 16-bit LD multiple can't touch R15, but POP can
1603        case ARM_INST_POP:  // Can also get the PC & updates SP
1604            mypid = m_thread->ProcessID();
1605            addressWherePCLives = baseAddress + numRegistersToLoad*4;
1606            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
1607            {
1608                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
1609                return false;
1610            }
1611
1612            *targetPC = myTargetPC;
1613            break;
1614
1615            // 16b TBB and TBH instructions load a jump address from a table
1616        case ARM_INST_TBB:
1617            mypid = m_thread->ProcessID();
1618            addressWherePCLives = baseAddress + addressOffsetFromRegisterAfterShift;
1619            if (DNBProcessMemoryRead(mypid, addressWherePCLives, 1, &halfwords) !=  1)
1620            {
1621                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBB instruction!", addressWherePCLives);
1622                return false;
1623            }
1624            // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords
1625            *targetPC = (currentPC + 4) + 2*halfwords;
1626            break;
1627
1628        case ARM_INST_TBH:
1629            mypid = m_thread->ProcessID();
1630            addressWherePCLives = ((baseAddress + (addressOffsetFromRegisterAfterShift << 1)) & ~0x1);
1631            if (DNBProcessMemoryRead(mypid, addressWherePCLives, 2, &halfwords) !=  2)
1632            {
1633                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBH instruction!", addressWherePCLives);
1634                return false;
1635            }
1636            // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords
1637            *targetPC = (currentPC + 4) + 2*halfwords;
1638            break;
1639
1640            // ThumbEE branch-to-handler instructions: Jump to handlers at some offset
1641            //  from a special base pointer register (which is unknown at disassembly time)
1642        case ARM_INST_HB:
1643        case ARM_INST_HBP:
1644            //          TODO: ARM_INST_HB, ARM_INST_HBP
1645            break;
1646
1647        case ARM_INST_HBL:
1648        case ARM_INST_HBLP:
1649            //          TODO: ARM_INST_HBL, ARM_INST_HBLP
1650            break;
1651
1652            // Breakpoint and software interrupt jump to interrupt handler (always ARM)
1653        case ARM_INST_BKPT:
1654        case ARM_INST_SMC:
1655        case ARM_INST_SVC:
1656            //          TODO: ARM_INST_BKPT, ARM_INST_SMC, ARM_INST_SVC
1657            break;
1658
1659            // Return from exception, obviously modifies PC [interrupt only!]
1660        case ARM_INST_RFEDA:
1661        case ARM_INST_RFEDB:
1662        case ARM_INST_RFEIA:
1663        case ARM_INST_RFEIB:
1664            //          TODO: ARM_INST_RFEDA, ARM_INST_RFEDB, ARM_INST_RFEIA, ARM_INST_RFEIB
1665            break;
1666
1667            // Other instructions either can't change R15 or are "undefined" if you do,
1668            //  so no sane compiler should ever generate them & we don't care here.
1669            //  Also, R15 can only legally be used in a read-only manner for the
1670            //  various ARM addressing mode (to get PC-relative addressing of constants),
1671            //  but can NOT be used with any of the update modes.
1672        default:
1673            DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code);
1674            return false;
1675            break;
1676    }
1677
1678    return true;
1679}
1680
1681void
1682DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup(nub_addr_t currentPC, uint32_t cpsr, bool currentPCIsThumb, nub_addr_t *nextPC, bool *nextPCIsThumb)
1683{
1684    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup() called");
1685
1686    nub_addr_t targetPC = INVALID_NUB_ADDRESS;
1687    uint32_t registerValue;
1688    arm_error_t decodeError;
1689    nub_addr_t currentPCInITBlock, nextPCInITBlock;
1690    int i;
1691    bool last_decoded_instruction_executes = true;
1692
1693    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: default nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM");
1694
1695    // Update *nextPC and *nextPCIsThumb for special cases
1696    if (m_last_decode_thumb.itBlockRemaining) // we are in an IT block
1697    {
1698        // Set the nextPC to the PC of the instruction which will execute in the IT block
1699        // If none of the instruction execute in the IT block based on the condition flags,
1700        // then point to the instruction immediately following the IT block
1701        const int itBlockRemaining = m_last_decode_thumb.itBlockRemaining;
1702        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%8.8x", __FUNCTION__, itBlockRemaining);
1703
1704        // Determine the PC at which the next instruction resides
1705        if (m_last_decode_arm.thumb16b)
1706            currentPCInITBlock = currentPC + 2;
1707        else
1708            currentPCInITBlock = currentPC + 4;
1709
1710        for (i = 0; i < itBlockRemaining; i++)
1711        {
1712            DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: currentPCInITBlock=%8.8x", __FUNCTION__, currentPCInITBlock);
1713            decodeError = DecodeInstructionUsingDisassembler(currentPCInITBlock, cpsr, &m_last_decode_arm, &m_last_decode_thumb, &nextPCInITBlock);
1714
1715            if (decodeError != ARM_SUCCESS)
1716                DNBLogError("unable to disassemble instruction at 0x%8.8llx", (uint64_t)currentPCInITBlock);
1717
1718            DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: condition=%d", __FUNCTION__, m_last_decode_arm.condition);
1719            if (ConditionPassed(m_last_decode_arm.condition, cpsr))
1720            {
1721                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes matched for instruction %d", __FUNCTION__, i);
1722                break; // break from the for loop
1723            }
1724            else
1725            {
1726                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes DID NOT matched for instruction %d", __FUNCTION__, i);
1727            }
1728
1729            // update currentPC and nextPCInITBlock
1730            currentPCInITBlock = nextPCInITBlock;
1731        }
1732
1733        if (i == itBlockRemaining) // We came out of the IT block without executing any instructions
1734            last_decoded_instruction_executes = false;
1735
1736        *nextPC = currentPCInITBlock;
1737        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: After IT block step-through: *nextPC=%8.8x", __FUNCTION__, *nextPC);
1738    }
1739
1740    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE,
1741                    "%s: cpsr = %8.8x, thumb16b = %d, thumb = %d, branch = %d, conditional = %d, knownTarget = %d, links = %d, canSwitchMode = %d, doesSwitchMode = %d",
1742                    __FUNCTION__,
1743                    cpsr,
1744                    m_last_decode_arm.thumb16b,
1745                    m_last_decode_arm.thumb,
1746                    m_last_decode_arm.branch,
1747                    m_last_decode_arm.conditional,
1748                    m_last_decode_arm.knownTarget,
1749                    m_last_decode_arm.links,
1750                    m_last_decode_arm.canSwitchMode,
1751                    m_last_decode_arm.doesSwitchMode);
1752
1753
1754    if (last_decoded_instruction_executes &&                    // Was this a conditional instruction that did execute?
1755        m_last_decode_arm.branch &&                             // Can this instruction change the PC?
1756        (m_last_decode_arm.instruction->code != ARM_INST_SVC))  // If this instruction is not an SVC instruction
1757    {
1758        // Set targetPC. Compute if needed.
1759        if (m_last_decode_arm.knownTarget)
1760        {
1761            // Fixed, known PC-relative
1762            targetPC = m_last_decode_arm.targetPC;
1763        }
1764        else
1765        {
1766            // if targetPC is not known at compile time (PC-relative target), compute targetPC
1767            if (!ComputeNextPC(currentPC, m_last_decode_arm, currentPCIsThumb, &targetPC))
1768            {
1769                DNBLogError("%s: Unable to compute targetPC for instruction at 0x%8.8llx", __FUNCTION__, (uint64_t)currentPC);
1770                targetPC = INVALID_NUB_ADDRESS;
1771            }
1772        }
1773
1774        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: targetPC=0x%8.8x, cpsr=0x%8.8x, condition=0x%hhx", __FUNCTION__, targetPC, cpsr, m_last_decode_arm.condition);
1775
1776        // Refine nextPC computation
1777        if ((m_last_decode_arm.instruction->code == ARM_INST_CBZ) ||
1778            (m_last_decode_arm.instruction->code == ARM_INST_CBNZ))
1779        {
1780            // Compare and branch on zero/non-zero (Thumb-16 only)
1781            // Unusual condition check built into the instruction
1782            registerValue = m_state.context.gpr.__r[m_last_decode_arm.op[REG_RD].value];
1783
1784            if (m_last_decode_arm.instruction->code == ARM_INST_CBZ)
1785            {
1786                if (registerValue == 0)
1787                    *nextPC = targetPC;
1788            }
1789            else
1790            {
1791                if (registerValue != 0)
1792                    *nextPC = targetPC;
1793            }
1794        }
1795        else if (m_last_decode_arm.conditional) // Is the change conditional on flag results?
1796        {
1797            if (ConditionPassed(m_last_decode_arm.condition, cpsr)) // conditions match
1798            {
1799                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition matched!", __FUNCTION__);
1800                *nextPC = targetPC;
1801            }
1802            else
1803            {
1804                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition did not match!", __FUNCTION__);
1805            }
1806        }
1807        else
1808        {
1809            *nextPC = targetPC;
1810        }
1811
1812        // Refine nextPCIsThumb computation
1813        if (m_last_decode_arm.doesSwitchMode)
1814        {
1815            *nextPCIsThumb = !currentPCIsThumb;
1816        }
1817        else if (m_last_decode_arm.canSwitchMode)
1818        {
1819            // Legal to switch ARM <--> Thumb mode with this branch
1820            // dependent on bit[0] of targetPC
1821            *nextPCIsThumb = (*nextPC & 1u) != 0;
1822        }
1823        else
1824        {
1825            *nextPCIsThumb = currentPCIsThumb;
1826        }
1827    }
1828
1829    DNBLogThreadedIf(LOG_STEP, "%s: calculated nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM");
1830}
1831
1832
1833arm_error_t
1834DNBArchMachARM::DecodeInstructionUsingDisassembler(nub_addr_t curr_pc, uint32_t curr_cpsr, arm_decoded_instruction_t *decodedInstruction, thumb_static_data_t *thumbStaticData, nub_addr_t *next_pc)
1835{
1836
1837    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc=0x%8.8x, cpsr=0x%8.8x", __FUNCTION__, curr_pc, curr_cpsr);
1838
1839    const uint32_t isetstate_mask = MASK_CPSR_T | MASK_CPSR_J;
1840    const uint32_t curr_isetstate = curr_cpsr & isetstate_mask;
1841    uint32_t opcode32;
1842    nub_addr_t nextPC = curr_pc;
1843    arm_error_t decodeReturnCode = ARM_SUCCESS;
1844
1845    m_last_decode_pc = curr_pc;
1846    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc);
1847
1848    switch (curr_isetstate) {
1849        case 0x0: // ARM Instruction
1850            // Read the ARM opcode
1851            if (m_thread->Process()->Task().ReadMemory(curr_pc, 4, &opcode32) != 4)
1852            {
1853                DNBLogError("unable to read opcode bits 31:0 for an ARM opcode at 0x%8.8llx", (uint64_t)curr_pc);
1854                decodeReturnCode = ARM_ERROR;
1855            }
1856            else
1857            {
1858                nextPC += 4;
1859                decodeReturnCode = ArmDisassembler((uint64_t)curr_pc, opcode32, false, decodedInstruction, NULL, 0, NULL, 0);
1860
1861                if (decodeReturnCode != ARM_SUCCESS)
1862                    DNBLogError("Unable to decode ARM instruction 0x%8.8x at 0x%8.8llx", opcode32, (uint64_t)curr_pc);
1863            }
1864            break;
1865
1866        case 0x20: // Thumb Instruction
1867            uint16_t opcode16;
1868            // Read the a 16 bit Thumb opcode
1869            if (m_thread->Process()->Task().ReadMemory(curr_pc, 2, &opcode16) != 2)
1870            {
1871                DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8llx", (uint64_t)curr_pc);
1872                decodeReturnCode = ARM_ERROR;
1873            }
1874            else
1875            {
1876                nextPC += 2;
1877                opcode32 = opcode16;
1878
1879                decodeReturnCode = ThumbDisassembler((uint64_t)curr_pc, opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0);
1880
1881                switch (decodeReturnCode) {
1882                    case ARM_SKIP:
1883                        // 32 bit thumb opcode
1884                        nextPC += 2;
1885                        if (m_thread->Process()->Task().ReadMemory(curr_pc+2, 2, &opcode16) != 2)
1886                        {
1887                            DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8llx", (uint64_t)curr_pc+2);
1888                        }
1889                        else
1890                        {
1891                            opcode32 = (opcode32 << 16) | opcode16;
1892
1893                            decodeReturnCode = ThumbDisassembler((uint64_t)(curr_pc+2), opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0);
1894
1895                            if (decodeReturnCode != ARM_SUCCESS)
1896                                DNBLogError("Unable to decode 2nd half of Thumb instruction 0x%8.4hx at 0x%8.8llx", opcode16, (uint64_t)curr_pc+2);
1897                            break;
1898                        }
1899                        break;
1900
1901                    case ARM_SUCCESS:
1902                        // 16 bit thumb opcode; at this point we are done decoding the opcode
1903                        break;
1904
1905                    default:
1906                        DNBLogError("Unable to decode Thumb instruction 0x%8.4hx at 0x%8.8llx", opcode16, (uint64_t)curr_pc);
1907                        decodeReturnCode = ARM_ERROR;
1908                        break;
1909                }
1910            }
1911            break;
1912
1913        default:
1914            break;
1915    }
1916
1917    if (next_pc)
1918        *next_pc = nextPC;
1919
1920    return decodeReturnCode;
1921}
1922
1923#endif
1924
1925nub_bool_t
1926DNBArchMachARM::BreakpointHit (nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton)
1927{
1928    nub_addr_t bkpt_pc = (nub_addr_t)baton;
1929    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s(pid = %i, tid = %4.4x, breakID = %u, baton = %p): Setting PC to 0x%8.8x", __FUNCTION__, pid, tid, breakID, baton, bkpt_pc);
1930
1931    DNBRegisterValue pc_value;
1932    DNBThreadGetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
1933    pc_value.value.uint32 = bkpt_pc;
1934    return DNBThreadSetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
1935}
1936
1937// Set the single step bit in the processor status register.
1938kern_return_t
1939DNBArchMachARM::SetSingleStepSoftwareBreakpoints()
1940{
1941    DNBError err;
1942
1943#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
1944    err = GetGPRState(false);
1945
1946    if (err.Fail())
1947    {
1948        err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__);
1949        return err.Error();
1950    }
1951
1952    nub_addr_t curr_pc = m_state.context.gpr.__pc;
1953    uint32_t curr_cpsr = m_state.context.gpr.__cpsr;
1954    nub_addr_t next_pc = curr_pc;
1955
1956    bool curr_pc_is_thumb = (m_state.context.gpr.__cpsr & 0x20) != 0;
1957    bool next_pc_is_thumb = curr_pc_is_thumb;
1958
1959    uint32_t curr_itstate = ((curr_cpsr & 0x6000000) >> 25) | ((curr_cpsr & 0xFC00) >> 8);
1960    bool inITBlock = (curr_itstate & 0xF) ? 1 : 0;
1961    bool lastInITBlock = ((curr_itstate & 0xF) == 0x8) ? 1 : 0;
1962
1963    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: curr_pc=0x%8.8x (%s), curr_itstate=0x%x, inITBlock=%d, lastInITBlock=%d", __FUNCTION__, curr_pc, curr_pc_is_thumb ? "Thumb" : "ARM", curr_itstate, inITBlock, lastInITBlock);
1964
1965    // If the instruction is not in the IT block, then decode using the Disassembler and compute next_pc
1966    if (!inITBlock)
1967    {
1968        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Decoding an instruction NOT in the IT block", __FUNCTION__);
1969
1970        arm_error_t decodeReturnCode =  DecodeInstructionUsingDisassembler(curr_pc, curr_cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc);
1971
1972        if (decodeReturnCode != ARM_SUCCESS)
1973        {
1974            err = KERN_INVALID_ARGUMENT;
1975            DNBLogError("DNBArchMachARM::SetSingleStepSoftwareBreakpoints: Unable to disassemble instruction at 0x%8.8llx", (uint64_t)curr_pc);
1976        }
1977    }
1978    else
1979    {
1980        next_pc = curr_pc + ((m_last_decode_arm.thumb16b) ? 2 : 4);
1981    }
1982
1983    // Instruction is NOT in the IT block OR
1984    if (!inITBlock)
1985    {
1986        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: normal instruction", __FUNCTION__);
1987        EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
1988    }
1989    else if (inITBlock && !m_last_decode_arm.setsFlags)
1990    {
1991        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that doesn't set flags", __FUNCTION__);
1992        EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
1993    }
1994    else if (lastInITBlock && m_last_decode_arm.branch)
1995    {
1996        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction which last in the IT block and is a branch", __FUNCTION__);
1997        EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
1998    }
1999    else
2000    {
2001        // Instruction is in IT block and can modify the CPSR flags
2002        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that sets flags", __FUNCTION__);
2003
2004        // NOTE: When this point of code is reached, the instruction at curr_pc has already been decoded
2005        // inside the function ThreadDidStop(). Therefore m_last_decode_arm, m_last_decode_thumb
2006        // reflect the decoded instruction at curr_pc
2007
2008        // If we find an instruction inside the IT block which will set/modify the condition flags (NZCV bits in CPSR),
2009        // we set breakpoints at all remaining instructions inside the IT block starting from the instruction immediately
2010        // following this one AND a breakpoint at the instruction immediately following the IT block. We do this because
2011        // we cannot determine the next_pc until the instruction at which we are currently stopped executes. Hence we
2012        // insert (m_last_decode_thumb.itBlockRemaining+1) 16-bit Thumb breakpoints at consecutive memory locations
2013        // starting at addrOfNextInstructionInITBlock. We record these breakpoints in class variable m_sw_single_step_itblock_break_id[],
2014        // and also record the total number of IT breakpoints set in the variable 'm_sw_single_step_itblock_break_count'.
2015
2016        // The instructions inside the IT block, which are replaced by the 16-bit Thumb breakpoints (opcode=0xDEFE)
2017        // instructions, can be either Thumb-16 or Thumb-32. When a Thumb-32 instruction (say, inst#1) is replaced  Thumb
2018        // by a 16-bit breakpoint (OS only supports 16-bit breakpoints in Thumb mode and 32-bit breakpoints in ARM mode), the
2019        // breakpoint for the next instruction (say instr#2) is saved in the upper half of this Thumb-32 (instr#1)
2020        // instruction. Hence if the execution stops at Breakpoint2 corresponding to instr#2, the PC is offset by 16-bits.
2021        // We therefore have to keep track of PC of each instruction in the IT block that is being replaced with the 16-bit
2022        // Thumb breakpoint, to ensure that when the breakpoint is hit, the PC is adjusted to the correct value. We save
2023        // the actual PC corresponding to each instruction in the IT block by associating a call back with each breakpoint
2024        // we set and passing it as a baton. When the breakpoint hits and the callback routine is called, the routine
2025        // adjusts the PC based on the baton that is passed to it.
2026
2027        nub_addr_t addrOfNextInstructionInITBlock, pcInITBlock, nextPCInITBlock, bpAddressInITBlock;
2028        uint16_t opcode16;
2029        uint32_t opcode32;
2030
2031        addrOfNextInstructionInITBlock = (m_last_decode_arm.thumb16b) ? curr_pc + 2 : curr_pc + 4;
2032
2033        pcInITBlock = addrOfNextInstructionInITBlock;
2034
2035        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%d", __FUNCTION__, m_last_decode_thumb.itBlockRemaining);
2036
2037        m_sw_single_step_itblock_break_count = 0;
2038        for (int i = 0; i <= m_last_decode_thumb.itBlockRemaining; i++)
2039        {
2040            if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
2041            {
2042                DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Array m_sw_single_step_itblock_break_id should not contain any valid breakpoint IDs at this point. But found a valid breakID=%d at index=%d", m_sw_single_step_itblock_break_id[i], i);
2043            }
2044            else
2045            {
2046                nextPCInITBlock = pcInITBlock;
2047                // Compute nextPCInITBlock based on opcode present at pcInITBlock
2048                if (m_thread->Process()->Task().ReadMemory(pcInITBlock, 2, &opcode16) == 2)
2049                {
2050                    opcode32 = opcode16;
2051                    nextPCInITBlock += 2;
2052
2053                    // Check for 32 bit thumb opcode and read the upper 16 bits if needed
2054                    if (((opcode32 & 0xE000) == 0xE000) && (opcode32 & 0x1800))
2055                    {
2056                        // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for
2057                        // a 32 bit Thumb opcode
2058                        // Read bits 31:16 of a 32 bit Thumb opcode
2059                        if (m_thread->Process()->Task().ReadMemory(pcInITBlock+2, 2, &opcode16) == 2)
2060                        {
2061                            // 32 bit thumb opcode
2062                            opcode32 = (opcode32 << 16) | opcode16;
2063                            nextPCInITBlock += 2;
2064                        }
2065                        else
2066                        {
2067                            DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8llx", (uint64_t)nextPCInITBlock);
2068                        }
2069                    }
2070                }
2071                else
2072                {
2073                    DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Error reading 16-bit Thumb instruction at pc=0x%8.8x", nextPCInITBlock);
2074                }
2075
2076
2077                // Set breakpoint and associate a callback function with it
2078                bpAddressInITBlock = addrOfNextInstructionInITBlock + 2*i;
2079                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Setting IT breakpoint[%d] at address: 0x%8.8x", __FUNCTION__, i, bpAddressInITBlock);
2080
2081                m_sw_single_step_itblock_break_id[i] = m_thread->Process()->CreateBreakpoint(bpAddressInITBlock, 2, false, m_thread->ThreadID());
2082                if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
2083                    err = KERN_INVALID_ARGUMENT;
2084                else
2085                {
2086                    DNBLogThreadedIf(LOG_STEP, "%s: Set IT breakpoint[%i]=%d set at 0x%8.8x for instruction at 0x%8.8x", __FUNCTION__, i, m_sw_single_step_itblock_break_id[i], bpAddressInITBlock, pcInITBlock);
2087
2088                    // Set the breakpoint callback for these special IT breakpoints
2089                    // so that if one of these breakpoints gets hit, it knows to
2090                    // update the PC to the original address of the conditional
2091                    // IT instruction.
2092                    DNBBreakpointSetCallback(m_thread->ProcessID(), m_sw_single_step_itblock_break_id[i], DNBArchMachARM::BreakpointHit, (void*)pcInITBlock);
2093                    m_sw_single_step_itblock_break_count++;
2094                }
2095            }
2096
2097            pcInITBlock = nextPCInITBlock;
2098        }
2099
2100        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Set %u IT software single breakpoints.", __FUNCTION__, m_sw_single_step_itblock_break_count);
2101
2102    }
2103
2104    DNBLogThreadedIf(LOG_STEP, "%s: next_pc=0x%8.8x (%s)", __FUNCTION__, next_pc, next_pc_is_thumb ? "Thumb" : "ARM");
2105
2106    if (next_pc & 0x1)
2107    {
2108        assert(next_pc_is_thumb);
2109    }
2110
2111    if (next_pc_is_thumb)
2112    {
2113        next_pc &= ~0x1;
2114    }
2115    else
2116    {
2117        assert((next_pc & 0x3) == 0);
2118    }
2119
2120    if (!inITBlock || (inITBlock && !m_last_decode_arm.setsFlags) || (lastInITBlock && m_last_decode_arm.branch))
2121    {
2122        err = KERN_SUCCESS;
2123
2124        const DNBBreakpoint *bp = m_thread->Process()->Breakpoints().FindByAddress(next_pc);
2125
2126        if (bp == NULL)
2127        {
2128            m_sw_single_step_break_id = m_thread->Process()->CreateBreakpoint(next_pc, next_pc_is_thumb ? 2 : 4, false, m_thread->ThreadID());
2129            if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id))
2130                err = KERN_INVALID_ARGUMENT;
2131            DNBLogThreadedIf(LOG_STEP, "%s: software single step breakpoint with breakID=%d set at 0x%8.8x", __FUNCTION__, m_sw_single_step_break_id, next_pc);
2132        }
2133    }
2134#else
2135    err.LogThreaded("%s: ARMDisassembler.framework support is disabled", __FUNCTION__);
2136#endif
2137    return err.Error();
2138}
2139
2140uint32_t
2141DNBArchMachARM::NumSupportedHardwareBreakpoints()
2142{
2143    // Set the init value to something that will let us know that we need to
2144    // autodetect how many breakpoints are supported dynamically...
2145    static uint32_t g_num_supported_hw_breakpoints = UINT_MAX;
2146    if (g_num_supported_hw_breakpoints == UINT_MAX)
2147    {
2148        // Set this to zero in case we can't tell if there are any HW breakpoints
2149        g_num_supported_hw_breakpoints = 0;
2150
2151        size_t len;
2152        uint32_t n = 0;
2153        len = sizeof (n);
2154        if (::sysctlbyname("hw.optional.breakpoint", &n, &len, NULL, 0) == 0)
2155        {
2156            g_num_supported_hw_breakpoints = n;
2157            DNBLogThreadedIf(LOG_THREAD, "hw.optional.breakpoint=%u", n);
2158        }
2159        else
2160        {
2161            // Read the DBGDIDR to get the number of available hardware breakpoints
2162            // However, in some of our current armv7 processors, hardware
2163            // breakpoints/watchpoints were not properly connected. So detect those
2164            // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
2165            // field to distinguish CPU architectures. This is a hack until we can
2166            // get <rdar://problem/6372672> fixed, at which point we will switch to
2167            // using a different sysctl string that will tell us how many BRPs
2168            // are available to us directly without having to read DBGDIDR.
2169            uint32_t register_DBGDIDR;
2170
2171            asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
2172            uint32_t numBRPs = bits(register_DBGDIDR, 27, 24);
2173            // Zero is reserved for the BRP count, so don't increment it if it is zero
2174            if (numBRPs > 0)
2175                numBRPs++;
2176            DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, numBRPs);
2177
2178            if (numBRPs > 0)
2179            {
2180                uint32_t cpusubtype;
2181                len = sizeof(cpusubtype);
2182                // TODO: remove this hack and change to using hw.optional.xx when implmented
2183                if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
2184                {
2185                    DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=%d", cpusubtype);
2186                    if (cpusubtype == CPU_SUBTYPE_ARM_V7)
2187                        DNBLogThreadedIf(LOG_THREAD, "Hardware breakpoints disabled for armv7 (rdar://problem/6372672)");
2188                    else
2189                        g_num_supported_hw_breakpoints = numBRPs;
2190                }
2191            }
2192        }
2193    }
2194    return g_num_supported_hw_breakpoints;
2195}
2196
2197
2198uint32_t
2199DNBArchMachARM::NumSupportedHardwareWatchpoints()
2200{
2201    // Set the init value to something that will let us know that we need to
2202    // autodetect how many watchpoints are supported dynamically...
2203    static uint32_t g_num_supported_hw_watchpoints = UINT_MAX;
2204    if (g_num_supported_hw_watchpoints == UINT_MAX)
2205    {
2206        // Set this to zero in case we can't tell if there are any HW breakpoints
2207        g_num_supported_hw_watchpoints = 0;
2208
2209
2210        size_t len;
2211        uint32_t n = 0;
2212        len = sizeof (n);
2213        if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0)
2214        {
2215            g_num_supported_hw_watchpoints = n;
2216            DNBLogThreadedIf(LOG_THREAD, "hw.optional.watchpoint=%u", n);
2217        }
2218        else
2219        {
2220            // Read the DBGDIDR to get the number of available hardware breakpoints
2221            // However, in some of our current armv7 processors, hardware
2222            // breakpoints/watchpoints were not properly connected. So detect those
2223            // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
2224            // field to distinguish CPU architectures. This is a hack until we can
2225            // get <rdar://problem/6372672> fixed, at which point we will switch to
2226            // using a different sysctl string that will tell us how many WRPs
2227            // are available to us directly without having to read DBGDIDR.
2228
2229            uint32_t register_DBGDIDR;
2230            asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
2231            uint32_t numWRPs = bits(register_DBGDIDR, 31, 28) + 1;
2232            DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, numWRPs);
2233
2234            if (numWRPs > 0)
2235            {
2236                uint32_t cpusubtype;
2237                size_t len;
2238                len = sizeof(cpusubtype);
2239                // TODO: remove this hack and change to using hw.optional.xx when implmented
2240                if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
2241                {
2242                    DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype);
2243
2244                    if (cpusubtype == CPU_SUBTYPE_ARM_V7)
2245                        DNBLogThreadedIf(LOG_THREAD, "Hardware watchpoints disabled for armv7 (rdar://problem/6372672)");
2246                    else
2247                        g_num_supported_hw_watchpoints = numWRPs;
2248                }
2249            }
2250        }
2251    }
2252    return g_num_supported_hw_watchpoints;
2253}
2254
2255
2256uint32_t
2257DNBArchMachARM::EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size)
2258{
2259    // Make sure our address isn't bogus
2260    if (addr & 1)
2261        return INVALID_NUB_HW_INDEX;
2262
2263    kern_return_t kret = GetDBGState(false);
2264
2265    if (kret == KERN_SUCCESS)
2266    {
2267        const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
2268        uint32_t i;
2269        for (i=0; i<num_hw_breakpoints; ++i)
2270        {
2271            if ((m_state.dbg.__bcr[i] & BCR_ENABLE) == 0)
2272                break; // We found an available hw breakpoint slot (in i)
2273        }
2274
2275        // See if we found an available hw breakpoint slot above
2276        if (i < num_hw_breakpoints)
2277        {
2278            // Make sure bits 1:0 are clear in our address
2279            m_state.dbg.__bvr[i] = addr & ~((nub_addr_t)3);
2280
2281            if (size == 2 || addr & 2)
2282            {
2283                uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
2284
2285                // We have a thumb breakpoint
2286                // We have an ARM breakpoint
2287                m_state.dbg.__bcr[i] =  BCR_M_IMVA_MATCH |  // Stop on address mismatch
2288                                        byte_addr_select |  // Set the correct byte address select so we only trigger on the correct opcode
2289                                        S_USER |            // Which modes should this breakpoint stop in?
2290                                        BCR_ENABLE;         // Enable this hardware breakpoint
2291                DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = 0x%8.8llx, size = %llu ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)",
2292                                  (uint64_t)addr,
2293                                  (uint64_t)size,
2294                                  i,
2295                                  i,
2296                                  m_state.dbg.__bvr[i],
2297                                  m_state.dbg.__bcr[i]);
2298            }
2299            else if (size == 4)
2300            {
2301                // We have an ARM breakpoint
2302                m_state.dbg.__bcr[i] =  BCR_M_IMVA_MATCH |  // Stop on address mismatch
2303                                        BAS_IMVA_ALL |      // Stop on any of the four bytes following the IMVA
2304                                        S_USER |            // Which modes should this breakpoint stop in?
2305                                        BCR_ENABLE;         // Enable this hardware breakpoint
2306                DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = 0x%8.8llx, size = %llu ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)",
2307                                  (uint64_t)addr,
2308                                  (uint64_t)size,
2309                                  i,
2310                                  i,
2311                                  m_state.dbg.__bvr[i],
2312                                  m_state.dbg.__bcr[i]);
2313            }
2314
2315            kret = SetDBGState();
2316            DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint() SetDBGState() => 0x%8.8x.", kret);
2317
2318            if (kret == KERN_SUCCESS)
2319                return i;
2320        }
2321        else
2322        {
2323            DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint(addr = 0x%8.8llx, size = %llu) => all hardware breakpoint resources are being used.", (uint64_t)addr, (uint64_t)size);
2324        }
2325    }
2326
2327    return INVALID_NUB_HW_INDEX;
2328}
2329
2330bool
2331DNBArchMachARM::DisableHardwareBreakpoint (uint32_t hw_index)
2332{
2333    kern_return_t kret = GetDBGState(false);
2334
2335    const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
2336    if (kret == KERN_SUCCESS)
2337    {
2338        if (hw_index < num_hw_points)
2339        {
2340            m_state.dbg.__bcr[hw_index] = 0;
2341            DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x  BCR%u = 0x%8.8x",
2342                    hw_index,
2343                    hw_index,
2344                    m_state.dbg.__bvr[hw_index],
2345                    hw_index,
2346                    m_state.dbg.__bcr[hw_index]);
2347
2348            kret = SetDBGState();
2349
2350            if (kret == KERN_SUCCESS)
2351                return true;
2352        }
2353    }
2354    return false;
2355}
2356
2357// This stores the lo->hi mappings.  It's safe to initialize to all 0's
2358// since hi > lo and therefore LoHi[i] cannot be 0.
2359static uint32_t LoHi[16] = { 0 };
2360
2361uint32_t
2362DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
2363{
2364    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(addr = 0x%8.8llx, size = %llu, read = %u, write = %u)", (uint64_t)addr, (uint64_t)size, read, write);
2365
2366    const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
2367
2368    // Can't watch zero bytes
2369    if (size == 0)
2370        return INVALID_NUB_HW_INDEX;
2371
2372    // We must watch for either read or write
2373    if (read == false && write == false)
2374        return INVALID_NUB_HW_INDEX;
2375
2376    // Divide-and-conquer for size == 8.
2377    if (size == 8)
2378    {
2379        uint32_t lo = EnableHardwareWatchpoint(addr, 4, read, write);
2380        if (lo == INVALID_NUB_HW_INDEX)
2381            return INVALID_NUB_HW_INDEX;
2382        uint32_t hi = EnableHardwareWatchpoint(addr+4, 4, read, write);
2383        if (hi == INVALID_NUB_HW_INDEX)
2384        {
2385            DisableHardwareWatchpoint(lo);
2386            return INVALID_NUB_HW_INDEX;
2387        }
2388        // Tag this lo->hi mapping in our database.
2389        LoHi[lo] = hi;
2390        return lo;
2391    }
2392
2393    // Otherwise, can't watch more than 4 bytes per WVR/WCR pair
2394    if (size > 4)
2395        return INVALID_NUB_HW_INDEX;
2396
2397    // We can only watch up to four bytes that follow a 4 byte aligned address
2398    // per watchpoint register pair. Since we can only watch until the next 4
2399    // byte boundary, we need to make sure we can properly encode this.
2400
2401    // addr_word_offset = addr % 4, i.e, is in set([0, 1, 2, 3])
2402    //
2403    //     +---+---+---+---+
2404    //     | 0 | 1 | 2 | 3 |
2405    //     +---+---+---+---+
2406    //     ^
2407    //     |
2408    // word address (4-byte aligned) = addr & 0xFFFFFFFC => goes into WVR
2409    //
2410    // examples:
2411    // 1. addr_word_offset = 1, size = 1 to watch a uint_8 => byte_mask = (0b0001 << 1) = 0b0010
2412    // 2. addr_word_offset = 2, size = 2 to watch a uint_16 => byte_mask = (0b0011 << 2) = 0b1100
2413    //
2414    // where byte_mask goes into WCR[8:5]
2415
2416    uint32_t addr_word_offset = addr % 4;
2417    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
2418
2419    uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
2420    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
2421    if (byte_mask > 0xfu)
2422        return INVALID_NUB_HW_INDEX;
2423
2424    // Read the debug state
2425    kern_return_t kret = GetDBGState(false);
2426
2427    if (kret == KERN_SUCCESS)
2428    {
2429        // Check to make sure we have the needed hardware support
2430        uint32_t i = 0;
2431
2432        for (i=0; i<num_hw_watchpoints; ++i)
2433        {
2434            if ((m_state.dbg.__wcr[i] & WCR_ENABLE) == 0)
2435                break; // We found an available hw watchpoint slot (in i)
2436        }
2437
2438        // See if we found an available hw watchpoint slot above
2439        if (i < num_hw_watchpoints)
2440        {
2441            //DumpDBGState(m_state.dbg);
2442
2443            // Make the byte_mask into a valid Byte Address Select mask
2444            uint32_t byte_address_select = byte_mask << 5;
2445            // Make sure bits 1:0 are clear in our address
2446            m_state.dbg.__wvr[i] = addr & ~((nub_addr_t)3);     // DVA (Data Virtual Address)
2447            m_state.dbg.__wcr[i] =  byte_address_select |       // Which bytes that follow the DVA that we will watch
2448                                    S_USER |                    // Stop only in user mode
2449                                    (read ? WCR_LOAD : 0) |     // Stop on read access?
2450                                    (write ? WCR_STORE : 0) |   // Stop on write access?
2451                                    WCR_ENABLE;                 // Enable this watchpoint;
2452
2453            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() adding watchpoint on address 0x%llx with control register value 0x%x", (uint64_t) m_state.dbg.__wvr[i], (uint32_t) m_state.dbg.__wcr[i]);
2454
2455            kret = SetDBGState();
2456            //DumpDBGState(m_state.dbg);
2457
2458            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret);
2459
2460            if (kret == KERN_SUCCESS)
2461                return i;
2462        }
2463        else
2464        {
2465            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
2466        }
2467    }
2468    return INVALID_NUB_HW_INDEX;
2469}
2470
2471bool
2472DNBArchMachARM::EnableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate)
2473{
2474    kern_return_t kret = GetDBGState(false);
2475    if (kret != KERN_SUCCESS)
2476        return false;
2477
2478    const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
2479    if (hw_index >= num_hw_points)
2480        return false;
2481
2482    if (Delegate && LoHi[hw_index]) {
2483        // Enable lo and hi watchpoint hardware indexes.
2484        return EnableHardwareWatchpoint0(hw_index, false) &&
2485            EnableHardwareWatchpoint0(LoHi[hw_index], false);
2486    }
2487
2488    m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE;
2489    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
2490                     hw_index,
2491                     hw_index,
2492                     m_state.dbg.__wvr[hw_index],
2493                     hw_index,
2494                     m_state.dbg.__wcr[hw_index]);
2495
2496    kret = SetDBGState();
2497
2498    return (kret == KERN_SUCCESS);
2499}
2500
2501bool
2502DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index)
2503{
2504    return DisableHardwareWatchpoint0(hw_index, true);
2505}
2506bool
2507DNBArchMachARM::DisableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate)
2508{
2509    kern_return_t kret = GetDBGState(false);
2510    if (kret != KERN_SUCCESS)
2511        return false;
2512
2513    const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
2514    if (hw_index >= num_hw_points)
2515        return false;
2516
2517    if (Delegate && LoHi[hw_index]) {
2518        // Disable lo and hi watchpoint hardware indexes.
2519        return DisableHardwareWatchpoint0(hw_index, false) &&
2520            DisableHardwareWatchpoint0(LoHi[hw_index], false);
2521    }
2522
2523    m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE);
2524    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
2525                     hw_index,
2526                     hw_index,
2527                     m_state.dbg.__wvr[hw_index],
2528                     hw_index,
2529                     m_state.dbg.__wcr[hw_index]);
2530
2531    kret = SetDBGState();
2532
2533    return (kret == KERN_SUCCESS);
2534}
2535
2536// {0} -> __bvr[16], {0} -> __bcr[16], {0} --> __wvr[16], {0} -> __wcr{16}
2537DNBArchMachARM::DBG DNBArchMachARM::Global_Debug_State = {{0},{0},{0},{0}};
2538bool DNBArchMachARM::Valid_Global_Debug_State = false;
2539
2540// Use this callback from MachThread, which in turn was called from MachThreadList, to update
2541// the global view of the hardware watchpoint state, so that when new thread comes along, they
2542// get to inherit the existing hardware watchpoint state.
2543void
2544DNBArchMachARM::HardwareWatchpointStateChanged ()
2545{
2546    Global_Debug_State = m_state.dbg;
2547    Valid_Global_Debug_State = true;
2548}
2549
2550// Returns -1 if the trailing bit patterns are not one of:
2551// { 0b???1, 0b??10, 0b?100, 0b1000 }.
2552static inline
2553int32_t
2554LowestBitSet(uint32_t val)
2555{
2556    for (unsigned i = 0; i < 4; ++i) {
2557        if (bit(val, i))
2558            return i;
2559    }
2560    return -1;
2561}
2562
2563// Iterate through the debug registers; return the index of the first watchpoint whose address matches.
2564// As a side effect, the starting address as understood by the debugger is returned which could be
2565// different from 'addr' passed as an in/out argument.
2566uint32_t
2567DNBArchMachARM::GetHardwareWatchpointHit(nub_addr_t &addr)
2568{
2569    // Read the debug state
2570    kern_return_t kret = GetDBGState(true);
2571    //DumpDBGState(m_state.dbg);
2572    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret);
2573    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::GetHardwareWatchpointHit() addr = 0x%llx", (uint64_t)addr);
2574
2575    // This is the watchpoint value to match against, i.e., word address.
2576    nub_addr_t wp_val = addr & ~((nub_addr_t)3);
2577    if (kret == KERN_SUCCESS)
2578    {
2579        DBG &debug_state = m_state.dbg;
2580        uint32_t i, num = NumSupportedHardwareWatchpoints();
2581        for (i = 0; i < num; ++i)
2582        {
2583            nub_addr_t wp_addr = GetWatchAddress(debug_state, i);
2584            DNBLogThreadedIf(LOG_WATCHPOINTS,
2585                             "DNBArchMachARM::GetHardwareWatchpointHit() slot: %u (addr = 0x%llx).",
2586                             i, (uint64_t)wp_addr);
2587            if (wp_val == wp_addr) {
2588                uint32_t byte_mask = bits(debug_state.__wcr[i], 8, 5);
2589
2590                // Sanity check the byte_mask, first.
2591                if (LowestBitSet(byte_mask) < 0)
2592                    continue;
2593
2594                // Compute the starting address (from the point of view of the debugger).
2595                addr = wp_addr + LowestBitSet(byte_mask);
2596                return i;
2597            }
2598        }
2599    }
2600    return INVALID_NUB_HW_INDEX;
2601}
2602
2603// ThreadWillResume() calls this to clear bits[5:2] (Method of entry bits) of
2604// the Debug Status and Control Register (DSCR).
2605//
2606// b0010 = a watchpoint occurred
2607// b0000 is the reset value
2608void
2609DNBArchMachARM::ClearWatchpointOccurred()
2610{
2611    uint32_t register_DBGDSCR;
2612    asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR));
2613    if (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED)
2614    {
2615        uint32_t mask = ~(0xF << 2);
2616        register_DBGDSCR &= mask;
2617        asm("mcr p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR));
2618    }
2619    return;
2620}
2621
2622// NotifyException() calls this to double check that a watchpoint has occurred
2623// by inspecting the bits[5:2] field of the Debug Status and Control Register
2624// (DSCR).
2625//
2626// b0010 = a watchpoint occurred
2627bool
2628DNBArchMachARM::HasWatchpointOccurred()
2629{
2630    uint32_t register_DBGDSCR;
2631    asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR));
2632    return (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED);
2633}
2634
2635bool
2636DNBArchMachARM::IsWatchpointEnabled(const DBG &debug_state, uint32_t hw_index)
2637{
2638    // Watchpoint Control Registers, bitfield definitions
2639    // ...
2640    // Bits    Value    Description
2641    // [0]     0        Watchpoint disabled
2642    //         1        Watchpoint enabled.
2643    return (debug_state.__wcr[hw_index] & 1u);
2644}
2645
2646nub_addr_t
2647DNBArchMachARM::GetWatchAddress(const DBG &debug_state, uint32_t hw_index)
2648{
2649    // Watchpoint Value Registers, bitfield definitions
2650    // Bits        Description
2651    // [31:2]      Watchpoint value (word address, i.e., 4-byte aligned)
2652    // [1:0]       RAZ/SBZP
2653    return bits(debug_state.__wvr[hw_index], 31, 0);
2654}
2655
2656//----------------------------------------------------------------------
2657// Register information defintions for 32 bit ARMV6.
2658//----------------------------------------------------------------------
2659enum gpr_regnums
2660{
2661    gpr_r0 = 0,
2662    gpr_r1,
2663    gpr_r2,
2664    gpr_r3,
2665    gpr_r4,
2666    gpr_r5,
2667    gpr_r6,
2668    gpr_r7,
2669    gpr_r8,
2670    gpr_r9,
2671    gpr_r10,
2672    gpr_r11,
2673    gpr_r12,
2674    gpr_sp,
2675    gpr_lr,
2676    gpr_pc,
2677    gpr_cpsr
2678};
2679
2680enum
2681{
2682    vfp_s0 = 0,
2683    vfp_s1,
2684    vfp_s2,
2685    vfp_s3,
2686    vfp_s4,
2687    vfp_s5,
2688    vfp_s6,
2689    vfp_s7,
2690    vfp_s8,
2691    vfp_s9,
2692    vfp_s10,
2693    vfp_s11,
2694    vfp_s12,
2695    vfp_s13,
2696    vfp_s14,
2697    vfp_s15,
2698    vfp_s16,
2699    vfp_s17,
2700    vfp_s18,
2701    vfp_s19,
2702    vfp_s20,
2703    vfp_s21,
2704    vfp_s22,
2705    vfp_s23,
2706    vfp_s24,
2707    vfp_s25,
2708    vfp_s26,
2709    vfp_s27,
2710    vfp_s28,
2711    vfp_s29,
2712    vfp_s30,
2713    vfp_s31,
2714    vfp_d0,
2715    vfp_d1,
2716    vfp_d2,
2717    vfp_d3,
2718    vfp_d4,
2719    vfp_d5,
2720    vfp_d6,
2721    vfp_d7,
2722    vfp_d8,
2723    vfp_d9,
2724    vfp_d10,
2725    vfp_d11,
2726    vfp_d12,
2727    vfp_d13,
2728    vfp_d14,
2729    vfp_d15,
2730    vfp_d16,
2731    vfp_d17,
2732    vfp_d18,
2733    vfp_d19,
2734    vfp_d20,
2735    vfp_d21,
2736    vfp_d22,
2737    vfp_d23,
2738    vfp_d24,
2739    vfp_d25,
2740    vfp_d26,
2741    vfp_d27,
2742    vfp_d28,
2743    vfp_d29,
2744    vfp_d30,
2745    vfp_d31,
2746    vfp_fpscr
2747};
2748
2749enum
2750{
2751    exc_exception,
2752	exc_fsr,
2753	exc_far,
2754};
2755
2756enum
2757{
2758    gdb_r0 = 0,
2759    gdb_r1,
2760    gdb_r2,
2761    gdb_r3,
2762    gdb_r4,
2763    gdb_r5,
2764    gdb_r6,
2765    gdb_r7,
2766    gdb_r8,
2767    gdb_r9,
2768    gdb_r10,
2769    gdb_r11,
2770    gdb_r12,
2771    gdb_sp,
2772    gdb_lr,
2773    gdb_pc,
2774    gdb_f0,
2775    gdb_f1,
2776    gdb_f2,
2777    gdb_f3,
2778    gdb_f4,
2779    gdb_f5,
2780    gdb_f6,
2781    gdb_f7,
2782    gdb_f8,
2783    gdb_cpsr,
2784    gdb_s0,
2785    gdb_s1,
2786    gdb_s2,
2787    gdb_s3,
2788    gdb_s4,
2789    gdb_s5,
2790    gdb_s6,
2791    gdb_s7,
2792    gdb_s8,
2793    gdb_s9,
2794    gdb_s10,
2795    gdb_s11,
2796    gdb_s12,
2797    gdb_s13,
2798    gdb_s14,
2799    gdb_s15,
2800    gdb_s16,
2801    gdb_s17,
2802    gdb_s18,
2803    gdb_s19,
2804    gdb_s20,
2805    gdb_s21,
2806    gdb_s22,
2807    gdb_s23,
2808    gdb_s24,
2809    gdb_s25,
2810    gdb_s26,
2811    gdb_s27,
2812    gdb_s28,
2813    gdb_s29,
2814    gdb_s30,
2815    gdb_s31,
2816    gdb_fpscr,
2817    gdb_d0,
2818    gdb_d1,
2819    gdb_d2,
2820    gdb_d3,
2821    gdb_d4,
2822    gdb_d5,
2823    gdb_d6,
2824    gdb_d7,
2825    gdb_d8,
2826    gdb_d9,
2827    gdb_d10,
2828    gdb_d11,
2829    gdb_d12,
2830    gdb_d13,
2831    gdb_d14,
2832    gdb_d15
2833};
2834
2835#define GPR_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::GPR, __r[idx]))
2836#define GPR_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::GPR, __##reg))
2837#define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[(idx)]) + offsetof (DNBArchMachARM::Context, vfp))
2838#define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 2))
2839#define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::FPU, __##reg) + offsetof (DNBArchMachARM::Context, vfp))
2840#define EXC_OFFSET(reg)      (offsetof (DNBArchMachARM::EXC, __##reg)  + offsetof (DNBArchMachARM::Context, exc))
2841
2842// These macros will auto define the register name, alt name, register size,
2843// register offset, encoding, format and native register. This ensures that
2844// the register state structures are defined correctly and have the correct
2845// sizes and offsets.
2846#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, gdb_##reg, NULL, NULL}
2847#define DEFINE_GPR_NAME(reg, alt, gen, inval) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, gdb_##reg, NULL, inval}
2848//#define FLOAT_FORMAT Float
2849#define FLOAT_FORMAT Hex
2850#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx, NULL, NULL}
2851//#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, Float, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, gdb_d##idx }
2852#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
2853
2854// In case we are debugging to a debug target that the ability to
2855// change into the protected modes with folded registers (ABT, IRQ,
2856// FIQ, SYS, USR, etc..), we should invalidate r8-r14 if the CPSR
2857// gets modified.
2858
2859uint32_t g_invalidate_cpsr[] = {
2860    gpr_r8,
2861    gpr_r9,
2862    gpr_r10,
2863    gpr_r11,
2864    gpr_r12,
2865    gpr_sp,
2866    gpr_lr,
2867    INVALID_NUB_REGNUM };
2868
2869// General purpose registers
2870const DNBRegisterInfo
2871DNBArchMachARM::g_gpr_registers[] =
2872{
2873    DEFINE_GPR_IDX ( 0,  r0,"arg1", GENERIC_REGNUM_ARG1  ),
2874    DEFINE_GPR_IDX ( 1,  r1,"arg2", GENERIC_REGNUM_ARG2  ),
2875    DEFINE_GPR_IDX ( 2,  r2,"arg3", GENERIC_REGNUM_ARG3  ),
2876    DEFINE_GPR_IDX ( 3,  r3,"arg4", GENERIC_REGNUM_ARG4  ),
2877    DEFINE_GPR_IDX ( 4,  r4,  NULL, INVALID_NUB_REGNUM   ),
2878    DEFINE_GPR_IDX ( 5,  r5,  NULL, INVALID_NUB_REGNUM   ),
2879    DEFINE_GPR_IDX ( 6,  r6,  NULL, INVALID_NUB_REGNUM   ),
2880    DEFINE_GPR_IDX ( 7,  r7,  "fp", GENERIC_REGNUM_FP    ),
2881    DEFINE_GPR_IDX ( 8,  r8,  NULL, INVALID_NUB_REGNUM   ),
2882    DEFINE_GPR_IDX ( 9,  r9,  NULL, INVALID_NUB_REGNUM   ),
2883    DEFINE_GPR_IDX (10, r10,  NULL, INVALID_NUB_REGNUM   ),
2884    DEFINE_GPR_IDX (11, r11,  NULL, INVALID_NUB_REGNUM   ),
2885    DEFINE_GPR_IDX (12, r12,  NULL, INVALID_NUB_REGNUM   ),
2886    DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP, NULL),
2887    DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA, NULL),
2888    DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC, NULL),
2889    DEFINE_GPR_NAME (cpsr, "flags", GENERIC_REGNUM_FLAGS, g_invalidate_cpsr)
2890};
2891
2892// Floating point registers
2893const DNBRegisterInfo
2894DNBArchMachARM::g_vfp_registers[] =
2895{
2896    DEFINE_VFP_S_IDX ( 0),
2897    DEFINE_VFP_S_IDX ( 1),
2898    DEFINE_VFP_S_IDX ( 2),
2899    DEFINE_VFP_S_IDX ( 3),
2900    DEFINE_VFP_S_IDX ( 4),
2901    DEFINE_VFP_S_IDX ( 5),
2902    DEFINE_VFP_S_IDX ( 6),
2903    DEFINE_VFP_S_IDX ( 7),
2904    DEFINE_VFP_S_IDX ( 8),
2905    DEFINE_VFP_S_IDX ( 9),
2906    DEFINE_VFP_S_IDX (10),
2907    DEFINE_VFP_S_IDX (11),
2908    DEFINE_VFP_S_IDX (12),
2909    DEFINE_VFP_S_IDX (13),
2910    DEFINE_VFP_S_IDX (14),
2911    DEFINE_VFP_S_IDX (15),
2912    DEFINE_VFP_S_IDX (16),
2913    DEFINE_VFP_S_IDX (17),
2914    DEFINE_VFP_S_IDX (18),
2915    DEFINE_VFP_S_IDX (19),
2916    DEFINE_VFP_S_IDX (20),
2917    DEFINE_VFP_S_IDX (21),
2918    DEFINE_VFP_S_IDX (22),
2919    DEFINE_VFP_S_IDX (23),
2920    DEFINE_VFP_S_IDX (24),
2921    DEFINE_VFP_S_IDX (25),
2922    DEFINE_VFP_S_IDX (26),
2923    DEFINE_VFP_S_IDX (27),
2924    DEFINE_VFP_S_IDX (28),
2925    DEFINE_VFP_S_IDX (29),
2926    DEFINE_VFP_S_IDX (30),
2927    DEFINE_VFP_S_IDX (31),
2928    DEFINE_VFP_D_IDX (0),
2929    DEFINE_VFP_D_IDX (1),
2930    DEFINE_VFP_D_IDX (2),
2931    DEFINE_VFP_D_IDX (3),
2932    DEFINE_VFP_D_IDX (4),
2933    DEFINE_VFP_D_IDX (5),
2934    DEFINE_VFP_D_IDX (6),
2935    DEFINE_VFP_D_IDX (7),
2936    DEFINE_VFP_D_IDX (8),
2937    DEFINE_VFP_D_IDX (9),
2938    DEFINE_VFP_D_IDX (10),
2939    DEFINE_VFP_D_IDX (11),
2940    DEFINE_VFP_D_IDX (12),
2941    DEFINE_VFP_D_IDX (13),
2942    DEFINE_VFP_D_IDX (14),
2943    DEFINE_VFP_D_IDX (15),
2944    DEFINE_VFP_D_IDX (16),
2945    DEFINE_VFP_D_IDX (17),
2946    DEFINE_VFP_D_IDX (18),
2947    DEFINE_VFP_D_IDX (19),
2948    DEFINE_VFP_D_IDX (20),
2949    DEFINE_VFP_D_IDX (21),
2950    DEFINE_VFP_D_IDX (22),
2951    DEFINE_VFP_D_IDX (23),
2952    DEFINE_VFP_D_IDX (24),
2953    DEFINE_VFP_D_IDX (25),
2954    DEFINE_VFP_D_IDX (26),
2955    DEFINE_VFP_D_IDX (27),
2956    DEFINE_VFP_D_IDX (28),
2957    DEFINE_VFP_D_IDX (29),
2958    DEFINE_VFP_D_IDX (30),
2959    DEFINE_VFP_D_IDX (31),
2960    { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr, NULL, NULL }
2961};
2962
2963// Exception registers
2964
2965const DNBRegisterInfo
2966DNBArchMachARM::g_exc_registers[] =
2967{
2968  { e_regSetVFP, exc_exception  , "exception"   , NULL, Uint, Hex, 4, EXC_OFFSET(exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
2969  { e_regSetVFP, exc_fsr        , "fsr"         , NULL, Uint, Hex, 4, EXC_OFFSET(fsr)       , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
2970  { e_regSetVFP, exc_far        , "far"         , NULL, Uint, Hex, 4, EXC_OFFSET(far)       , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
2971};
2972
2973// Number of registers in each register set
2974const size_t DNBArchMachARM::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo);
2975const size_t DNBArchMachARM::k_num_vfp_registers = sizeof(g_vfp_registers)/sizeof(DNBRegisterInfo);
2976const size_t DNBArchMachARM::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo);
2977const size_t DNBArchMachARM::k_num_all_registers = k_num_gpr_registers + k_num_vfp_registers + k_num_exc_registers;
2978
2979//----------------------------------------------------------------------
2980// Register set definitions. The first definitions at register set index
2981// of zero is for all registers, followed by other registers sets. The
2982// register information for the all register set need not be filled in.
2983//----------------------------------------------------------------------
2984const DNBRegisterSetInfo
2985DNBArchMachARM::g_reg_sets[] =
2986{
2987    { "ARM Registers",              NULL,               k_num_all_registers     },
2988    { "General Purpose Registers",  g_gpr_registers,    k_num_gpr_registers     },
2989    { "Floating Point Registers",   g_vfp_registers,    k_num_vfp_registers     },
2990    { "Exception State Registers",  g_exc_registers,    k_num_exc_registers     }
2991};
2992// Total number of register sets for this architecture
2993const size_t DNBArchMachARM::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);
2994
2995
2996const DNBRegisterSetInfo *
2997DNBArchMachARM::GetRegisterSetInfo(nub_size_t *num_reg_sets)
2998{
2999    *num_reg_sets = k_num_register_sets;
3000    return g_reg_sets;
3001}
3002
3003bool
3004DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
3005{
3006    if (set == REGISTER_SET_GENERIC)
3007    {
3008        switch (reg)
3009        {
3010        case GENERIC_REGNUM_PC:     // Program Counter
3011            set = e_regSetGPR;
3012            reg = gpr_pc;
3013            break;
3014
3015        case GENERIC_REGNUM_SP:     // Stack Pointer
3016            set = e_regSetGPR;
3017            reg = gpr_sp;
3018            break;
3019
3020        case GENERIC_REGNUM_FP:     // Frame Pointer
3021            set = e_regSetGPR;
3022            reg = gpr_r7;   // is this the right reg?
3023            break;
3024
3025        case GENERIC_REGNUM_RA:     // Return Address
3026            set = e_regSetGPR;
3027            reg = gpr_lr;
3028            break;
3029
3030        case GENERIC_REGNUM_FLAGS:  // Processor flags register
3031            set = e_regSetGPR;
3032            reg = gpr_cpsr;
3033            break;
3034
3035        default:
3036            return false;
3037        }
3038    }
3039
3040    if (GetRegisterState(set, false) != KERN_SUCCESS)
3041        return false;
3042
3043    const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
3044    if (regInfo)
3045    {
3046        value->info = *regInfo;
3047        switch (set)
3048        {
3049        case e_regSetGPR:
3050            if (reg < k_num_gpr_registers)
3051            {
3052                value->value.uint32 = m_state.context.gpr.__r[reg];
3053                return true;
3054            }
3055            break;
3056
3057        case e_regSetVFP:
3058            if (reg <= vfp_s31)
3059            {
3060                value->value.uint32 = m_state.context.vfp.__r[reg];
3061                return true;
3062            }
3063            else if (reg <= vfp_d31)
3064            {
3065                uint32_t d_reg_idx = reg - vfp_d0;
3066                uint32_t s_reg_idx = d_reg_idx * 2;
3067                value->value.v_sint32[0] = m_state.context.vfp.__r[s_reg_idx + 0];
3068                value->value.v_sint32[1] = m_state.context.vfp.__r[s_reg_idx + 1];
3069                return true;
3070            }
3071            else if (reg == vfp_fpscr)
3072            {
3073                value->value.uint32 = m_state.context.vfp.__fpscr;
3074                return true;
3075            }
3076            break;
3077
3078        case e_regSetEXC:
3079            if (reg < k_num_exc_registers)
3080            {
3081                value->value.uint32 = (&m_state.context.exc.__exception)[reg];
3082                return true;
3083            }
3084            break;
3085        }
3086    }
3087    return false;
3088}
3089
3090bool
3091DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value)
3092{
3093    if (set == REGISTER_SET_GENERIC)
3094    {
3095        switch (reg)
3096        {
3097        case GENERIC_REGNUM_PC:     // Program Counter
3098            set = e_regSetGPR;
3099            reg = gpr_pc;
3100            break;
3101
3102        case GENERIC_REGNUM_SP:     // Stack Pointer
3103            set = e_regSetGPR;
3104            reg = gpr_sp;
3105            break;
3106
3107        case GENERIC_REGNUM_FP:     // Frame Pointer
3108            set = e_regSetGPR;
3109            reg = gpr_r7;
3110            break;
3111
3112        case GENERIC_REGNUM_RA:     // Return Address
3113            set = e_regSetGPR;
3114            reg = gpr_lr;
3115            break;
3116
3117        case GENERIC_REGNUM_FLAGS:  // Processor flags register
3118            set = e_regSetGPR;
3119            reg = gpr_cpsr;
3120            break;
3121
3122        default:
3123            return false;
3124        }
3125    }
3126
3127    if (GetRegisterState(set, false) != KERN_SUCCESS)
3128        return false;
3129
3130    bool success = false;
3131    const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
3132    if (regInfo)
3133    {
3134        switch (set)
3135        {
3136        case e_regSetGPR:
3137            if (reg < k_num_gpr_registers)
3138            {
3139                m_state.context.gpr.__r[reg] = value->value.uint32;
3140                success = true;
3141            }
3142            break;
3143
3144        case e_regSetVFP:
3145            if (reg <= vfp_s31)
3146            {
3147                m_state.context.vfp.__r[reg] = value->value.uint32;
3148                success = true;
3149            }
3150            else if (reg <= vfp_d31)
3151            {
3152                uint32_t d_reg_idx = reg - vfp_d0;
3153                uint32_t s_reg_idx = d_reg_idx * 2;
3154                m_state.context.vfp.__r[s_reg_idx + 0] = value->value.v_sint32[0];
3155                m_state.context.vfp.__r[s_reg_idx + 1] = value->value.v_sint32[1];
3156                success = true;
3157            }
3158            else if (reg == vfp_fpscr)
3159            {
3160                m_state.context.vfp.__fpscr = value->value.uint32;
3161                success = true;
3162            }
3163            break;
3164
3165        case e_regSetEXC:
3166            if (reg < k_num_exc_registers)
3167            {
3168                (&m_state.context.exc.__exception)[reg] = value->value.uint32;
3169                success = true;
3170            }
3171            break;
3172        }
3173
3174    }
3175    if (success)
3176        return SetRegisterState(set) == KERN_SUCCESS;
3177    return false;
3178}
3179
3180kern_return_t
3181DNBArchMachARM::GetRegisterState(int set, bool force)
3182{
3183    switch (set)
3184    {
3185    case e_regSetALL:   return GetGPRState(force) |
3186                               GetVFPState(force) |
3187                               GetEXCState(force) |
3188                               GetDBGState(force);
3189    case e_regSetGPR:   return GetGPRState(force);
3190    case e_regSetVFP:   return GetVFPState(force);
3191    case e_regSetEXC:   return GetEXCState(force);
3192    case e_regSetDBG:   return GetDBGState(force);
3193    default: break;
3194    }
3195    return KERN_INVALID_ARGUMENT;
3196}
3197
3198kern_return_t
3199DNBArchMachARM::SetRegisterState(int set)
3200{
3201    // Make sure we have a valid context to set.
3202    kern_return_t err = GetRegisterState(set, false);
3203    if (err != KERN_SUCCESS)
3204        return err;
3205
3206    switch (set)
3207    {
3208    case e_regSetALL:   return SetGPRState() |
3209                               SetVFPState() |
3210                               SetEXCState() |
3211                               SetDBGState();
3212    case e_regSetGPR:   return SetGPRState();
3213    case e_regSetVFP:   return SetVFPState();
3214    case e_regSetEXC:   return SetEXCState();
3215    case e_regSetDBG:   return SetDBGState();
3216    default: break;
3217    }
3218    return KERN_INVALID_ARGUMENT;
3219}
3220
3221bool
3222DNBArchMachARM::RegisterSetStateIsValid (int set) const
3223{
3224    return m_state.RegsAreValid(set);
3225}
3226
3227
3228nub_size_t
3229DNBArchMachARM::GetRegisterContext (void *buf, nub_size_t buf_len)
3230{
3231    nub_size_t size = sizeof (m_state.context);
3232
3233    if (buf && buf_len)
3234    {
3235        if (size > buf_len)
3236            size = buf_len;
3237
3238        bool force = false;
3239        if (GetGPRState(force) | GetVFPState(force) | GetEXCState(force))
3240            return 0;
3241        ::memcpy (buf, &m_state.context, size);
3242    }
3243    DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::GetRegisterContext (buf = %p, len = %llu) => %llu", buf, (uint64_t)buf_len, (uint64_t)size);
3244    // Return the size of the register context even if NULL was passed in
3245    return size;
3246}
3247
3248nub_size_t
3249DNBArchMachARM::SetRegisterContext (const void *buf, nub_size_t buf_len)
3250{
3251    nub_size_t size = sizeof (m_state.context);
3252    if (buf == NULL || buf_len == 0)
3253        size = 0;
3254
3255    if (size)
3256    {
3257        if (size > buf_len)
3258            size = buf_len;
3259
3260        ::memcpy (&m_state.context, buf, size);
3261        SetGPRState();
3262        SetVFPState();
3263        SetEXCState();
3264    }
3265    DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::SetRegisterContext (buf = %p, len = %llu) => %llu", buf, (uint64_t)buf_len, (uint64_t)size);
3266    return size;
3267}
3268
3269
3270#endif    // #if defined (__arm__)
3271
3272