Home | History | Annotate | Download | only in MacOSX-arm
      1 //===-- ABIMacOSX_arm.cpp --------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "ABIMacOSX_arm.h"
     11 
     12 #include "lldb/Core/ConstString.h"
     13 #include "lldb/Core/Error.h"
     14 #include "lldb/Core/Module.h"
     15 #include "lldb/Core/PluginManager.h"
     16 #include "lldb/Core/RegisterValue.h"
     17 #include "lldb/Core/Scalar.h"
     18 #include "lldb/Core/Value.h"
     19 #include "lldb/Core/ValueObjectConstResult.h"
     20 #include "lldb/Symbol/ClangASTContext.h"
     21 #include "lldb/Symbol/UnwindPlan.h"
     22 #include "lldb/Target/Process.h"
     23 #include "lldb/Target/RegisterContext.h"
     24 #include "lldb/Target/Target.h"
     25 #include "lldb/Target/Thread.h"
     26 
     27 #include "llvm/ADT/Triple.h"
     28 
     29 #include "Utility/ARM_DWARF_Registers.h"
     30 #include "Utility/ARM_GCC_Registers.h"
     31 #include "Plugins/Process/Utility/ARMDefines.h"
     32 
     33 #include <vector>
     34 
     35 using namespace lldb;
     36 using namespace lldb_private;
     37 
     38 static RegisterInfo g_register_infos[] =
     39 {
     40     //  NAME       ALT       SZ OFF ENCODING         FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE            VALUE REGS    INVALIDATE REGS
     41     //  ========== =======   == === =============    ============    ======================= =================== =========================== ======================= ====================== ==========    ===============
     42     {   "r0",      "arg1",    4, 0, eEncodingUint    , eFormatHex,   { gcc_r0,               dwarf_r0,           LLDB_REGNUM_GENERIC_ARG1,   gdb_arm_r0,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     43     {   "r1",      "arg2",    4, 0, eEncodingUint    , eFormatHex,   { gcc_r1,               dwarf_r1,           LLDB_REGNUM_GENERIC_ARG2,   gdb_arm_r1,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     44     {   "r2",      "arg3",    4, 0, eEncodingUint    , eFormatHex,   { gcc_r2,               dwarf_r2,           LLDB_REGNUM_GENERIC_ARG3,   gdb_arm_r2,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     45     {   "r3",      "arg4",    4, 0, eEncodingUint    , eFormatHex,   { gcc_r3,               dwarf_r3,           LLDB_REGNUM_GENERIC_ARG4,   gdb_arm_r3,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     46     {   "r4",      NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r4,               dwarf_r4,           LLDB_INVALID_REGNUM,        gdb_arm_r4,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     47     {   "r5",      NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r5,               dwarf_r5,           LLDB_INVALID_REGNUM,        gdb_arm_r5,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     48     {   "r6",      NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r6,               dwarf_r6,           LLDB_INVALID_REGNUM,        gdb_arm_r6,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     49     {   "r7",      NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r7,               dwarf_r7,           LLDB_REGNUM_GENERIC_FP,     gdb_arm_r7,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     50     {   "r8",      NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r8,               dwarf_r8,           LLDB_INVALID_REGNUM,        gdb_arm_r8,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     51     {   "r9",      NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r9,               dwarf_r9,           LLDB_INVALID_REGNUM,        gdb_arm_r9,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     52     {   "r10",     NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r10,              dwarf_r10,          LLDB_INVALID_REGNUM,        gdb_arm_r10,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     53     {   "r11",     NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r11,              dwarf_r11,          LLDB_INVALID_REGNUM,        gdb_arm_r11,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     54     {   "r12",     NULL,      4, 0, eEncodingUint    , eFormatHex,   { gcc_r12,              dwarf_r12,          LLDB_INVALID_REGNUM,        gdb_arm_r12,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     55     {   "sp",      "r13",     4, 0, eEncodingUint    , eFormatHex,   { gcc_sp,               dwarf_sp,           LLDB_REGNUM_GENERIC_SP,     gdb_arm_sp,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     56     {   "lr",      "r14",     4, 0, eEncodingUint    , eFormatHex,   { gcc_lr,               dwarf_lr,           LLDB_REGNUM_GENERIC_RA,     gdb_arm_lr,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     57     {   "pc",      "r15",     4, 0, eEncodingUint    , eFormatHex,   { gcc_pc,               dwarf_pc,           LLDB_REGNUM_GENERIC_PC,     gdb_arm_pc,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     58     {   "cpsr",    "psr",     4, 0, eEncodingUint    , eFormatHex,   { gcc_cpsr,             dwarf_cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  gdb_arm_cpsr,           LLDB_INVALID_REGNUM },      NULL,              NULL},
     59     {   "s0",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s0,           LLDB_INVALID_REGNUM,        gdb_arm_s0,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     60     {   "s1",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s1,           LLDB_INVALID_REGNUM,        gdb_arm_s1,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     61     {   "s2",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s2,           LLDB_INVALID_REGNUM,        gdb_arm_s2,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     62     {   "s3",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s3,           LLDB_INVALID_REGNUM,        gdb_arm_s3,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     63     {   "s4",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s4,           LLDB_INVALID_REGNUM,        gdb_arm_s4,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     64     {   "s5",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s5,           LLDB_INVALID_REGNUM,        gdb_arm_s5,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     65     {   "s6",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s6,           LLDB_INVALID_REGNUM,        gdb_arm_s6,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     66     {   "s7",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s7,           LLDB_INVALID_REGNUM,        gdb_arm_s7,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     67     {   "s8",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s8,           LLDB_INVALID_REGNUM,        gdb_arm_s8,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     68     {   "s9",      NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s9,           LLDB_INVALID_REGNUM,        gdb_arm_s9,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     69     {   "s10",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s10,          LLDB_INVALID_REGNUM,        gdb_arm_s10,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     70     {   "s11",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s11,          LLDB_INVALID_REGNUM,        gdb_arm_s11,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     71     {   "s12",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s12,          LLDB_INVALID_REGNUM,        gdb_arm_s12,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     72     {   "s13",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s13,          LLDB_INVALID_REGNUM,        gdb_arm_s13,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     73     {   "s14",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s14,          LLDB_INVALID_REGNUM,        gdb_arm_s14,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     74     {   "s15",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s15,          LLDB_INVALID_REGNUM,        gdb_arm_s15,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     75     {   "s16",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s16,          LLDB_INVALID_REGNUM,        gdb_arm_s16,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     76     {   "s17",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s17,          LLDB_INVALID_REGNUM,        gdb_arm_s17,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     77     {   "s18",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s18,          LLDB_INVALID_REGNUM,        gdb_arm_s18,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     78     {   "s19",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s19,          LLDB_INVALID_REGNUM,        gdb_arm_s19,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     79     {   "s20",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s20,          LLDB_INVALID_REGNUM,        gdb_arm_s20,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     80     {   "s21",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s21,          LLDB_INVALID_REGNUM,        gdb_arm_s21,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     81     {   "s22",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s22,          LLDB_INVALID_REGNUM,        gdb_arm_s22,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     82     {   "s23",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s23,          LLDB_INVALID_REGNUM,        gdb_arm_s23,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     83     {   "s24",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s24,          LLDB_INVALID_REGNUM,        gdb_arm_s24,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     84     {   "s25",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s25,          LLDB_INVALID_REGNUM,        gdb_arm_s25,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     85     {   "s26",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s26,          LLDB_INVALID_REGNUM,        gdb_arm_s26,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     86     {   "s27",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s27,          LLDB_INVALID_REGNUM,        gdb_arm_s27,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     87     {   "s28",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s28,          LLDB_INVALID_REGNUM,        gdb_arm_s28,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     88     {   "s29",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s29,          LLDB_INVALID_REGNUM,        gdb_arm_s29,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     89     {   "s30",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s30,          LLDB_INVALID_REGNUM,        gdb_arm_s30,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     90     {   "s31",     NULL,      4, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_s31,          LLDB_INVALID_REGNUM,        gdb_arm_s31,            LLDB_INVALID_REGNUM },      NULL,              NULL},
     91     {   "fpscr",   NULL,      4, 0, eEncodingUint    , eFormatHex  , { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        gdb_arm_fpscr,          LLDB_INVALID_REGNUM },      NULL,              NULL},
     92     {   "d0",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d0,           LLDB_INVALID_REGNUM,        gdb_arm_d0,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     93     {   "d1",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d1,           LLDB_INVALID_REGNUM,        gdb_arm_d1,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     94     {   "d2",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d2,           LLDB_INVALID_REGNUM,        gdb_arm_d2,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     95     {   "d3",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d3,           LLDB_INVALID_REGNUM,        gdb_arm_d3,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     96     {   "d4",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d4,           LLDB_INVALID_REGNUM,        gdb_arm_d4,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     97     {   "d5",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d5,           LLDB_INVALID_REGNUM,        gdb_arm_d5,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     98     {   "d6",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d6,           LLDB_INVALID_REGNUM,        gdb_arm_d6,             LLDB_INVALID_REGNUM },      NULL,              NULL},
     99     {   "d7",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d7,           LLDB_INVALID_REGNUM,        gdb_arm_d7,             LLDB_INVALID_REGNUM },      NULL,              NULL},
    100     {   "d8",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d8,           LLDB_INVALID_REGNUM,        gdb_arm_d8,             LLDB_INVALID_REGNUM },      NULL,              NULL},
    101     {   "d9",      NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d9,           LLDB_INVALID_REGNUM,        gdb_arm_d9,             LLDB_INVALID_REGNUM },      NULL,              NULL},
    102     {   "d10",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d10,          LLDB_INVALID_REGNUM,        gdb_arm_d10,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    103     {   "d11",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d11,          LLDB_INVALID_REGNUM,        gdb_arm_d11,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    104     {   "d12",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d12,          LLDB_INVALID_REGNUM,        gdb_arm_d12,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    105     {   "d13",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d13,          LLDB_INVALID_REGNUM,        gdb_arm_d13,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    106     {   "d14",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d14,          LLDB_INVALID_REGNUM,        gdb_arm_d14,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    107     {   "d15",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d15,          LLDB_INVALID_REGNUM,        gdb_arm_d15,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    108     {   "d16",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d16,          LLDB_INVALID_REGNUM,        gdb_arm_d16,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    109     {   "d17",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d17,          LLDB_INVALID_REGNUM,        gdb_arm_d17,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    110     {   "d18",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d18,          LLDB_INVALID_REGNUM,        gdb_arm_d18,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    111     {   "d19",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d19,          LLDB_INVALID_REGNUM,        gdb_arm_d19,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    112     {   "d20",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d20,          LLDB_INVALID_REGNUM,        gdb_arm_d20,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    113     {   "d21",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d21,          LLDB_INVALID_REGNUM,        gdb_arm_d21,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    114     {   "d22",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d22,          LLDB_INVALID_REGNUM,        gdb_arm_d22,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    115     {   "d23",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d23,          LLDB_INVALID_REGNUM,        gdb_arm_d23,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    116     {   "d24",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d24,          LLDB_INVALID_REGNUM,        gdb_arm_d24,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    117     {   "d25",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d25,          LLDB_INVALID_REGNUM,        gdb_arm_d25,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    118     {   "d26",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d26,          LLDB_INVALID_REGNUM,        gdb_arm_d26,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    119     {   "d27",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d27,          LLDB_INVALID_REGNUM,        gdb_arm_d27,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    120     {   "d28",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d28,          LLDB_INVALID_REGNUM,        gdb_arm_d28,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    121     {   "d29",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d29,          LLDB_INVALID_REGNUM,        gdb_arm_d29,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    122     {   "d30",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d30,          LLDB_INVALID_REGNUM,        gdb_arm_d30,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    123     {   "d31",     NULL,      8, 0, eEncodingIEEE754 , eFormatFloat, { LLDB_INVALID_REGNUM,  dwarf_d31,          LLDB_INVALID_REGNUM,        gdb_arm_d31,            LLDB_INVALID_REGNUM },      NULL,              NULL},
    124     {   "r8_usr",  NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r8_usr,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    125     {   "r9_usr",  NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r9_usr,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    126     {   "r10_usr", NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r10_usr,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    127     {   "r11_usr", NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r11_usr,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    128     {   "r12_usr", NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r12_usr,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    129     {   "r13_usr", "sp_usr",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r13_usr,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    130     {   "r14_usr", "lr_usr",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r14_usr,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    131     {   "r8_fiq",  NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r8_fiq,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    132     {   "r9_fiq",  NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r9_fiq,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    133     {   "r10_fiq", NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r10_fiq,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    134     {   "r11_fiq", NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r11_fiq,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    135     {   "r12_fiq", NULL,      4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r12_fiq,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    136     {   "r13_fiq", "sp_fiq",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r13_fiq,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    137     {   "r14_fiq", "lr_fiq",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r14_fiq,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    138     {   "r13_irq", "sp_irq",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r13_irq,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    139     {   "r14_irq", "lr_irq",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r14_irq,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    140     {   "r13_abt", "sp_abt",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r13_abt,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    141     {   "r14_abt", "lr_abt",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r14_abt,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    142     {   "r13_und", "sp_und",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r13_und,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    143     {   "r14_und", "lr_und",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r14_und,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    144     {   "r13_svc", "sp_svc",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r13_svc,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL},
    145     {   "r14_svc", "lr_svc",  4, 0, eEncodingUint    , eFormatHex,   { LLDB_INVALID_REGNUM,  dwarf_r14_svc,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM },      NULL,              NULL}
    146 };
    147 static const uint32_t k_num_register_infos = sizeof(g_register_infos)/sizeof(RegisterInfo);
    148 static bool g_register_info_names_constified = false;
    149 
    150 const lldb_private::RegisterInfo *
    151 ABIMacOSX_arm::GetRegisterInfoArray (uint32_t &count)
    152 {
    153     // Make the C-string names and alt_names for the register infos into const
    154     // C-string values by having the ConstString unique the names in the global
    155     // constant C-string pool.
    156     if (!g_register_info_names_constified)
    157     {
    158         g_register_info_names_constified = true;
    159         for (uint32_t i=0; i<k_num_register_infos; ++i)
    160         {
    161             if (g_register_infos[i].name)
    162                 g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
    163             if (g_register_infos[i].alt_name)
    164                 g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
    165         }
    166     }
    167     count = k_num_register_infos;
    168     return g_register_infos;
    169 }
    170 
    171 
    172 size_t
    173 ABIMacOSX_arm::GetRedZoneSize () const
    174 {
    175     return 0;
    176 }
    177 
    178 //------------------------------------------------------------------
    179 // Static Functions
    180 //------------------------------------------------------------------
    181 ABISP
    182 ABIMacOSX_arm::CreateInstance (const ArchSpec &arch)
    183 {
    184     static ABISP g_abi_sp;
    185     const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
    186     if ((arch_type == llvm::Triple::arm) ||
    187         (arch_type == llvm::Triple::thumb))
    188     {
    189         if (!g_abi_sp)
    190             g_abi_sp.reset (new ABIMacOSX_arm);
    191         return g_abi_sp;
    192     }
    193     return ABISP();
    194 }
    195 
    196 bool
    197 ABIMacOSX_arm::PrepareTrivialCall (Thread &thread,
    198                                    addr_t sp,
    199                                    addr_t function_addr,
    200                                    addr_t return_addr,
    201                                    addr_t *arg1_ptr,
    202                                    addr_t *arg2_ptr,
    203                                    addr_t *arg3_ptr,
    204                                    addr_t *arg4_ptr,
    205                                    addr_t *arg5_ptr,
    206                                    addr_t *arg6_ptr) const
    207 {
    208     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    209     if (!reg_ctx)
    210         return false;
    211 
    212     const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    213     const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    214     const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
    215 
    216     RegisterValue reg_value;
    217 
    218     if (arg1_ptr)
    219     {
    220         reg_value.SetUInt32(*arg1_ptr);
    221         if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r0"), reg_value))
    222             return false;
    223 
    224         if (arg2_ptr)
    225         {
    226             reg_value.SetUInt32(*arg2_ptr);
    227             if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r1"), reg_value))
    228                 return false;
    229 
    230             if (arg3_ptr)
    231             {
    232                 reg_value.SetUInt32(*arg3_ptr);
    233                 if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r2"), reg_value))
    234                     return false;
    235                 if (arg4_ptr)
    236                 {
    237                     reg_value.SetUInt32(*arg4_ptr);
    238                     const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3");
    239                     if (!reg_ctx->WriteRegister (reg_info, reg_value))
    240                         return false;
    241                     if (arg5_ptr)
    242                     {
    243                         // Keep the stack 8 byte aligned, not that we need to
    244                         sp -= 8;
    245                         sp &= ~(8ull-1ull);
    246                         reg_value.SetUInt32(*arg5_ptr);
    247                         if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp, reg_info->byte_size, reg_value).Fail())
    248                             return false;
    249                         if (arg6_ptr)
    250                         {
    251                             reg_value.SetUInt32(*arg6_ptr);
    252                             if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp + 4, reg_info->byte_size, reg_value).Fail())
    253                                 return false;
    254                         }
    255                     }
    256                 }
    257             }
    258         }
    259     }
    260 
    261 
    262     TargetSP target_sp (thread.CalculateTarget());
    263     Address so_addr;
    264 
    265     // Figure out if our return address is ARM or Thumb by using the
    266     // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
    267     // thumb-ness and set the correct address bits for us.
    268     so_addr.SetLoadAddress (return_addr, target_sp.get());
    269     return_addr = so_addr.GetCallableLoadAddress (target_sp.get());
    270 
    271     // Set "lr" to the return address
    272     if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
    273         return false;
    274 
    275     // Set "sp" to the requested value
    276     if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
    277         return false;
    278 
    279     // If bit zero or 1 is set, this must be a thumb function, no need to figure
    280     // this out from the symbols.
    281     so_addr.SetLoadAddress (function_addr, target_sp.get());
    282     function_addr = so_addr.GetCallableLoadAddress (target_sp.get());
    283 
    284     const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
    285     const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
    286 
    287     // Make a new CPSR and mask out any Thumb IT (if/then) bits
    288     uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
    289     // If bit zero or 1 is set, this must be thumb...
    290     if (function_addr & 1ull)
    291         new_cpsr |= MASK_CPSR_T;    // Set T bit in CPSR
    292     else
    293         new_cpsr &= ~MASK_CPSR_T;   // Clear T bit in CPSR
    294 
    295     if (new_cpsr != curr_cpsr)
    296     {
    297         if (!reg_ctx->WriteRegisterFromUnsigned (cpsr_reg_info, new_cpsr))
    298             return false;
    299     }
    300 
    301     function_addr &= ~1ull;   // clear bit zero since the CPSR will take care of the mode for us
    302 
    303     // Set "pc" to the address requested
    304     if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, function_addr))
    305         return false;
    306 
    307     return true;
    308 }
    309 
    310 bool
    311 ABIMacOSX_arm::GetArgumentValues (Thread &thread,
    312                                   ValueList &values) const
    313 {
    314     uint32_t num_values = values.GetSize();
    315 
    316 
    317     ExecutionContext exe_ctx (thread.shared_from_this());
    318     // For now, assume that the types in the AST values come from the Target's
    319     // scratch AST.
    320 
    321     // Extract the register context so we can read arguments from registers
    322 
    323     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    324 
    325     if (!reg_ctx)
    326         return false;
    327 
    328     addr_t sp = 0;
    329 
    330     for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
    331     {
    332         // We currently only support extracting values with Clang QualTypes.
    333         // Do we care about others?
    334         Value *value = values.GetValueAtIndex(value_idx);
    335 
    336         if (!value)
    337             return false;
    338 
    339         ClangASTType clang_type = value->GetClangType();
    340         if (clang_type)
    341         {
    342             bool is_signed = false;
    343             size_t bit_width = 0;
    344             if (clang_type.IsIntegerType (is_signed))
    345             {
    346                 bit_width = clang_type.GetBitSize();
    347             }
    348             else if (clang_type.IsPointerOrReferenceType ())
    349             {
    350                 bit_width = clang_type.GetBitSize();
    351             }
    352             else
    353             {
    354                 // We only handle integer, pointer and reference types currently...
    355                 return false;
    356             }
    357 
    358             if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
    359             {
    360                 if (value_idx < 4)
    361                 {
    362                     // Arguments 1-4 are in r0-r3...
    363                     const RegisterInfo *arg_reg_info = NULL;
    364                     // Search by generic ID first, then fall back to by name
    365                     uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
    366                     if (arg_reg_num != LLDB_INVALID_REGNUM)
    367                     {
    368                         arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
    369                     }
    370                     else
    371                     {
    372                         switch (value_idx)
    373                         {
    374                             case 0: arg_reg_info = reg_ctx->GetRegisterInfoByName("r0"); break;
    375                             case 1: arg_reg_info = reg_ctx->GetRegisterInfoByName("r1"); break;
    376                             case 2: arg_reg_info = reg_ctx->GetRegisterInfoByName("r2"); break;
    377                             case 3: arg_reg_info = reg_ctx->GetRegisterInfoByName("r3"); break;
    378                         }
    379                     }
    380 
    381                     if (arg_reg_info)
    382                     {
    383                         RegisterValue reg_value;
    384 
    385                         if (reg_ctx->ReadRegister(arg_reg_info, reg_value))
    386                         {
    387                             if (is_signed)
    388                                 reg_value.SignExtend(bit_width);
    389                             if (!reg_value.GetScalarValue(value->GetScalar()))
    390                                 return false;
    391                             continue;
    392                         }
    393                     }
    394                     return false;
    395                 }
    396                 else
    397                 {
    398                     if (sp == 0)
    399                     {
    400                         // Read the stack pointer if it already hasn't been read
    401                         sp = reg_ctx->GetSP(0);
    402                         if (sp == 0)
    403                             return false;
    404                     }
    405 
    406                     // Arguments 5 on up are on the stack
    407                     const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
    408                     Error error;
    409                     if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
    410                         return false;
    411 
    412                     sp += arg_byte_size;
    413                 }
    414             }
    415         }
    416     }
    417     return true;
    418 }
    419 
    420 ValueObjectSP
    421 ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
    422                                          lldb_private::ClangASTType &clang_type) const
    423 {
    424     Value value;
    425     ValueObjectSP return_valobj_sp;
    426 
    427     if (!clang_type)
    428         return return_valobj_sp;
    429 
    430     clang::ASTContext *ast_context = clang_type.GetASTContext();
    431     if (!ast_context)
    432         return return_valobj_sp;
    433 
    434     //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType());
    435     value.SetClangType (clang_type);
    436 
    437     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    438     if (!reg_ctx)
    439         return return_valobj_sp;
    440 
    441     bool is_signed;
    442 
    443     // Get the pointer to the first stack argument so we have a place to start
    444     // when reading data
    445 
    446     const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
    447     if (clang_type.IsIntegerType (is_signed))
    448     {
    449         size_t bit_width = clang_type.GetBitSize();
    450 
    451         switch (bit_width)
    452         {
    453             default:
    454                 return return_valobj_sp;
    455             case 64:
    456             {
    457                 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
    458                 uint64_t raw_value;
    459                 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
    460                 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
    461                 if (is_signed)
    462                     value.GetScalar() = (int64_t)raw_value;
    463                 else
    464                     value.GetScalar() = (uint64_t)raw_value;
    465             }
    466                 break;
    467             case 32:
    468                 if (is_signed)
    469                     value.GetScalar() = (int32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
    470                 else
    471                     value.GetScalar() = (uint32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
    472                 break;
    473             case 16:
    474                 if (is_signed)
    475                     value.GetScalar() = (int16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
    476                 else
    477                     value.GetScalar() = (uint16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
    478                 break;
    479             case 8:
    480                 if (is_signed)
    481                     value.GetScalar() = (int8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
    482                 else
    483                     value.GetScalar() = (uint8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
    484                 break;
    485         }
    486     }
    487     else if (clang_type.IsPointerType ())
    488     {
    489         uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
    490         value.GetScalar() = ptr;
    491     }
    492     else
    493     {
    494         // not handled yet
    495         return return_valobj_sp;
    496     }
    497 
    498     // If we get here, we have a valid Value, so make our ValueObject out of it:
    499 
    500     return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
    501                                                       value,
    502                                                       ConstString(""));
    503     return return_valobj_sp;
    504 }
    505 
    506 Error
    507 ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
    508 {
    509     Error error;
    510     if (!new_value_sp)
    511     {
    512         error.SetErrorString("Empty value object for return value.");
    513         return error;
    514     }
    515 
    516     ClangASTType clang_type = new_value_sp->GetClangType();
    517     if (!clang_type)
    518     {
    519         error.SetErrorString ("Null clang type for return value.");
    520         return error;
    521     }
    522 
    523     Thread *thread = frame_sp->GetThread().get();
    524 
    525     bool is_signed;
    526     uint32_t count;
    527     bool is_complex;
    528 
    529     RegisterContext *reg_ctx = thread->GetRegisterContext().get();
    530 
    531     bool set_it_simple = false;
    532     if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
    533     {
    534         DataExtractor data;
    535         size_t num_bytes = new_value_sp->GetData(data);
    536         lldb::offset_t offset = 0;
    537         if (num_bytes <= 8)
    538         {
    539             const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
    540             if (num_bytes <= 4)
    541             {
    542                 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
    543 
    544                 if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
    545                     set_it_simple = true;
    546             }
    547             else
    548             {
    549                 uint32_t raw_value = data.GetMaxU32(&offset, 4);
    550 
    551                 if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
    552                 {
    553                     const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
    554                     uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
    555 
    556                     if (reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value))
    557                         set_it_simple = true;
    558                 }
    559             }
    560         }
    561         else
    562         {
    563             error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
    564         }
    565     }
    566     else if (clang_type.IsFloatingPointType (count, is_complex))
    567     {
    568         if (is_complex)
    569             error.SetErrorString ("We don't support returning complex values at present");
    570         else
    571             error.SetErrorString ("We don't support returning float values at present");
    572     }
    573 
    574     if (!set_it_simple)
    575         error.SetErrorString ("We only support setting simple integer return types at present.");
    576 
    577     return error;
    578 }
    579 
    580 bool
    581 ABIMacOSX_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
    582 {
    583     uint32_t reg_kind = unwind_plan.GetRegisterKind();
    584     uint32_t lr_reg_num = LLDB_INVALID_REGNUM;
    585     uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
    586     uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
    587 
    588     switch (reg_kind)
    589     {
    590         case eRegisterKindDWARF:
    591         case eRegisterKindGCC:
    592             lr_reg_num = dwarf_lr;
    593             sp_reg_num = dwarf_sp;
    594             pc_reg_num = dwarf_pc;
    595             break;
    596 
    597         case eRegisterKindGeneric:
    598             lr_reg_num = LLDB_REGNUM_GENERIC_RA;
    599             sp_reg_num = LLDB_REGNUM_GENERIC_SP;
    600             pc_reg_num = LLDB_REGNUM_GENERIC_PC;
    601             break;
    602     }
    603 
    604     if (lr_reg_num == LLDB_INVALID_REGNUM ||
    605         sp_reg_num == LLDB_INVALID_REGNUM ||
    606         pc_reg_num == LLDB_INVALID_REGNUM)
    607         return false;
    608 
    609     UnwindPlan::RowSP row(new UnwindPlan::Row);
    610 
    611     // Our Call Frame Address is the stack pointer value
    612     row->SetCFARegister (sp_reg_num);
    613 
    614     // The previous PC is in the LR
    615     row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
    616     unwind_plan.AppendRow (row);
    617 
    618     // All other registers are the same.
    619 
    620     unwind_plan.SetSourceName ("arm at-func-entry default");
    621     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
    622 
    623     return true;
    624 }
    625 
    626 bool
    627 ABIMacOSX_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
    628 {
    629     uint32_t fp_reg_num = dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11;
    630     uint32_t pc_reg_num = dwarf_pc;
    631 
    632     UnwindPlan::RowSP row(new UnwindPlan::Row);
    633     const int32_t ptr_size = 4;
    634 
    635     unwind_plan.Clear ();
    636     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
    637     row->SetCFARegister (fp_reg_num);
    638     row->SetCFAOffset (2 * ptr_size);
    639     row->SetOffset (0);
    640 
    641     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
    642     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
    643 
    644     unwind_plan.AppendRow (row);
    645     unwind_plan.SetSourceName ("arm-apple-ios default unwind plan");
    646     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
    647     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
    648 
    649     return true;
    650 }
    651 
    652 // ARMv7 on iOS general purpose reg rules:
    653 //    r0-r3 not preserved  (used for argument passing)
    654 //    r4-r6 preserved
    655 //    r7    preserved (frame pointer)
    656 //    r8    preserved
    657 //    r9    not preserved (usable as volatile scratch register with iOS 3.x and later)
    658 //    r10-r11 preserved
    659 //    r12   not presrved
    660 //    r13   preserved (stack pointer)
    661 //    r14   not preserved (link register)
    662 //    r15   preserved (pc)
    663 //    cpsr  not preserved (different rules for different bits)
    664 
    665 // ARMv7 on iOS floating point rules:
    666 //    d0-d7   not preserved   (aka s0-s15, q0-q3)
    667 //    d8-d15  preserved       (aka s16-s31, q4-q7)
    668 //    d16-d31 not preserved   (aka q8-q15)
    669 
    670 bool
    671 ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
    672 {
    673     if (reg_info)
    674     {
    675         // Volatile registers include: r0, r1, r2, r3, r9, r12, r13
    676         const char *name = reg_info->name;
    677         if (name[0] == 'r')
    678         {
    679             switch (name[1])
    680             {
    681                 case '0': return name[2] == '\0'; // r0
    682                 case '1':
    683                     switch (name[2])
    684                     {
    685                     case '\0':
    686                         return true; // r1
    687                     case '2':
    688                     case '3':
    689                         return name[2] == '\0'; // r12 - r13
    690                     default:
    691                         break;
    692                     }
    693                     break;
    694 
    695                 case '2': return name[2] == '\0'; // r2
    696                 case '3': return name[2] == '\0'; // r3
    697                 case '9': return name[2] == '\0'; // r9 (apple-ios only...)
    698 
    699                 break;
    700             }
    701         }
    702         else if (name[0] == 'd')
    703         {
    704             switch (name[1])
    705             {
    706                 case '0':
    707                     return name[2] == '\0'; // d0 is volatile
    708 
    709                 case '1':
    710                     switch (name[2])
    711                     {
    712                     case '\0':
    713                         return true; // d1 is volatile
    714                     case '6':
    715                     case '7':
    716                     case '8':
    717                     case '9':
    718                         return name[3] == '\0'; // d16 - d19 are volatile
    719                     default:
    720                         break;
    721                     }
    722                     break;
    723 
    724                 case '2':
    725                     switch (name[2])
    726                     {
    727                     case '\0':
    728                         return true; // d2 is volatile
    729                     case '0':
    730                     case '1':
    731                     case '2':
    732                     case '3':
    733                     case '4':
    734                     case '5':
    735                     case '6':
    736                     case '7':
    737                     case '8':
    738                     case '9':
    739                         return name[3] == '\0'; // d20 - d29 are volatile
    740                     default:
    741                         break;
    742                     }
    743                     break;
    744 
    745                 case '3':
    746                     switch (name[2])
    747                     {
    748                     case '\0':
    749                         return true; // d3 is volatile
    750                     case '0':
    751                     case '1':
    752                         return name[3] == '\0'; // d30 - d31 are volatile
    753                     default:
    754                         break;
    755                     }
    756                 case '4':
    757                 case '5':
    758                 case '6':
    759                 case '7':
    760                     return name[2] == '\0'; // d4 - d7 are volatile
    761 
    762                 default:
    763                     break;
    764             }
    765         }
    766         else if (name[0] == 's')
    767         {
    768             switch (name[1])
    769             {
    770                 case '0':
    771                     return name[2] == '\0'; // s0 is volatile
    772 
    773                 case '1':
    774                     switch (name[2])
    775                     {
    776                     case '\0':
    777                         return true; // s1 is volatile
    778                     case '0':
    779                     case '1':
    780                     case '2':
    781                     case '3':
    782                     case '4':
    783                     case '5':
    784                         return name[3] == '\0'; // s10 - s15 are volatile
    785                     default:
    786                         break;
    787                     }
    788                     break;
    789 
    790                 case '2':
    791                     switch (name[2])
    792                     {
    793                     case '\0':
    794                         return true; // s2 is volatile
    795                     default:
    796                         break;
    797                     }
    798                     break;
    799 
    800                 case '3':
    801                     switch (name[2])
    802                     {
    803                     case '\0':
    804                         return true; // s3 is volatile
    805                     default:
    806                         break;
    807                     }
    808                 case '4':
    809                 case '5':
    810                 case '6':
    811                 case '7':
    812                 case '8':
    813                 case '9':
    814                     return name[2] == '\0'; // s4 - s9 are volatile
    815 
    816                 default:
    817                     break;
    818             }
    819         }
    820         else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
    821             return true;
    822     }
    823     return false;
    824 }
    825 
    826 void
    827 ABIMacOSX_arm::Initialize()
    828 {
    829     PluginManager::RegisterPlugin (GetPluginNameStatic(),
    830                                    "Mac OS X ABI for arm targets",
    831                                    CreateInstance);
    832 }
    833 
    834 void
    835 ABIMacOSX_arm::Terminate()
    836 {
    837     PluginManager::UnregisterPlugin (CreateInstance);
    838 }
    839 
    840 lldb_private::ConstString
    841 ABIMacOSX_arm::GetPluginNameStatic()
    842 {
    843     static ConstString g_name("macosx-arm");
    844     return g_name;
    845 }
    846 
    847 //------------------------------------------------------------------
    848 // PluginInterface protocol
    849 //------------------------------------------------------------------
    850 lldb_private::ConstString
    851 ABIMacOSX_arm::GetPluginName()
    852 {
    853     return GetPluginNameStatic();
    854 }
    855 
    856 uint32_t
    857 ABIMacOSX_arm::GetPluginVersion()
    858 {
    859     return 1;
    860 }
    861 
    862