ABIMacOSX_arm64.cpp revision 296417
1//===-- ABIMacOSX_arm64.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_arm64.h"
11
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/Error.h"
14#include "lldb/Core/Log.h"
15#include "lldb/Core/Module.h"
16#include "lldb/Core/PluginManager.h"
17#include "lldb/Core/RegisterValue.h"
18#include "lldb/Core/Scalar.h"
19#include "lldb/Core/Value.h"
20#include "lldb/Core/Value.h"
21#include "lldb/Core/ValueObjectConstResult.h"
22#include "lldb/Symbol/UnwindPlan.h"
23#include "lldb/Target/Process.h"
24#include "lldb/Target/RegisterContext.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Target/Thread.h"
27
28#include "llvm/ADT/STLExtras.h"
29#include "llvm/ADT/Triple.h"
30
31#include "Utility/ARM64_DWARF_Registers.h"
32
33#include <vector>
34
35using namespace lldb;
36using namespace lldb_private;
37
38static const char *pluginDesc = "Mac OS X ABI for arm64 targets";
39
40
41static RegisterInfo g_register_infos[] =
42{
43    //  NAME       ALT       SZ OFF ENCODING          FORMAT                   EH_FRAME             DWARF                  GENERIC                     PROCESS PLUGIN          LLDB NATIVE
44    //  ========== =======   == === =============     ===================      ===================  ====================== =========================== ======================= ======================
45    {   "x0",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x0,       LLDB_REGNUM_GENERIC_ARG1,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
46    {   "x1",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x1,       LLDB_REGNUM_GENERIC_ARG2,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
47    {   "x2",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x2,       LLDB_REGNUM_GENERIC_ARG3,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
48    {   "x3",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x3,       LLDB_REGNUM_GENERIC_ARG4,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
49    {   "x4",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x4,       LLDB_REGNUM_GENERIC_ARG5,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
50    {   "x5",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x5,       LLDB_REGNUM_GENERIC_ARG6,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
51    {   "x6",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x6,       LLDB_REGNUM_GENERIC_ARG7,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
52    {   "x7",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x7,       LLDB_REGNUM_GENERIC_ARG8,   LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
53    {   "x8",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x8,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
54    {   "x9",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x9,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
55    {   "x10",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x10,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
56    {   "x11",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x11,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
57    {   "x12",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x12,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
58    {   "x13",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x13,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
59    {   "x14",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x14,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
60    {   "x15",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x15,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
61    {   "x16",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x16,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
62    {   "x17",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x17,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
63    {   "x18",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x18,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
64    {   "x19",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x19,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
65    {   "x20",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x20,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
66    {   "x21",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x21,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
67    {   "x22",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x22,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
68    {   "x23",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x23,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
69    {   "x24",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x24,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
70    {   "x25",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x25,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
71    {   "x26",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x26,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
72    {   "x27",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x27,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
73    {   "x28",     NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x28,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
74    {   "fp",      "x29",     8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x29,      LLDB_REGNUM_GENERIC_FP,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
75    {   "lr",      "x30",     8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x30,      LLDB_REGNUM_GENERIC_RA,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
76    {   "sp",      "x31",     8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::x31,      LLDB_REGNUM_GENERIC_SP,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
77    {   "pc",      NULL,      8, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::pc,       LLDB_REGNUM_GENERIC_PC,     LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
78    {   "cpsr",    "psr",     4, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, arm64_dwarf::cpsr,     LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
79
80    {   "v0",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v0,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
81    {   "v1",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v1,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
82    {   "v2",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v2,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
83    {   "v3",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v3,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
84    {   "v4",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v4,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
85    {   "v5",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v5,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
86    {   "v6",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v6,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
87    {   "v7",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v7,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
88    {   "v8",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v8,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
89    {   "v9",      NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v9,       LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
90    {   "v10",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v10,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
91    {   "v11",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v11,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
92    {   "v12",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v12,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
93    {   "v13",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v13,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
94    {   "v14",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v14,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
95    {   "v15",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v15,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
96    {   "v16",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v16,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
97    {   "v17",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v17,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
98    {   "v18",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v18,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
99    {   "v19",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v19,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
100    {   "v20",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v20,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
101    {   "v21",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v21,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
102    {   "v22",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v22,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
103    {   "v23",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v23,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
104    {   "v24",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v24,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
105    {   "v25",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v25,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
106    {   "v26",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v26,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
107    {   "v27",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v27,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
108    {   "v28",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v28,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
109    {   "v29",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v29,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
110    {   "v30",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v30,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
111    {   "v31",     NULL,     16, 0, eEncodingVector , eFormatVectorOfUInt8,  { LLDB_INVALID_REGNUM, arm64_dwarf::v31,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
112
113    {   "fpsr",    NULL,      4, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
114    {   "fpcr",    NULL,      4, 0, eEncodingUint   , eFormatHex           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
115
116    {   "s0",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
117    {   "s1",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
118    {   "s2",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
119    {   "s3",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
120    {   "s4",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
121    {   "s5",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
122    {   "s6",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
123    {   "s7",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
124    {   "s8",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
125    {   "s9",      NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
126    {   "s10",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
127    {   "s11",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
128    {   "s12",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
129    {   "s13",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
130    {   "s14",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
131    {   "s15",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
132    {   "s16",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
133    {   "s17",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
134    {   "s18",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
135    {   "s19",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
136    {   "s20",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
137    {   "s21",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
138    {   "s22",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
139    {   "s23",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
140    {   "s24",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
141    {   "s25",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
142    {   "s26",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
143    {   "s27",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
144    {   "s28",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
145    {   "s29",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
146    {   "s30",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
147    {   "s31",     NULL,     4, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
148
149    {   "d0",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
150    {   "d1",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
151    {   "d2",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
152    {   "d3",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
153    {   "d4",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
154    {   "d5",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
155    {   "d6",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
156    {   "d7",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
157    {   "d8",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
158    {   "d9",      NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
159    {   "d10",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
160    {   "d11",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
161    {   "d12",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
162    {   "d13",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
163    {   "d14",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
164    {   "d15",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
165    {   "d16",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
166    {   "d17",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
167    {   "d18",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
168    {   "d19",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
169    {   "d20",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
170    {   "d21",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
171    {   "d22",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
172    {   "d23",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
173    {   "d24",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
174    {   "d25",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
175    {   "d26",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
176    {   "d27",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
177    {   "d28",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
178    {   "d29",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
179    {   "d30",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL },
180    {   "d31",     NULL,     8, 0, eEncodingIEEE754 , eFormatFloat         , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,   LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM }, NULL, NULL }
181};
182
183static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
184static bool g_register_info_names_constified = false;
185
186const lldb_private::RegisterInfo *
187ABIMacOSX_arm64::GetRegisterInfoArray (uint32_t &count)
188{
189    // Make the C-string names and alt_names for the register infos into const
190    // C-string values by having the ConstString unique the names in the global
191    // constant C-string pool.
192    if (!g_register_info_names_constified)
193    {
194        g_register_info_names_constified = true;
195        for (uint32_t i=0; i<k_num_register_infos; ++i)
196        {
197            if (g_register_infos[i].name)
198                g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
199            if (g_register_infos[i].alt_name)
200                g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
201        }
202    }
203    count = k_num_register_infos;
204    return g_register_infos;
205}
206
207size_t
208ABIMacOSX_arm64::GetRedZoneSize () const
209{
210    return 128;
211}
212
213//------------------------------------------------------------------
214// Static Functions
215//------------------------------------------------------------------
216ABISP
217ABIMacOSX_arm64::CreateInstance (const ArchSpec &arch)
218{
219    static ABISP g_abi_sp;
220    const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
221    const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
222
223    if (vendor_type == llvm::Triple::Apple)
224    {
225	    if (arch_type == llvm::Triple::aarch64)
226        {
227            if (!g_abi_sp)
228                g_abi_sp.reset (new ABIMacOSX_arm64);
229            return g_abi_sp;
230        }
231    }
232
233    return ABISP();
234}
235
236bool
237ABIMacOSX_arm64::PrepareTrivialCall (Thread &thread,
238                                     lldb::addr_t sp,
239                                     lldb::addr_t func_addr,
240                                     lldb::addr_t return_addr,
241                                     llvm::ArrayRef<lldb::addr_t> args) const
242{
243    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
244    if (!reg_ctx)
245        return false;
246
247    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
248
249    if (log)
250    {
251        StreamString s;
252        s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
253                 thread.GetID(),
254                 (uint64_t)sp,
255                 (uint64_t)func_addr,
256                 (uint64_t)return_addr);
257
258        for (size_t i = 0; i < args.size(); ++i)
259            s.Printf (", arg%d = 0x%" PRIx64, static_cast<int>(i + 1), args[i]);
260        s.PutCString (")");
261        log->PutCString(s.GetString().c_str());
262    }
263
264    const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
265    const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
266    const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
267
268    // x0 - x7 contain first 8 simple args
269    if (args.size() > 8) // TODO handle more than 6 arguments
270        return false;
271
272    for (size_t i = 0; i < args.size(); ++i)
273    {
274        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
275        if (log)
276            log->Printf("About to write arg%d (0x%" PRIx64 ") into %s",
277                        static_cast<int>(i + 1), args[i], reg_info->name);
278        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
279            return false;
280    }
281
282    // Set "lr" to the return address
283    if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (ra_reg_num), return_addr))
284        return false;
285
286    // Set "sp" to the requested value
287    if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (sp_reg_num), sp))
288        return false;
289
290    // Set "pc" to the address requested
291    if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoAtIndex (pc_reg_num), func_addr))
292        return false;
293
294    return true;
295}
296
297
298bool
299ABIMacOSX_arm64::GetArgumentValues (Thread &thread, ValueList &values) const
300{
301    uint32_t num_values = values.GetSize();
302
303    ExecutionContext exe_ctx (thread.shared_from_this());
304
305    // Extract the register context so we can read arguments from registers
306
307    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
308
309    if (!reg_ctx)
310        return false;
311
312    addr_t sp = 0;
313
314    for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
315    {
316        // We currently only support extracting values with Clang QualTypes.
317        // Do we care about others?
318        Value *value = values.GetValueAtIndex(value_idx);
319
320        if (!value)
321            return false;
322
323        CompilerType value_type = value->GetCompilerType();
324        if (value_type)
325        {
326            bool is_signed = false;
327            size_t bit_width = 0;
328            if (value_type.IsIntegerType (is_signed))
329            {
330                bit_width = value_type.GetBitSize(&thread);
331            }
332            else if (value_type.IsPointerOrReferenceType ())
333            {
334                bit_width = value_type.GetBitSize(&thread);
335            }
336            else
337            {
338                // We only handle integer, pointer and reference types currently...
339                return false;
340            }
341
342            if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
343            {
344                if (value_idx < 8)
345                {
346                    // Arguments 1-6 are in x0-x5...
347                    const RegisterInfo *reg_info = NULL;
348                    // Search by generic ID first, then fall back to by name
349                    uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
350                    if (arg_reg_num != LLDB_INVALID_REGNUM)
351                    {
352                        reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
353                    }
354                    else
355                    {
356                        switch (value_idx)
357                        {
358                            case 0: reg_info = reg_ctx->GetRegisterInfoByName("x0"); break;
359                            case 1: reg_info = reg_ctx->GetRegisterInfoByName("x1"); break;
360                            case 2: reg_info = reg_ctx->GetRegisterInfoByName("x2"); break;
361                            case 3: reg_info = reg_ctx->GetRegisterInfoByName("x3"); break;
362                            case 4: reg_info = reg_ctx->GetRegisterInfoByName("x4"); break;
363                            case 5: reg_info = reg_ctx->GetRegisterInfoByName("x5"); break;
364                            case 6: reg_info = reg_ctx->GetRegisterInfoByName("x6"); break;
365                            case 7: reg_info = reg_ctx->GetRegisterInfoByName("x7"); break;
366                        }
367                    }
368
369                    if (reg_info)
370                    {
371                        RegisterValue reg_value;
372
373                        if (reg_ctx->ReadRegister(reg_info, reg_value))
374                        {
375                            if (is_signed)
376                                reg_value.SignExtend(bit_width);
377                            if (!reg_value.GetScalarValue(value->GetScalar()))
378                                return false;
379                            continue;
380                        }
381                    }
382                    return false;
383                }
384                else
385                {
386                    if (sp == 0)
387                    {
388                        // Read the stack pointer if we already haven't read it
389                        sp = reg_ctx->GetSP(0);
390                        if (sp == 0)
391                            return false;
392                    }
393
394                    // Arguments 5 on up are on the stack
395                    const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
396                    Error error;
397                    if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
398                        return false;
399
400                    sp += arg_byte_size;
401                    // Align up to the next 8 byte boundary if needed
402                    if (sp % 8)
403                    {
404                        sp >>= 3;
405                        sp += 1;
406                        sp <<= 3;
407                    }
408                }
409            }
410        }
411    }
412    return true;
413}
414
415Error
416ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
417{
418    Error error;
419    if (!new_value_sp)
420    {
421        error.SetErrorString("Empty value object for return value.");
422        return error;
423    }
424
425    CompilerType return_value_type = new_value_sp->GetCompilerType();
426    if (!return_value_type)
427    {
428        error.SetErrorString ("Null clang type for return value.");
429        return error;
430    }
431
432    Thread *thread = frame_sp->GetThread().get();
433
434    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
435
436    if (reg_ctx)
437    {
438        DataExtractor data;
439        Error data_error;
440        const uint64_t byte_size = new_value_sp->GetData(data, data_error);
441        if (data_error.Fail())
442        {
443            error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
444            return error;
445        }
446
447        const uint32_t type_flags = return_value_type.GetTypeInfo (NULL);
448        if (type_flags & eTypeIsScalar ||
449            type_flags & eTypeIsPointer)
450        {
451            if (type_flags & eTypeIsInteger ||
452                type_flags & eTypeIsPointer )
453            {
454                // Extract the register context so we can read arguments from registers
455                lldb::offset_t offset = 0;
456                if (byte_size <= 16)
457                {
458                    const RegisterInfo *x0_info = reg_ctx->GetRegisterInfoByName("x0", 0);
459                    if (byte_size <= 8)
460                    {
461                        uint64_t raw_value = data.GetMaxU64(&offset, byte_size);
462
463                        if (!reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
464                            error.SetErrorString ("failed to write register x0");
465                    }
466                    else
467                    {
468                        uint64_t raw_value = data.GetMaxU64(&offset, 8);
469
470                        if (reg_ctx->WriteRegisterFromUnsigned (x0_info, raw_value))
471                        {
472                            const RegisterInfo *x1_info = reg_ctx->GetRegisterInfoByName("x1", 0);
473                            raw_value = data.GetMaxU64(&offset, byte_size - offset);
474
475                            if (!reg_ctx->WriteRegisterFromUnsigned (x1_info, raw_value))
476                                error.SetErrorString ("failed to write register x1");
477                        }
478                    }
479                }
480                else
481                {
482                    error.SetErrorString("We don't support returning longer than 128 bit integer values at present.");
483                }
484            }
485            else if (type_flags & eTypeIsFloat)
486            {
487                if (type_flags & eTypeIsComplex)
488                {
489                    // Don't handle complex yet.
490                    error.SetErrorString ("returning complex float values are not supported");
491                }
492                else
493                {
494                    const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
495
496                    if (v0_info)
497                    {
498                        if (byte_size <= 16)
499                        {
500                            if (byte_size <= RegisterValue::GetMaxByteSize())
501                            {
502                                RegisterValue reg_value;
503                                error = reg_value.SetValueFromData (v0_info, data, 0, true);
504                                if (error.Success())
505                                {
506                                    if (!reg_ctx->WriteRegister (v0_info, reg_value))
507                                        error.SetErrorString ("failed to write register v0");
508                                }
509                            }
510                            else
511                            {
512                                error.SetErrorStringWithFormat ("returning float values with a byte size of %" PRIu64 " are not supported", byte_size);
513                            }
514                        }
515                        else
516                        {
517                            error.SetErrorString("returning float values longer than 128 bits are not supported");
518                        }
519                    }
520                    else
521                    {
522                        error.SetErrorString("v0 register is not available on this target");
523                    }
524                }
525            }
526        }
527        else if (type_flags & eTypeIsVector)
528        {
529            if (byte_size > 0)
530            {
531                const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
532
533                if (v0_info)
534                {
535                    if (byte_size <= v0_info->byte_size)
536                    {
537                        RegisterValue reg_value;
538                        error = reg_value.SetValueFromData (v0_info, data, 0, true);
539                        if (error.Success())
540                        {
541                            if (!reg_ctx->WriteRegister (v0_info, reg_value))
542                                error.SetErrorString ("failed to write register v0");
543                        }
544                    }
545                }
546            }
547        }
548    }
549    else
550    {
551        error.SetErrorString("no registers are available");
552    }
553
554    return error;
555}
556
557bool
558ABIMacOSX_arm64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
559{
560    unwind_plan.Clear();
561    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
562
563    uint32_t lr_reg_num = arm64_dwarf::lr;
564    uint32_t sp_reg_num = arm64_dwarf::sp;
565    uint32_t pc_reg_num = arm64_dwarf::pc;
566
567    UnwindPlan::RowSP row(new UnwindPlan::Row);
568
569    // Our previous Call Frame Address is the stack pointer
570    row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
571
572    // Our previous PC is in the LR
573    row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
574
575    unwind_plan.AppendRow (row);
576
577    // All other registers are the same.
578
579    unwind_plan.SetSourceName ("arm64 at-func-entry default");
580    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
581
582    return true;
583}
584
585bool
586ABIMacOSX_arm64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
587{
588    unwind_plan.Clear();
589    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
590
591    uint32_t fp_reg_num = arm64_dwarf::fp;
592    uint32_t pc_reg_num = arm64_dwarf::pc;
593
594    UnwindPlan::RowSP row(new UnwindPlan::Row);
595    const int32_t ptr_size = 8;
596
597    row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
598    row->SetOffset (0);
599
600    row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
601    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
602
603    unwind_plan.AppendRow (row);
604    unwind_plan.SetSourceName ("arm64-apple-darwin default unwind plan");
605    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
606    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
607    return true;
608}
609
610// AAPCS64 (Procedure Call Standard for the ARM 64-bit Architecture) says
611// registers x19 through x28 and sp are callee preserved.
612// v8-v15 are non-volatile (and specifically only the lower 8 bytes of these regs),
613// the rest of the fp/SIMD registers are volatile.
614
615// We treat x29 as callee preserved also, else the unwinder won't try to
616// retrieve fp saves.
617
618bool
619ABIMacOSX_arm64::RegisterIsVolatile (const RegisterInfo *reg_info)
620{
621    if (reg_info)
622    {
623        const char *name = reg_info->name;
624
625        // Sometimes we'll be called with the "alternate" name for these registers;
626        // recognize them as non-volatile.
627
628        if (name[0] == 'p' && name[1] == 'c')        // pc
629            return false;
630        if (name[0] == 'f' && name[1] == 'p')        // fp
631            return false;
632        if (name[0] == 's' && name[1] == 'p')        // sp
633            return false;
634        if (name[0] == 'l' && name[1] == 'r')        // lr
635            return false;
636
637        if (name[0] == 'x')
638        {
639            // Volatile registers: x0-x18, x30 (lr)
640            // Return false for the non-volatile gpr regs, true for everything else
641            switch (name[1])
642            {
643                case '1':
644                    switch (name[2])
645                    {
646                        case '9':
647                            return false;             // x19 is non-volatile
648                        default:
649                          return true;
650                    }
651                        break;
652                case '2':
653                    switch (name[2])
654                    {
655                        case '0':
656                        case '1':
657                        case '2':
658                        case '3':
659                        case '4':
660                        case '5':
661                        case '6':
662                        case '7':
663                        case '8':
664                            return false;             // x20 - 28 are non-volatile
665                        case '9':
666                            return false;             // x29 aka fp treat as non-volatile on Darwin
667                        default:
668                            return true;
669                    }
670                case '3':                             // x30 aka lr treat as non-volatile
671                    if (name[2] == '0')
672                      return false;
673                default:
674                    return true;
675            }
676        }
677        else if (name[0] == 'v' || name[0] == 's' || name[0] == 'd')
678        {
679            // Volatile registers: v0-7, v16-v31
680            // Return false for non-volatile fp/SIMD regs, true for everything else
681            switch (name[1])
682            {
683                case '8':
684                case '9':
685                    return false; // v8-v9 are non-volatile
686                case '1':
687                    switch (name[2])
688                    {
689                        case '0':
690                        case '1':
691                        case '2':
692                        case '3':
693                        case '4':
694                        case '5':
695                            return false; // v10-v15 are non-volatile
696                        default:
697                            return true;
698                    }
699                default:
700                    return true;
701            }
702        }
703    }
704    return true;
705}
706
707static bool
708LoadValueFromConsecutiveGPRRegisters (ExecutionContext &exe_ctx,
709                                      RegisterContext *reg_ctx,
710                                      const CompilerType &value_type,
711                                      bool is_return_value, // false => parameter, true => return value
712                                      uint32_t &NGRN,       // NGRN (see ABI documentation)
713                                      uint32_t &NSRN,       // NSRN (see ABI documentation)
714                                      DataExtractor &data)
715{
716    const size_t byte_size = value_type.GetByteSize(nullptr);
717
718    if (byte_size == 0)
719        return false;
720
721    std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
722    const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
723    Error error;
724
725    CompilerType base_type;
726    const uint32_t homogeneous_count = value_type.IsHomogeneousAggregate (&base_type);
727    if (homogeneous_count > 0 && homogeneous_count <= 8)
728    {
729        // Make sure we have enough registers
730        if (NSRN < 8 && (8-NSRN) >= homogeneous_count)
731        {
732            if (!base_type)
733                return false;
734            const size_t base_byte_size = base_type.GetByteSize(nullptr);
735            uint32_t data_offset = 0;
736
737            for (uint32_t i=0; i<homogeneous_count; ++i)
738            {
739                char v_name[8];
740                ::snprintf (v_name, sizeof(v_name), "v%u", NSRN);
741                const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(v_name, 0);
742                if (reg_info == NULL)
743                    return false;
744
745                if (base_byte_size > reg_info->byte_size)
746                    return false;
747
748                RegisterValue reg_value;
749
750                if (!reg_ctx->ReadRegister(reg_info, reg_value))
751                    return false;
752
753                // Make sure we have enough room in "heap_data_ap"
754                if ((data_offset + base_byte_size) <= heap_data_ap->GetByteSize())
755                {
756                    const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
757                                                                           heap_data_ap->GetBytes()+data_offset,
758                                                                           base_byte_size,
759                                                                           byte_order,
760                                                                           error);
761                    if (bytes_copied != base_byte_size)
762                        return false;
763                    data_offset += bytes_copied;
764                    ++NSRN;
765                }
766                else
767                    return false;
768            }
769            data.SetByteOrder(byte_order);
770            data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
771            data.SetData(DataBufferSP (heap_data_ap.release()));
772            return true;
773        }
774    }
775
776    const size_t max_reg_byte_size = 16;
777    if (byte_size <= max_reg_byte_size)
778    {
779        size_t bytes_left = byte_size;
780        uint32_t data_offset = 0;
781        while (data_offset < byte_size)
782        {
783            if (NGRN >= 8)
784                return false;
785
786            uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
787            if (reg_num == LLDB_INVALID_REGNUM)
788                return false;
789
790            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
791            if (reg_info == NULL)
792                return false;
793
794            RegisterValue reg_value;
795
796            if (!reg_ctx->ReadRegister(reg_info, reg_value))
797                return false;
798
799            const size_t curr_byte_size = std::min<size_t>(8,bytes_left);
800            const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info, heap_data_ap->GetBytes()+data_offset, curr_byte_size, byte_order, error);
801            if (bytes_copied == 0)
802                return false;
803            if (bytes_copied >= bytes_left)
804                break;
805            data_offset += bytes_copied;
806            bytes_left -= bytes_copied;
807            ++NGRN;
808        }
809    }
810    else
811    {
812        const RegisterInfo *reg_info = NULL;
813        if (is_return_value)
814        {
815            // We are assuming we are decoding this immediately after returning
816            // from a function call and that the address of the structure is in x8
817            reg_info = reg_ctx->GetRegisterInfoByName("x8", 0);
818        }
819        else
820        {
821            // We are assuming we are stopped at the first instruction in a function
822            // and that the ABI is being respected so all parameters appear where they
823            // should be (functions with no external linkage can legally violate the ABI).
824            if (NGRN >= 8)
825                return false;
826
827            uint32_t reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + NGRN);
828            if (reg_num == LLDB_INVALID_REGNUM)
829                return false;
830            reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
831            if (reg_info == NULL)
832                return false;
833            ++NGRN;
834        }
835
836        if (reg_info == NULL)
837            return false;
838
839        const lldb::addr_t value_addr = reg_ctx->ReadRegisterAsUnsigned(reg_info, LLDB_INVALID_ADDRESS);
840
841        if (value_addr == LLDB_INVALID_ADDRESS)
842            return false;
843
844        if (exe_ctx.GetProcessRef().ReadMemory (value_addr,
845                                                heap_data_ap->GetBytes(),
846                                                heap_data_ap->GetByteSize(),
847                                                error) != heap_data_ap->GetByteSize())
848        {
849            return false;
850        }
851    }
852
853    data.SetByteOrder(byte_order);
854    data.SetAddressByteSize(exe_ctx.GetProcessRef().GetAddressByteSize());
855    data.SetData(DataBufferSP (heap_data_ap.release()));
856    return true;
857}
858
859ValueObjectSP
860ABIMacOSX_arm64::GetReturnValueObjectImpl (Thread &thread, CompilerType &return_compiler_type) const
861{
862    ValueObjectSP return_valobj_sp;
863    Value value;
864
865    ExecutionContext exe_ctx (thread.shared_from_this());
866    if (exe_ctx.GetTargetPtr() == NULL || exe_ctx.GetProcessPtr() == NULL)
867        return return_valobj_sp;
868
869    //value.SetContext (Value::eContextTypeClangType, return_compiler_type);
870    value.SetCompilerType(return_compiler_type);
871
872    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
873    if (!reg_ctx)
874        return return_valobj_sp;
875
876    const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
877
878    const uint32_t type_flags = return_compiler_type.GetTypeInfo (NULL);
879    if (type_flags & eTypeIsScalar ||
880        type_flags & eTypeIsPointer)
881    {
882        value.SetValueType(Value::eValueTypeScalar);
883
884        bool success = false;
885        if (type_flags & eTypeIsInteger ||
886            type_flags & eTypeIsPointer )
887        {
888            // Extract the register context so we can read arguments from registers
889            if (byte_size <= 8)
890            {
891                const RegisterInfo *x0_reg_info = reg_ctx->GetRegisterInfoByName("x0", 0);
892                if (x0_reg_info)
893                {
894                    uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, 0);
895                    const bool is_signed = (type_flags & eTypeIsSigned) != 0;
896                    switch (byte_size)
897                    {
898                        default:
899                            break;
900                        case 16: // uint128_t
901                            // In register x0 and x1
902                            {
903                                const RegisterInfo *x1_reg_info = reg_ctx->GetRegisterInfoByName("x1", 0);
904
905                                if (x1_reg_info)
906                                {
907                                    if (byte_size <= x0_reg_info->byte_size + x1_reg_info->byte_size)
908                                    {
909                                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
910                                        const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
911                                        RegisterValue x0_reg_value;
912                                        RegisterValue x1_reg_value;
913                                        if (reg_ctx->ReadRegister(x0_reg_info, x0_reg_value) &&
914                                            reg_ctx->ReadRegister(x1_reg_info, x1_reg_value))
915                                        {
916                                            Error error;
917                                            if (x0_reg_value.GetAsMemoryData (x0_reg_info, heap_data_ap->GetBytes()+0, 8, byte_order, error) &&
918                                                x1_reg_value.GetAsMemoryData (x1_reg_info, heap_data_ap->GetBytes()+8, 8, byte_order, error))
919                                            {
920                                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
921                                                                    byte_order,
922                                                                    exe_ctx.GetProcessRef().GetAddressByteSize());
923
924                                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
925                                                                                                   return_compiler_type,
926                                                                                                   ConstString(""),
927                                                                                                   data);
928                                                return return_valobj_sp;
929                                            }
930                                        }
931                                    }
932                                }
933                            }
934                            break;
935                        case sizeof(uint64_t):
936                            if (is_signed)
937                                value.GetScalar() = (int64_t)(raw_value);
938                            else
939                                value.GetScalar() = (uint64_t)(raw_value);
940                            success = true;
941                            break;
942
943                        case sizeof(uint32_t):
944                            if (is_signed)
945                                value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
946                            else
947                                value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
948                            success = true;
949                            break;
950
951                        case sizeof(uint16_t):
952                            if (is_signed)
953                                value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
954                            else
955                                value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
956                            success = true;
957                            break;
958
959                        case sizeof(uint8_t):
960                            if (is_signed)
961                                value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
962                            else
963                                value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
964                            success = true;
965                            break;
966                    }
967                }
968            }
969        }
970        else if (type_flags & eTypeIsFloat)
971        {
972            if (type_flags & eTypeIsComplex)
973            {
974                // Don't handle complex yet.
975            }
976            else
977            {
978                if (byte_size <= sizeof(long double))
979                {
980                    const RegisterInfo *v0_reg_info = reg_ctx->GetRegisterInfoByName("v0", 0);
981                    RegisterValue v0_value;
982                    if (reg_ctx->ReadRegister (v0_reg_info, v0_value))
983                    {
984                        DataExtractor data;
985                        if (v0_value.GetData(data))
986                        {
987                            lldb::offset_t offset = 0;
988                            if (byte_size == sizeof(float))
989                            {
990                                value.GetScalar() = data.GetFloat(&offset);
991                                success = true;
992                            }
993                            else if (byte_size == sizeof(double))
994                            {
995                                value.GetScalar() = data.GetDouble(&offset);
996                                success = true;
997                            }
998                            else if (byte_size == sizeof(long double))
999                            {
1000                                value.GetScalar() = data.GetLongDouble(&offset);
1001                                success = true;
1002                            }
1003                        }
1004                    }
1005                }
1006            }
1007        }
1008
1009        if (success)
1010            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
1011                                                               value,
1012                                                               ConstString(""));
1013
1014    }
1015    else if (type_flags & eTypeIsVector)
1016    {
1017        if (byte_size > 0)
1018        {
1019
1020            const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
1021
1022            if (v0_info)
1023            {
1024                if (byte_size <= v0_info->byte_size)
1025                {
1026                    std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
1027                    const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
1028                    RegisterValue reg_value;
1029                    if (reg_ctx->ReadRegister(v0_info, reg_value))
1030                    {
1031                        Error error;
1032                        if (reg_value.GetAsMemoryData (v0_info,
1033                                                       heap_data_ap->GetBytes(),
1034                                                       heap_data_ap->GetByteSize(),
1035                                                       byte_order,
1036                                                       error))
1037                        {
1038                            DataExtractor data (DataBufferSP (heap_data_ap.release()),
1039                                                byte_order,
1040                                                exe_ctx.GetProcessRef().GetAddressByteSize());
1041                            return_valobj_sp = ValueObjectConstResult::Create (&thread,
1042                                                                               return_compiler_type,
1043                                                                               ConstString(""),
1044                                                                               data);
1045                        }
1046                    }
1047                }
1048            }
1049        }
1050    }
1051    else if (type_flags & eTypeIsStructUnion ||
1052             type_flags & eTypeIsClass)
1053    {
1054        DataExtractor data;
1055
1056        uint32_t NGRN = 0;  // Search ABI docs for NGRN
1057        uint32_t NSRN = 0;  // Search ABI docs for NSRN
1058        const bool is_return_value = true;
1059        if (LoadValueFromConsecutiveGPRRegisters (exe_ctx, reg_ctx, return_compiler_type, is_return_value, NGRN, NSRN, data))
1060        {
1061            return_valobj_sp = ValueObjectConstResult::Create (&thread,
1062                                                               return_compiler_type,
1063                                                               ConstString(""),
1064                                                               data);
1065        }
1066    }
1067    return return_valobj_sp;
1068}
1069
1070void
1071ABIMacOSX_arm64::Initialize()
1072{
1073    PluginManager::RegisterPlugin (GetPluginNameStatic(),
1074                                   pluginDesc,
1075                                   CreateInstance);
1076}
1077
1078void
1079ABIMacOSX_arm64::Terminate()
1080{
1081    PluginManager::UnregisterPlugin (CreateInstance);
1082}
1083
1084//------------------------------------------------------------------
1085// PluginInterface protocol
1086//------------------------------------------------------------------
1087ConstString
1088ABIMacOSX_arm64::GetPluginNameStatic()
1089{
1090    static ConstString g_plugin_name("ABIMacOSX_arm64");
1091    return g_plugin_name;
1092}
1093
1094uint32_t
1095ABIMacOSX_arm64::GetPluginVersion()
1096{
1097    return 1;
1098}
1099
1100