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