]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / ABI / SysV-x86_64 / ABISysV_x86_64.cpp
1 //===-- ABISysV_x86_64.cpp --------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "ABISysV_x86_64.h"
10
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/Triple.h"
14
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Core/ValueObjectConstResult.h"
19 #include "lldb/Core/ValueObjectMemory.h"
20 #include "lldb/Core/ValueObjectRegister.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/ConstString.h"
28 #include "lldb/Utility/DataExtractor.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/RegisterValue.h"
31 #include "lldb/Utility/Status.h"
32
33 #include <vector>
34
35 using namespace lldb;
36 using namespace lldb_private;
37
38 enum dwarf_regnums {
39   dwarf_rax = 0,
40   dwarf_rdx,
41   dwarf_rcx,
42   dwarf_rbx,
43   dwarf_rsi,
44   dwarf_rdi,
45   dwarf_rbp,
46   dwarf_rsp,
47   dwarf_r8,
48   dwarf_r9,
49   dwarf_r10,
50   dwarf_r11,
51   dwarf_r12,
52   dwarf_r13,
53   dwarf_r14,
54   dwarf_r15,
55   dwarf_rip,
56   dwarf_xmm0,
57   dwarf_xmm1,
58   dwarf_xmm2,
59   dwarf_xmm3,
60   dwarf_xmm4,
61   dwarf_xmm5,
62   dwarf_xmm6,
63   dwarf_xmm7,
64   dwarf_xmm8,
65   dwarf_xmm9,
66   dwarf_xmm10,
67   dwarf_xmm11,
68   dwarf_xmm12,
69   dwarf_xmm13,
70   dwarf_xmm14,
71   dwarf_xmm15,
72   dwarf_stmm0,
73   dwarf_stmm1,
74   dwarf_stmm2,
75   dwarf_stmm3,
76   dwarf_stmm4,
77   dwarf_stmm5,
78   dwarf_stmm6,
79   dwarf_stmm7,
80   dwarf_ymm0,
81   dwarf_ymm1,
82   dwarf_ymm2,
83   dwarf_ymm3,
84   dwarf_ymm4,
85   dwarf_ymm5,
86   dwarf_ymm6,
87   dwarf_ymm7,
88   dwarf_ymm8,
89   dwarf_ymm9,
90   dwarf_ymm10,
91   dwarf_ymm11,
92   dwarf_ymm12,
93   dwarf_ymm13,
94   dwarf_ymm14,
95   dwarf_ymm15,
96   dwarf_bnd0 = 126,
97   dwarf_bnd1,
98   dwarf_bnd2,
99   dwarf_bnd3
100 };
101
102 static RegisterInfo g_register_infos[] = {
103     // clang-format off
104     // NAME      ALT      SZ OFF  ENCODING         FORMAT                     EH_FRAME                DWARF                     GENERIC                     LLDB                  NATIVE
105     // ========  =======  == ===  =============    ===================        ======================= =====================     =========================== ===================== ======================
106     {"rax",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_rax,              dwarf_rax,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
107     {"rbx",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_rbx,              dwarf_rbx,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
108     {"rcx",      "arg4",   8,  0, eEncodingUint,   eFormatHex,               {dwarf_rcx,              dwarf_rcx,                LLDB_REGNUM_GENERIC_ARG4,   LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
109     {"rdx",      "arg3",   8,  0, eEncodingUint,   eFormatHex,               {dwarf_rdx,              dwarf_rdx,                LLDB_REGNUM_GENERIC_ARG3,   LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
110     {"rsi",      "arg2",   8,  0, eEncodingUint,   eFormatHex,               {dwarf_rsi,              dwarf_rsi,                LLDB_REGNUM_GENERIC_ARG2,   LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
111     {"rdi",      "arg1",   8,  0, eEncodingUint,   eFormatHex,               {dwarf_rdi,              dwarf_rdi,                LLDB_REGNUM_GENERIC_ARG1,   LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
112     {"rbp",      "fp",     8,  0, eEncodingUint,   eFormatHex,               {dwarf_rbp,              dwarf_rbp,                LLDB_REGNUM_GENERIC_FP,     LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
113     {"rsp",      "sp",     8,  0, eEncodingUint,   eFormatHex,               {dwarf_rsp,              dwarf_rsp,                LLDB_REGNUM_GENERIC_SP,     LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
114     {"r8",       "arg5",   8,  0, eEncodingUint,   eFormatHex,               {dwarf_r8,               dwarf_r8,                 LLDB_REGNUM_GENERIC_ARG5,   LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
115     {"r9",       "arg6",   8,  0, eEncodingUint,   eFormatHex,               {dwarf_r9,               dwarf_r9,                 LLDB_REGNUM_GENERIC_ARG6,   LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
116     {"r10",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_r10,              dwarf_r10,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
117     {"r11",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_r11,              dwarf_r11,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
118     {"r12",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_r12,              dwarf_r12,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
119     {"r13",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_r13,              dwarf_r13,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
120     {"r14",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_r14,              dwarf_r14,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
121     {"r15",      nullptr,  8,  0, eEncodingUint,   eFormatHex,               {dwarf_r15,              dwarf_r15,                LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
122     {"rip",      "pc",     8,  0, eEncodingUint,   eFormatHex,               {dwarf_rip,              dwarf_rip,                LLDB_REGNUM_GENERIC_PC,     LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
123     {"rflags",   nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
124     {"cs",       nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
125     {"ss",       nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
126     {"ds",       nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
127     {"es",       nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
128     {"fs",       nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
129     {"gs",       nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
130     {"stmm0",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm0,            dwarf_stmm0,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
131     {"stmm1",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm1,            dwarf_stmm1,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
132     {"stmm2",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm2,            dwarf_stmm2,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
133     {"stmm3",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm3,            dwarf_stmm3,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
134     {"stmm4",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm4,            dwarf_stmm4,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
135     {"stmm5",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm5,            dwarf_stmm5,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
136     {"stmm6",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm6,            dwarf_stmm6,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
137     {"stmm7",    nullptr, 10,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_stmm7,            dwarf_stmm7,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
138     {"fctrl",    nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
139     {"fstat",    nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
140     {"ftag",     nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
141     {"fiseg",    nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
142     {"fioff",    nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
143     {"foseg",    nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
144     {"fooff",    nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
145     {"fop",      nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
146     {"xmm0",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm0,             dwarf_xmm0,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
147     {"xmm1",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm1,             dwarf_xmm1,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
148     {"xmm2",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm2,             dwarf_xmm2,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
149     {"xmm3",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm3,             dwarf_xmm3,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
150     {"xmm4",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm4,             dwarf_xmm4,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
151     {"xmm5",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm5,             dwarf_xmm5,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
152     {"xmm6",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm6,             dwarf_xmm6,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
153     {"xmm7",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm7,             dwarf_xmm7,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
154     {"xmm8",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm8,             dwarf_xmm8,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
155     {"xmm9",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm9,             dwarf_xmm9,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
156     {"xmm10",    nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm10,            dwarf_xmm10,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
157     {"xmm11",    nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm11,            dwarf_xmm11,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
158     {"xmm12",    nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm12,            dwarf_xmm12,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
159     {"xmm13",    nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm13,            dwarf_xmm13,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
160     {"xmm14",    nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm14,            dwarf_xmm14,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
161     {"xmm15",    nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_xmm15,            dwarf_xmm15,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
162     {"mxcsr",    nullptr,  4,  0, eEncodingUint,   eFormatHex,               {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
163     {"ymm0",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm0,             dwarf_ymm0,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
164     {"ymm1",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm1,             dwarf_ymm1,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
165     {"ymm2",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm2,             dwarf_ymm2,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
166     {"ymm3",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm3,             dwarf_ymm3,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
167     {"ymm4",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm4,             dwarf_ymm4,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
168     {"ymm5",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm5,             dwarf_ymm5,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
169     {"ymm6",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm6,             dwarf_ymm6,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
170     {"ymm7",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm7,             dwarf_ymm7,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
171     {"ymm8",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm8,             dwarf_ymm8,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
172     {"ymm9",     nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm9,             dwarf_ymm9,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
173     {"ymm10",    nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm10,            dwarf_ymm10,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
174     {"ymm11",    nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm11,            dwarf_ymm11,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
175     {"ymm12",    nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm12,            dwarf_ymm12,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
176     {"ymm13",    nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm13,            dwarf_ymm13,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
177     {"ymm14",    nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm14,            dwarf_ymm14,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
178     {"ymm15",    nullptr, 32,  0, eEncodingVector, eFormatVectorOfUInt8,     {dwarf_ymm15,            dwarf_ymm15,              LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
179     {"bnd0",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt64,    {dwarf_bnd0,             dwarf_bnd0,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
180     {"bnd1",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt64,    {dwarf_bnd1,             dwarf_bnd1,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
181     {"bnd2",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt64,    {dwarf_bnd2,             dwarf_bnd2,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
182     {"bnd3",     nullptr, 16,  0, eEncodingVector, eFormatVectorOfUInt64,    {dwarf_bnd3,             dwarf_bnd3,               LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
183     {"bndcfgu",  nullptr,  8,  0, eEncodingVector, eFormatVectorOfUInt8,     {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
184     {"bndstatus",nullptr,  8,  0, eEncodingVector, eFormatVectorOfUInt8,     {LLDB_INVALID_REGNUM,    LLDB_INVALID_REGNUM,      LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM},     nullptr,     nullptr,     nullptr,     0},
185     // clang-format on
186 };
187
188 static const uint32_t k_num_register_infos =
189     llvm::array_lengthof(g_register_infos);
190 static bool g_register_info_names_constified = false;
191
192 const lldb_private::RegisterInfo *
193 ABISysV_x86_64::GetRegisterInfoArray(uint32_t &count) {
194   // Make the C-string names and alt_names for the register infos into const
195   // C-string values by having the ConstString unique the names in the global
196   // constant C-string pool.
197   if (!g_register_info_names_constified) {
198     g_register_info_names_constified = true;
199     for (uint32_t i = 0; i < k_num_register_infos; ++i) {
200       if (g_register_infos[i].name)
201         g_register_infos[i].name =
202             ConstString(g_register_infos[i].name).GetCString();
203       if (g_register_infos[i].alt_name)
204         g_register_infos[i].alt_name =
205             ConstString(g_register_infos[i].alt_name).GetCString();
206     }
207   }
208   count = k_num_register_infos;
209   return g_register_infos;
210 }
211
212 bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) {
213   name = "rax";
214   return true;
215 }
216
217 size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; }
218
219 // Static Functions
220
221 ABISP
222 ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
223   const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
224   const llvm::Triple::OSType os_type = arch.GetTriple().getOS();
225   if (arch_type == llvm::Triple::x86_64) {
226     switch(os_type) {
227       case llvm::Triple::OSType::MacOSX:
228       case llvm::Triple::OSType::Linux:
229       case llvm::Triple::OSType::FreeBSD:
230       case llvm::Triple::OSType::NetBSD:
231       case llvm::Triple::OSType::Solaris:
232       case llvm::Triple::OSType::UnknownOS:
233         return ABISP(new ABISysV_x86_64(process_sp));
234       default: 
235         return ABISP();
236     }
237   }
238   return ABISP();
239 }
240
241 bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
242                                         addr_t func_addr, addr_t return_addr,
243                                         llvm::ArrayRef<addr_t> args) const {
244   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
245
246   if (log) {
247     StreamString s;
248     s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
249              ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
250              ", return_addr = 0x%" PRIx64,
251              thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
252              (uint64_t)return_addr);
253
254     for (size_t i = 0; i < args.size(); ++i)
255       s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
256                args[i]);
257     s.PutCString(")");
258     log->PutString(s.GetString());
259   }
260
261   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
262   if (!reg_ctx)
263     return false;
264
265   const RegisterInfo *reg_info = nullptr;
266
267   if (args.size() > 6) // TODO handle more than 6 arguments
268     return false;
269
270   for (size_t i = 0; i < args.size(); ++i) {
271     reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
272                                         LLDB_REGNUM_GENERIC_ARG1 + i);
273     if (log)
274       log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
275                   static_cast<uint64_t>(i + 1), args[i], reg_info->name);
276     if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
277       return false;
278   }
279
280   // First, align the SP
281
282   if (log)
283     log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
284                 (uint64_t)sp, (uint64_t)(sp & ~0xfull));
285
286   sp &= ~(0xfull); // 16-byte alignment
287
288   sp -= 8;
289
290   Status error;
291   const RegisterInfo *pc_reg_info =
292       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
293   const RegisterInfo *sp_reg_info =
294       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
295   ProcessSP process_sp(thread.GetProcess());
296
297   RegisterValue reg_value;
298   if (log)
299     log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
300                 ": 0x%" PRIx64,
301                 (uint64_t)sp, (uint64_t)return_addr);
302
303   // Save return address onto the stack
304   if (!process_sp->WritePointerToMemory(sp, return_addr, error))
305     return false;
306
307   // %rsp is set to the actual stack value.
308
309   if (log)
310     log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
311
312   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
313     return false;
314
315   // %rip is set to the address of the called function.
316
317   if (log)
318     log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
319
320   if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
321     return false;
322
323   return true;
324 }
325
326 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
327                                 bool is_signed, Thread &thread,
328                                 uint32_t *argument_register_ids,
329                                 unsigned int &current_argument_register,
330                                 addr_t &current_stack_argument) {
331   if (bit_width > 64)
332     return false; // Scalar can't hold large integer arguments
333
334   if (current_argument_register < 6) {
335     scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
336         argument_register_ids[current_argument_register], 0);
337     current_argument_register++;
338     if (is_signed)
339       scalar.SignExtend(bit_width);
340   } else {
341     uint32_t byte_size = (bit_width + (8 - 1)) / 8;
342     Status error;
343     if (thread.GetProcess()->ReadScalarIntegerFromMemory(
344             current_stack_argument, byte_size, is_signed, scalar, error)) {
345       current_stack_argument += byte_size;
346       return true;
347     }
348     return false;
349   }
350   return true;
351 }
352
353 bool ABISysV_x86_64::GetArgumentValues(Thread &thread,
354                                        ValueList &values) const {
355   unsigned int num_values = values.GetSize();
356   unsigned int value_index;
357
358   // Extract the register context so we can read arguments from registers
359
360   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
361
362   if (!reg_ctx)
363     return false;
364
365   // Get the pointer to the first stack argument so we have a place to start
366   // when reading data
367
368   addr_t sp = reg_ctx->GetSP(0);
369
370   if (!sp)
371     return false;
372
373   addr_t current_stack_argument = sp + 8; // jump over return address
374
375   uint32_t argument_register_ids[6];
376
377   argument_register_ids[0] =
378       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
379           ->kinds[eRegisterKindLLDB];
380   argument_register_ids[1] =
381       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
382           ->kinds[eRegisterKindLLDB];
383   argument_register_ids[2] =
384       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
385           ->kinds[eRegisterKindLLDB];
386   argument_register_ids[3] =
387       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
388           ->kinds[eRegisterKindLLDB];
389   argument_register_ids[4] =
390       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
391           ->kinds[eRegisterKindLLDB];
392   argument_register_ids[5] =
393       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
394           ->kinds[eRegisterKindLLDB];
395
396   unsigned int current_argument_register = 0;
397
398   for (value_index = 0; value_index < num_values; ++value_index) {
399     Value *value = values.GetValueAtIndex(value_index);
400
401     if (!value)
402       return false;
403
404     // We currently only support extracting values with Clang QualTypes. Do we
405     // care about others?
406     CompilerType compiler_type = value->GetCompilerType();
407     llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
408     if (!bit_size)
409       return false;
410     bool is_signed;
411
412     if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
413       ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
414                           argument_register_ids, current_argument_register,
415                           current_stack_argument);
416     } else if (compiler_type.IsPointerType()) {
417       ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
418                           argument_register_ids, current_argument_register,
419                           current_stack_argument);
420     }
421   }
422
423   return true;
424 }
425
426 Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
427                                             lldb::ValueObjectSP &new_value_sp) {
428   Status error;
429   if (!new_value_sp) {
430     error.SetErrorString("Empty value object for return value.");
431     return error;
432   }
433
434   CompilerType compiler_type = new_value_sp->GetCompilerType();
435   if (!compiler_type) {
436     error.SetErrorString("Null clang type for return value.");
437     return error;
438   }
439
440   Thread *thread = frame_sp->GetThread().get();
441
442   bool is_signed;
443   uint32_t count;
444   bool is_complex;
445
446   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
447
448   bool set_it_simple = false;
449   if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
450       compiler_type.IsPointerType()) {
451     const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
452
453     DataExtractor data;
454     Status data_error;
455     size_t num_bytes = new_value_sp->GetData(data, data_error);
456     if (data_error.Fail()) {
457       error.SetErrorStringWithFormat(
458           "Couldn't convert return value to raw data: %s",
459           data_error.AsCString());
460       return error;
461     }
462     lldb::offset_t offset = 0;
463     if (num_bytes <= 8) {
464       uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
465
466       if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
467         set_it_simple = true;
468     } else {
469       error.SetErrorString("We don't support returning longer than 64 bit "
470                            "integer values at present.");
471     }
472   } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
473     if (is_complex)
474       error.SetErrorString(
475           "We don't support returning complex values at present");
476     else {
477       llvm::Optional<uint64_t> bit_width =
478           compiler_type.GetBitSize(frame_sp.get());
479       if (!bit_width) {
480         error.SetErrorString("can't get type size");
481         return error;
482       }
483       if (*bit_width <= 64) {
484         const RegisterInfo *xmm0_info =
485             reg_ctx->GetRegisterInfoByName("xmm0", 0);
486         RegisterValue xmm0_value;
487         DataExtractor data;
488         Status data_error;
489         size_t num_bytes = new_value_sp->GetData(data, data_error);
490         if (data_error.Fail()) {
491           error.SetErrorStringWithFormat(
492               "Couldn't convert return value to raw data: %s",
493               data_error.AsCString());
494           return error;
495         }
496
497         unsigned char buffer[16];
498         ByteOrder byte_order = data.GetByteOrder();
499
500         data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
501         xmm0_value.SetBytes(buffer, 16, byte_order);
502         reg_ctx->WriteRegister(xmm0_info, xmm0_value);
503         set_it_simple = true;
504       } else {
505         // FIXME - don't know how to do 80 bit long doubles yet.
506         error.SetErrorString(
507             "We don't support returning float values > 64 bits at present");
508       }
509     }
510   }
511
512   if (!set_it_simple) {
513     // Okay we've got a structure or something that doesn't fit in a simple
514     // register. We should figure out where it really goes, but we don't
515     // support this yet.
516     error.SetErrorString("We only support setting simple integer and float "
517                          "return types at present.");
518   }
519
520   return error;
521 }
522
523 ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
524     Thread &thread, CompilerType &return_compiler_type) const {
525   ValueObjectSP return_valobj_sp;
526   Value value;
527
528   if (!return_compiler_type)
529     return return_valobj_sp;
530
531   // value.SetContext (Value::eContextTypeClangType, return_value_type);
532   value.SetCompilerType(return_compiler_type);
533
534   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
535   if (!reg_ctx)
536     return return_valobj_sp;
537
538   const uint32_t type_flags = return_compiler_type.GetTypeInfo();
539   if (type_flags & eTypeIsScalar) {
540     value.SetValueType(Value::eValueTypeScalar);
541
542     bool success = false;
543     if (type_flags & eTypeIsInteger) {
544       // Extract the register context so we can read arguments from registers
545
546       llvm::Optional<uint64_t> byte_size =
547           return_compiler_type.GetByteSize(nullptr);
548       if (!byte_size)
549         return return_valobj_sp;
550       uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
551           reg_ctx->GetRegisterInfoByName("rax", 0), 0);
552       const bool is_signed = (type_flags & eTypeIsSigned) != 0;
553       switch (*byte_size) {
554       default:
555         break;
556
557       case sizeof(uint64_t):
558         if (is_signed)
559           value.GetScalar() = (int64_t)(raw_value);
560         else
561           value.GetScalar() = (uint64_t)(raw_value);
562         success = true;
563         break;
564
565       case sizeof(uint32_t):
566         if (is_signed)
567           value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
568         else
569           value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
570         success = true;
571         break;
572
573       case sizeof(uint16_t):
574         if (is_signed)
575           value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
576         else
577           value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
578         success = true;
579         break;
580
581       case sizeof(uint8_t):
582         if (is_signed)
583           value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
584         else
585           value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
586         success = true;
587         break;
588       }
589     } else if (type_flags & eTypeIsFloat) {
590       if (type_flags & eTypeIsComplex) {
591         // Don't handle complex yet.
592       } else {
593         llvm::Optional<uint64_t> byte_size =
594             return_compiler_type.GetByteSize(nullptr);
595         if (byte_size && *byte_size <= sizeof(long double)) {
596           const RegisterInfo *xmm0_info =
597               reg_ctx->GetRegisterInfoByName("xmm0", 0);
598           RegisterValue xmm0_value;
599           if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
600             DataExtractor data;
601             if (xmm0_value.GetData(data)) {
602               lldb::offset_t offset = 0;
603               if (*byte_size == sizeof(float)) {
604                 value.GetScalar() = (float)data.GetFloat(&offset);
605                 success = true;
606               } else if (*byte_size == sizeof(double)) {
607                 value.GetScalar() = (double)data.GetDouble(&offset);
608                 success = true;
609               } else if (*byte_size == sizeof(long double)) {
610                 // Don't handle long double since that can be encoded as 80 bit
611                 // floats...
612               }
613             }
614           }
615         }
616       }
617     }
618
619     if (success)
620       return_valobj_sp = ValueObjectConstResult::Create(
621           thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
622   } else if (type_flags & eTypeIsPointer) {
623     unsigned rax_id =
624         reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
625     value.GetScalar() =
626         (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
627                                                                       0);
628     value.SetValueType(Value::eValueTypeScalar);
629     return_valobj_sp = ValueObjectConstResult::Create(
630         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
631   } else if (type_flags & eTypeIsVector) {
632     llvm::Optional<uint64_t> byte_size =
633         return_compiler_type.GetByteSize(nullptr);
634     if (byte_size && *byte_size > 0) {
635       const RegisterInfo *altivec_reg =
636           reg_ctx->GetRegisterInfoByName("xmm0", 0);
637       if (altivec_reg == nullptr)
638         altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
639
640       if (altivec_reg) {
641         if (*byte_size <= altivec_reg->byte_size) {
642           ProcessSP process_sp(thread.GetProcess());
643           if (process_sp) {
644             std::unique_ptr<DataBufferHeap> heap_data_up(
645                 new DataBufferHeap(*byte_size, 0));
646             const ByteOrder byte_order = process_sp->GetByteOrder();
647             RegisterValue reg_value;
648             if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
649               Status error;
650               if (reg_value.GetAsMemoryData(
651                       altivec_reg, heap_data_up->GetBytes(),
652                       heap_data_up->GetByteSize(), byte_order, error)) {
653                 DataExtractor data(DataBufferSP(heap_data_up.release()),
654                                    byte_order,
655                                    process_sp->GetTarget()
656                                        .GetArchitecture()
657                                        .GetAddressByteSize());
658                 return_valobj_sp = ValueObjectConstResult::Create(
659                     &thread, return_compiler_type, ConstString(""), data);
660               }
661             }
662           }
663         } else if (*byte_size <= altivec_reg->byte_size * 2) {
664           const RegisterInfo *altivec_reg2 =
665               reg_ctx->GetRegisterInfoByName("xmm1", 0);
666           if (altivec_reg2) {
667             ProcessSP process_sp(thread.GetProcess());
668             if (process_sp) {
669               std::unique_ptr<DataBufferHeap> heap_data_up(
670                   new DataBufferHeap(*byte_size, 0));
671               const ByteOrder byte_order = process_sp->GetByteOrder();
672               RegisterValue reg_value;
673               RegisterValue reg_value2;
674               if (reg_ctx->ReadRegister(altivec_reg, reg_value) &&
675                   reg_ctx->ReadRegister(altivec_reg2, reg_value2)) {
676
677                 Status error;
678                 if (reg_value.GetAsMemoryData(
679                         altivec_reg, heap_data_up->GetBytes(),
680                         altivec_reg->byte_size, byte_order, error) &&
681                     reg_value2.GetAsMemoryData(
682                         altivec_reg2,
683                         heap_data_up->GetBytes() + altivec_reg->byte_size,
684                         heap_data_up->GetByteSize() - altivec_reg->byte_size,
685                         byte_order, error)) {
686                   DataExtractor data(DataBufferSP(heap_data_up.release()),
687                                      byte_order,
688                                      process_sp->GetTarget()
689                                          .GetArchitecture()
690                                          .GetAddressByteSize());
691                   return_valobj_sp = ValueObjectConstResult::Create(
692                       &thread, return_compiler_type, ConstString(""), data);
693                 }
694               }
695             }
696           }
697         }
698       }
699     }
700   }
701
702   return return_valobj_sp;
703 }
704
705 // The compiler will flatten the nested aggregate type into single
706 // layer and push the value to stack
707 // This helper function will flatten an aggregate type
708 // and return true if it can be returned in register(s) by value
709 // return false if the aggregate is in memory
710 static bool FlattenAggregateType(
711     Thread &thread, ExecutionContext &exe_ctx,
712     CompilerType &return_compiler_type,
713     uint32_t data_byte_offset,
714     std::vector<uint32_t> &aggregate_field_offsets,
715     std::vector<CompilerType> &aggregate_compiler_types) {
716
717   const uint32_t num_children = return_compiler_type.GetNumFields();
718   for (uint32_t idx = 0; idx < num_children; ++idx) {
719     std::string name;
720     bool is_signed;
721     uint32_t count;
722     bool is_complex;
723
724     uint64_t field_bit_offset = 0;
725     CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
726         idx, name, &field_bit_offset, nullptr, nullptr);
727     llvm::Optional<uint64_t> field_bit_width =
728           field_compiler_type.GetBitSize(&thread);
729
730     // if we don't know the size of the field (e.g. invalid type), exit
731     if (!field_bit_width || *field_bit_width == 0) {
732       return false;
733     }
734
735     uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
736
737     const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
738     if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
739         field_compiler_type.IsPointerType() ||
740         field_compiler_type.IsFloatingPointType(count, is_complex)) {
741       aggregate_field_offsets.push_back(field_byte_offset);
742       aggregate_compiler_types.push_back(field_compiler_type);
743     } else if (field_type_flags & eTypeHasChildren) {
744       if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
745                                 field_byte_offset, aggregate_field_offsets,
746                                 aggregate_compiler_types)) {
747         return false;
748       }
749     }
750   }
751   return true;
752 }
753
754 ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
755     Thread &thread, CompilerType &return_compiler_type) const {
756   ValueObjectSP return_valobj_sp;
757
758   if (!return_compiler_type)
759     return return_valobj_sp;
760
761   ExecutionContext exe_ctx(thread.shared_from_this());
762   return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
763   if (return_valobj_sp)
764     return return_valobj_sp;
765
766   RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
767   if (!reg_ctx_sp)
768     return return_valobj_sp;
769
770   llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
771   if (!bit_width)
772     return return_valobj_sp;
773   if (return_compiler_type.IsAggregateType()) {
774     Target *target = exe_ctx.GetTargetPtr();
775     bool is_memory = true;
776     std::vector<uint32_t> aggregate_field_offsets;
777     std::vector<CompilerType> aggregate_compiler_types;
778     if (return_compiler_type.GetTypeSystem()->CanPassInRegisters(
779           return_compiler_type) &&
780       *bit_width <= 128 &&
781       FlattenAggregateType(thread, exe_ctx, return_compiler_type,
782                           0, aggregate_field_offsets,
783                           aggregate_compiler_types)) {
784       ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
785       DataBufferSP data_sp(new DataBufferHeap(16, 0));
786       DataExtractor return_ext(data_sp, byte_order,
787                                target->GetArchitecture().GetAddressByteSize());
788
789       const RegisterInfo *rax_info =
790           reg_ctx_sp->GetRegisterInfoByName("rax", 0);
791       const RegisterInfo *rdx_info =
792           reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
793       const RegisterInfo *xmm0_info =
794           reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
795       const RegisterInfo *xmm1_info =
796           reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
797
798       RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
799       reg_ctx_sp->ReadRegister(rax_info, rax_value);
800       reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
801       reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value);
802       reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value);
803
804       DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
805
806       rax_value.GetData(rax_data);
807       rdx_value.GetData(rdx_data);
808       xmm0_value.GetData(xmm0_data);
809       xmm1_value.GetData(xmm1_data);
810
811       uint32_t fp_bytes =
812           0; // Tracks how much of the xmm registers we've consumed so far
813       uint32_t integer_bytes =
814           0; // Tracks how much of the rax/rds registers we've consumed so far
815
816       // in case of the returned type is a subclass of non-abstract-base class
817       // it will have a padding to skip the base content
818       if (aggregate_field_offsets.size()) {
819         fp_bytes = aggregate_field_offsets[0];
820         integer_bytes = aggregate_field_offsets[0];
821       }
822
823       const uint32_t num_children = aggregate_compiler_types.size();
824
825       // Since we are in the small struct regime, assume we are not in memory.
826       is_memory = false;
827       for (uint32_t idx = 0; idx < num_children; idx++) {
828         bool is_signed;
829         uint32_t count;
830         bool is_complex;
831
832         CompilerType field_compiler_type = aggregate_compiler_types[idx];
833         uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread));
834         uint32_t field_byte_offset = aggregate_field_offsets[idx];
835
836         uint32_t field_bit_width = field_byte_width * 8;
837
838         DataExtractor *copy_from_extractor = nullptr;
839         uint32_t copy_from_offset = 0;
840
841         if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
842             field_compiler_type.IsPointerType()) {
843           if (integer_bytes < 8) {
844             if (integer_bytes + field_byte_width <= 8) {
845               // This is in RAX, copy from register to our result structure:
846               copy_from_extractor = &rax_data;
847               copy_from_offset = integer_bytes;
848               integer_bytes += field_byte_width;
849             } else {
850               // The next field wouldn't fit in the remaining space, so we
851               // pushed it to rdx.
852               copy_from_extractor = &rdx_data;
853               copy_from_offset = 0;
854               integer_bytes = 8 + field_byte_width;
855             }
856           } else if (integer_bytes + field_byte_width <= 16) {
857             copy_from_extractor = &rdx_data;
858             copy_from_offset = integer_bytes - 8;
859             integer_bytes += field_byte_width;
860           } else {
861             // The last field didn't fit.  I can't see how that would happen
862             // w/o the overall size being greater than 16 bytes.  For now,
863             // return a nullptr return value object.
864             return return_valobj_sp;
865           }
866         } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
867           // Structs with long doubles are always passed in memory.
868           if (field_bit_width == 128) {
869             is_memory = true;
870             break;
871           } else if (field_bit_width == 64) {
872             // These have to be in a single xmm register.
873             if (fp_bytes == 0)
874               copy_from_extractor = &xmm0_data;
875             else
876               copy_from_extractor = &xmm1_data;
877
878             copy_from_offset = 0;
879             fp_bytes += field_byte_width;
880           } else if (field_bit_width == 32) {
881             // This one is kind of complicated.  If we are in an "eightbyte"
882             // with another float, we'll be stuffed into an xmm register with
883             // it.  If we are in an "eightbyte" with one or more ints, then we
884             // will be stuffed into the appropriate GPR with them.
885             bool in_gpr;
886             if (field_byte_offset % 8 == 0) {
887               // We are at the beginning of one of the eightbytes, so check the
888               // next element (if any)
889               if (idx == num_children - 1) {
890                 in_gpr = false;
891               } else {
892                 CompilerType next_field_compiler_type =
893                     aggregate_compiler_types[idx + 1];
894                 if (next_field_compiler_type.IsIntegerOrEnumerationType(
895                         is_signed)) {
896                   in_gpr = true;
897                 } else {
898                   copy_from_offset = 0;
899                   in_gpr = false;
900                 }
901               }
902             } else if (field_byte_offset % 4 == 0) {
903               // We are inside of an eightbyte, so see if the field before us
904               // is floating point: This could happen if somebody put padding
905               // in the structure.
906               if (idx == 0) {
907                 in_gpr = false;
908               } else {
909                 CompilerType prev_field_compiler_type =
910                     aggregate_compiler_types[idx - 1];
911                 if (prev_field_compiler_type.IsIntegerOrEnumerationType(
912                         is_signed)) {
913                   in_gpr = true;
914                 } else {
915                   copy_from_offset = 4;
916                   in_gpr = false;
917                 }
918               }
919             } else {
920               is_memory = true;
921               continue;
922             }
923
924             // Okay, we've figured out whether we are in GPR or XMM, now figure
925             // out which one.
926             if (in_gpr) {
927               if (integer_bytes < 8) {
928                 // This is in RAX, copy from register to our result structure:
929                 copy_from_extractor = &rax_data;
930                 copy_from_offset = integer_bytes;
931                 integer_bytes += field_byte_width;
932               } else {
933                 copy_from_extractor = &rdx_data;
934                 copy_from_offset = integer_bytes - 8;
935                 integer_bytes += field_byte_width;
936               }
937             } else {
938               if (fp_bytes < 8)
939                 copy_from_extractor = &xmm0_data;
940               else
941                 copy_from_extractor = &xmm1_data;
942
943               fp_bytes += field_byte_width;
944             }
945           }
946         }
947         // These two tests are just sanity checks.  If I somehow get the type
948         // calculation wrong above it is better to just return nothing than to
949         // assert or crash.
950         if (!copy_from_extractor)
951           return return_valobj_sp;
952         if (copy_from_offset + field_byte_width >
953             copy_from_extractor->GetByteSize())
954           return return_valobj_sp;
955         copy_from_extractor->CopyByteOrderedData(
956             copy_from_offset, field_byte_width,
957             data_sp->GetBytes() + field_byte_offset, field_byte_width,
958             byte_order);
959       }
960       if (!is_memory) {
961         // The result is in our data buffer.  Let's make a variable object out
962         // of it:
963         return_valobj_sp = ValueObjectConstResult::Create(
964             &thread, return_compiler_type, ConstString(""), return_ext);
965       }
966     }
967
968     // FIXME: This is just taking a guess, rax may very well no longer hold the
969     // return storage location.
970     // If we are going to do this right, when we make a new frame we should
971     // check to see if it uses a memory return, and if we are at the first
972     // instruction and if so stash away the return location.  Then we would
973     // only return the memory return value if we know it is valid.
974
975     if (is_memory) {
976       unsigned rax_id =
977           reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
978       lldb::addr_t storage_addr =
979           (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
980                                                                         0);
981       return_valobj_sp = ValueObjectMemory::Create(
982           &thread, "", Address(storage_addr, nullptr), return_compiler_type);
983     }
984   }
985
986   return return_valobj_sp;
987 }
988
989 // This defines the CFA as rsp+8
990 // the saved pc is at CFA-8 (i.e. rsp+0)
991 // The saved rsp is CFA+0
992
993 bool ABISysV_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
994   unwind_plan.Clear();
995   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
996
997   uint32_t sp_reg_num = dwarf_rsp;
998   uint32_t pc_reg_num = dwarf_rip;
999
1000   UnwindPlan::RowSP row(new UnwindPlan::Row);
1001   row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
1002   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
1003   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1004   unwind_plan.AppendRow(row);
1005   unwind_plan.SetSourceName("x86_64 at-func-entry default");
1006   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1007   return true;
1008 }
1009
1010 // This defines the CFA as rbp+16
1011 // The saved pc is at CFA-8 (i.e. rbp+8)
1012 // The saved rbp is at CFA-16 (i.e. rbp+0)
1013 // The saved rsp is CFA+0
1014
1015 bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1016   unwind_plan.Clear();
1017   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1018
1019   uint32_t fp_reg_num = dwarf_rbp;
1020   uint32_t sp_reg_num = dwarf_rsp;
1021   uint32_t pc_reg_num = dwarf_rip;
1022
1023   UnwindPlan::RowSP row(new UnwindPlan::Row);
1024
1025   const int32_t ptr_size = 8;
1026   row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
1027   row->SetOffset(0);
1028
1029   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1030   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1031   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1032
1033   unwind_plan.AppendRow(row);
1034   unwind_plan.SetSourceName("x86_64 default unwind plan");
1035   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1036   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1037   return true;
1038 }
1039
1040 bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1041   return !RegisterIsCalleeSaved(reg_info);
1042 }
1043
1044 // See "Register Usage" in the
1045 // "System V Application Binary Interface"
1046 // "AMD64 Architecture Processor Supplement" (or "x86-64(tm) Architecture
1047 // Processor Supplement" in earlier revisions) (this doc is also commonly
1048 // referred to as the x86-64/AMD64 psABI) Edited by Michael Matz, Jan Hubicka,
1049 // Andreas Jaeger, and Mark Mitchell current version is 0.99.6 released
1050 // 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
1051 // It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
1052
1053 bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1054   if (!reg_info)
1055     return false;
1056   assert(reg_info->name != nullptr && "unnamed register?");
1057   std::string Name = std::string(reg_info->name);
1058   bool IsCalleeSaved =
1059       llvm::StringSwitch<bool>(Name)
1060           .Cases("r12", "r13", "r14", "r15", "rbp", "ebp", "rbx", "ebx", true)
1061           .Cases("rip", "eip", "rsp", "esp", "sp", "fp", "pc", true)
1062           .Default(false);
1063   return IsCalleeSaved;
1064 }
1065
1066 void ABISysV_x86_64::Initialize() {
1067   PluginManager::RegisterPlugin(
1068       GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance);
1069 }
1070
1071 void ABISysV_x86_64::Terminate() {
1072   PluginManager::UnregisterPlugin(CreateInstance);
1073 }
1074
1075 lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() {
1076   static ConstString g_name("sysv-x86_64");
1077   return g_name;
1078 }
1079
1080 // PluginInterface protocol
1081
1082 lldb_private::ConstString ABISysV_x86_64::GetPluginName() {
1083   return GetPluginNameStatic();
1084 }
1085
1086 uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; }