ABISysV_x86_64.cpp revision 360784
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
35using namespace lldb;
36using namespace lldb_private;
37
38enum 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
102static 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
188static const uint32_t k_num_register_infos =
189    llvm::array_lengthof(g_register_infos);
190static bool g_register_info_names_constified = false;
191
192const lldb_private::RegisterInfo *
193ABISysV_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
212bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) {
213  name = "rax";
214  return true;
215}
216
217size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; }
218
219// Static Functions
220
221ABISP
222ABISysV_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  const llvm::Triple::EnvironmentType os_env =
226      arch.GetTriple().getEnvironment();
227  if (arch_type == llvm::Triple::x86_64) {
228    switch(os_type) {
229    case llvm::Triple::OSType::IOS:
230    case llvm::Triple::OSType::TvOS:
231    case llvm::Triple::OSType::WatchOS:
232      switch (os_env) {
233      case llvm::Triple::EnvironmentType::MacABI:
234      case llvm::Triple::EnvironmentType::Simulator:
235      case llvm::Triple::EnvironmentType::UnknownEnvironment:
236        // UnknownEnvironment is needed for older compilers that don't
237        // support the simulator environment.
238        return ABISP(new ABISysV_x86_64(std::move(process_sp),
239                                        MakeMCRegisterInfo(arch)));
240      default:
241        return ABISP();
242      }
243    case llvm::Triple::OSType::Darwin:
244    case llvm::Triple::OSType::FreeBSD:
245    case llvm::Triple::OSType::Linux:
246    case llvm::Triple::OSType::MacOSX:
247    case llvm::Triple::OSType::NetBSD:
248    case llvm::Triple::OSType::Solaris:
249    case llvm::Triple::OSType::UnknownOS:
250      return ABISP(
251          new ABISysV_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
252    default:
253      return ABISP();
254    }
255  }
256  return ABISP();
257}
258
259bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
260                                        addr_t func_addr, addr_t return_addr,
261                                        llvm::ArrayRef<addr_t> args) const {
262  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
263
264  if (log) {
265    StreamString s;
266    s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
267             ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
268             ", return_addr = 0x%" PRIx64,
269             thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
270             (uint64_t)return_addr);
271
272    for (size_t i = 0; i < args.size(); ++i)
273      s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
274               args[i]);
275    s.PutCString(")");
276    log->PutString(s.GetString());
277  }
278
279  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
280  if (!reg_ctx)
281    return false;
282
283  const RegisterInfo *reg_info = nullptr;
284
285  if (args.size() > 6) // TODO handle more than 6 arguments
286    return false;
287
288  for (size_t i = 0; i < args.size(); ++i) {
289    reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
290                                        LLDB_REGNUM_GENERIC_ARG1 + i);
291    LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
292              static_cast<uint64_t>(i + 1), args[i], reg_info->name);
293    if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
294      return false;
295  }
296
297  // First, align the SP
298
299  LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
300            (uint64_t)sp, (uint64_t)(sp & ~0xfull));
301
302  sp &= ~(0xfull); // 16-byte alignment
303
304  sp -= 8;
305
306  Status error;
307  const RegisterInfo *pc_reg_info =
308      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
309  const RegisterInfo *sp_reg_info =
310      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
311  ProcessSP process_sp(thread.GetProcess());
312
313  RegisterValue reg_value;
314  LLDB_LOGF(log,
315            "Pushing the return address onto the stack: 0x%" PRIx64
316            ": 0x%" PRIx64,
317            (uint64_t)sp, (uint64_t)return_addr);
318
319  // Save return address onto the stack
320  if (!process_sp->WritePointerToMemory(sp, return_addr, error))
321    return false;
322
323  // %rsp is set to the actual stack value.
324
325  LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
326
327  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
328    return false;
329
330  // %rip is set to the address of the called function.
331
332  LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
333
334  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
335    return false;
336
337  return true;
338}
339
340static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
341                                bool is_signed, Thread &thread,
342                                uint32_t *argument_register_ids,
343                                unsigned int &current_argument_register,
344                                addr_t &current_stack_argument) {
345  if (bit_width > 64)
346    return false; // Scalar can't hold large integer arguments
347
348  if (current_argument_register < 6) {
349    scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
350        argument_register_ids[current_argument_register], 0);
351    current_argument_register++;
352    if (is_signed)
353      scalar.SignExtend(bit_width);
354  } else {
355    uint32_t byte_size = (bit_width + (8 - 1)) / 8;
356    Status error;
357    if (thread.GetProcess()->ReadScalarIntegerFromMemory(
358            current_stack_argument, byte_size, is_signed, scalar, error)) {
359      current_stack_argument += byte_size;
360      return true;
361    }
362    return false;
363  }
364  return true;
365}
366
367bool ABISysV_x86_64::GetArgumentValues(Thread &thread,
368                                       ValueList &values) const {
369  unsigned int num_values = values.GetSize();
370  unsigned int value_index;
371
372  // Extract the register context so we can read arguments from registers
373
374  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
375
376  if (!reg_ctx)
377    return false;
378
379  // Get the pointer to the first stack argument so we have a place to start
380  // when reading data
381
382  addr_t sp = reg_ctx->GetSP(0);
383
384  if (!sp)
385    return false;
386
387  addr_t current_stack_argument = sp + 8; // jump over return address
388
389  uint32_t argument_register_ids[6];
390
391  argument_register_ids[0] =
392      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
393          ->kinds[eRegisterKindLLDB];
394  argument_register_ids[1] =
395      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
396          ->kinds[eRegisterKindLLDB];
397  argument_register_ids[2] =
398      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
399          ->kinds[eRegisterKindLLDB];
400  argument_register_ids[3] =
401      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
402          ->kinds[eRegisterKindLLDB];
403  argument_register_ids[4] =
404      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
405          ->kinds[eRegisterKindLLDB];
406  argument_register_ids[5] =
407      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
408          ->kinds[eRegisterKindLLDB];
409
410  unsigned int current_argument_register = 0;
411
412  for (value_index = 0; value_index < num_values; ++value_index) {
413    Value *value = values.GetValueAtIndex(value_index);
414
415    if (!value)
416      return false;
417
418    // We currently only support extracting values with Clang QualTypes. Do we
419    // care about others?
420    CompilerType compiler_type = value->GetCompilerType();
421    llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
422    if (!bit_size)
423      return false;
424    bool is_signed;
425
426    if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
427      ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
428                          argument_register_ids, current_argument_register,
429                          current_stack_argument);
430    } else if (compiler_type.IsPointerType()) {
431      ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
432                          argument_register_ids, current_argument_register,
433                          current_stack_argument);
434    }
435  }
436
437  return true;
438}
439
440Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
441                                            lldb::ValueObjectSP &new_value_sp) {
442  Status error;
443  if (!new_value_sp) {
444    error.SetErrorString("Empty value object for return value.");
445    return error;
446  }
447
448  CompilerType compiler_type = new_value_sp->GetCompilerType();
449  if (!compiler_type) {
450    error.SetErrorString("Null clang type for return value.");
451    return error;
452  }
453
454  Thread *thread = frame_sp->GetThread().get();
455
456  bool is_signed;
457  uint32_t count;
458  bool is_complex;
459
460  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
461
462  bool set_it_simple = false;
463  if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
464      compiler_type.IsPointerType()) {
465    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
466
467    DataExtractor data;
468    Status data_error;
469    size_t num_bytes = new_value_sp->GetData(data, data_error);
470    if (data_error.Fail()) {
471      error.SetErrorStringWithFormat(
472          "Couldn't convert return value to raw data: %s",
473          data_error.AsCString());
474      return error;
475    }
476    lldb::offset_t offset = 0;
477    if (num_bytes <= 8) {
478      uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
479
480      if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
481        set_it_simple = true;
482    } else {
483      error.SetErrorString("We don't support returning longer than 64 bit "
484                           "integer values at present.");
485    }
486  } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
487    if (is_complex)
488      error.SetErrorString(
489          "We don't support returning complex values at present");
490    else {
491      llvm::Optional<uint64_t> bit_width =
492          compiler_type.GetBitSize(frame_sp.get());
493      if (!bit_width) {
494        error.SetErrorString("can't get type size");
495        return error;
496      }
497      if (*bit_width <= 64) {
498        const RegisterInfo *xmm0_info =
499            reg_ctx->GetRegisterInfoByName("xmm0", 0);
500        RegisterValue xmm0_value;
501        DataExtractor data;
502        Status data_error;
503        size_t num_bytes = new_value_sp->GetData(data, data_error);
504        if (data_error.Fail()) {
505          error.SetErrorStringWithFormat(
506              "Couldn't convert return value to raw data: %s",
507              data_error.AsCString());
508          return error;
509        }
510
511        unsigned char buffer[16];
512        ByteOrder byte_order = data.GetByteOrder();
513
514        data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
515        xmm0_value.SetBytes(buffer, 16, byte_order);
516        reg_ctx->WriteRegister(xmm0_info, xmm0_value);
517        set_it_simple = true;
518      } else {
519        // FIXME - don't know how to do 80 bit long doubles yet.
520        error.SetErrorString(
521            "We don't support returning float values > 64 bits at present");
522      }
523    }
524  }
525
526  if (!set_it_simple) {
527    // Okay we've got a structure or something that doesn't fit in a simple
528    // register. We should figure out where it really goes, but we don't
529    // support this yet.
530    error.SetErrorString("We only support setting simple integer and float "
531                         "return types at present.");
532  }
533
534  return error;
535}
536
537ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
538    Thread &thread, CompilerType &return_compiler_type) const {
539  ValueObjectSP return_valobj_sp;
540  Value value;
541
542  if (!return_compiler_type)
543    return return_valobj_sp;
544
545  // value.SetContext (Value::eContextTypeClangType, return_value_type);
546  value.SetCompilerType(return_compiler_type);
547
548  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
549  if (!reg_ctx)
550    return return_valobj_sp;
551
552  const uint32_t type_flags = return_compiler_type.GetTypeInfo();
553  if (type_flags & eTypeIsScalar) {
554    value.SetValueType(Value::eValueTypeScalar);
555
556    bool success = false;
557    if (type_flags & eTypeIsInteger) {
558      // Extract the register context so we can read arguments from registers
559
560      llvm::Optional<uint64_t> byte_size =
561          return_compiler_type.GetByteSize(nullptr);
562      if (!byte_size)
563        return return_valobj_sp;
564      uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
565          reg_ctx->GetRegisterInfoByName("rax", 0), 0);
566      const bool is_signed = (type_flags & eTypeIsSigned) != 0;
567      switch (*byte_size) {
568      default:
569        break;
570
571      case sizeof(uint64_t):
572        if (is_signed)
573          value.GetScalar() = (int64_t)(raw_value);
574        else
575          value.GetScalar() = (uint64_t)(raw_value);
576        success = true;
577        break;
578
579      case sizeof(uint32_t):
580        if (is_signed)
581          value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
582        else
583          value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
584        success = true;
585        break;
586
587      case sizeof(uint16_t):
588        if (is_signed)
589          value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
590        else
591          value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
592        success = true;
593        break;
594
595      case sizeof(uint8_t):
596        if (is_signed)
597          value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
598        else
599          value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
600        success = true;
601        break;
602      }
603    } else if (type_flags & eTypeIsFloat) {
604      if (type_flags & eTypeIsComplex) {
605        // Don't handle complex yet.
606      } else {
607        llvm::Optional<uint64_t> byte_size =
608            return_compiler_type.GetByteSize(nullptr);
609        if (byte_size && *byte_size <= sizeof(long double)) {
610          const RegisterInfo *xmm0_info =
611              reg_ctx->GetRegisterInfoByName("xmm0", 0);
612          RegisterValue xmm0_value;
613          if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
614            DataExtractor data;
615            if (xmm0_value.GetData(data)) {
616              lldb::offset_t offset = 0;
617              if (*byte_size == sizeof(float)) {
618                value.GetScalar() = (float)data.GetFloat(&offset);
619                success = true;
620              } else if (*byte_size == sizeof(double)) {
621                value.GetScalar() = (double)data.GetDouble(&offset);
622                success = true;
623              } else if (*byte_size == sizeof(long double)) {
624                // Don't handle long double since that can be encoded as 80 bit
625                // floats...
626              }
627            }
628          }
629        }
630      }
631    }
632
633    if (success)
634      return_valobj_sp = ValueObjectConstResult::Create(
635          thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
636  } else if (type_flags & eTypeIsPointer) {
637    unsigned rax_id =
638        reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
639    value.GetScalar() =
640        (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
641                                                                      0);
642    value.SetValueType(Value::eValueTypeScalar);
643    return_valobj_sp = ValueObjectConstResult::Create(
644        thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
645  } else if (type_flags & eTypeIsVector) {
646    llvm::Optional<uint64_t> byte_size =
647        return_compiler_type.GetByteSize(nullptr);
648    if (byte_size && *byte_size > 0) {
649      const RegisterInfo *altivec_reg =
650          reg_ctx->GetRegisterInfoByName("xmm0", 0);
651      if (altivec_reg == nullptr)
652        altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
653
654      if (altivec_reg) {
655        if (*byte_size <= altivec_reg->byte_size) {
656          ProcessSP process_sp(thread.GetProcess());
657          if (process_sp) {
658            std::unique_ptr<DataBufferHeap> heap_data_up(
659                new DataBufferHeap(*byte_size, 0));
660            const ByteOrder byte_order = process_sp->GetByteOrder();
661            RegisterValue reg_value;
662            if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
663              Status error;
664              if (reg_value.GetAsMemoryData(
665                      altivec_reg, heap_data_up->GetBytes(),
666                      heap_data_up->GetByteSize(), byte_order, error)) {
667                DataExtractor data(DataBufferSP(heap_data_up.release()),
668                                   byte_order,
669                                   process_sp->GetTarget()
670                                       .GetArchitecture()
671                                       .GetAddressByteSize());
672                return_valobj_sp = ValueObjectConstResult::Create(
673                    &thread, return_compiler_type, ConstString(""), data);
674              }
675            }
676          }
677        } else if (*byte_size <= altivec_reg->byte_size * 2) {
678          const RegisterInfo *altivec_reg2 =
679              reg_ctx->GetRegisterInfoByName("xmm1", 0);
680          if (altivec_reg2) {
681            ProcessSP process_sp(thread.GetProcess());
682            if (process_sp) {
683              std::unique_ptr<DataBufferHeap> heap_data_up(
684                  new DataBufferHeap(*byte_size, 0));
685              const ByteOrder byte_order = process_sp->GetByteOrder();
686              RegisterValue reg_value;
687              RegisterValue reg_value2;
688              if (reg_ctx->ReadRegister(altivec_reg, reg_value) &&
689                  reg_ctx->ReadRegister(altivec_reg2, reg_value2)) {
690
691                Status error;
692                if (reg_value.GetAsMemoryData(
693                        altivec_reg, heap_data_up->GetBytes(),
694                        altivec_reg->byte_size, byte_order, error) &&
695                    reg_value2.GetAsMemoryData(
696                        altivec_reg2,
697                        heap_data_up->GetBytes() + altivec_reg->byte_size,
698                        heap_data_up->GetByteSize() - altivec_reg->byte_size,
699                        byte_order, error)) {
700                  DataExtractor data(DataBufferSP(heap_data_up.release()),
701                                     byte_order,
702                                     process_sp->GetTarget()
703                                         .GetArchitecture()
704                                         .GetAddressByteSize());
705                  return_valobj_sp = ValueObjectConstResult::Create(
706                      &thread, return_compiler_type, ConstString(""), data);
707                }
708              }
709            }
710          }
711        }
712      }
713    }
714  }
715
716  return return_valobj_sp;
717}
718
719// The compiler will flatten the nested aggregate type into single
720// layer and push the value to stack
721// This helper function will flatten an aggregate type
722// and return true if it can be returned in register(s) by value
723// return false if the aggregate is in memory
724static bool FlattenAggregateType(
725    Thread &thread, ExecutionContext &exe_ctx,
726    CompilerType &return_compiler_type,
727    uint32_t data_byte_offset,
728    std::vector<uint32_t> &aggregate_field_offsets,
729    std::vector<CompilerType> &aggregate_compiler_types) {
730
731  const uint32_t num_children = return_compiler_type.GetNumFields();
732  for (uint32_t idx = 0; idx < num_children; ++idx) {
733    std::string name;
734    bool is_signed;
735    uint32_t count;
736    bool is_complex;
737
738    uint64_t field_bit_offset = 0;
739    CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
740        idx, name, &field_bit_offset, nullptr, nullptr);
741    llvm::Optional<uint64_t> field_bit_width =
742          field_compiler_type.GetBitSize(&thread);
743
744    // if we don't know the size of the field (e.g. invalid type), exit
745    if (!field_bit_width || *field_bit_width == 0) {
746      return false;
747    }
748
749    uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
750
751    const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
752    if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
753        field_compiler_type.IsPointerType() ||
754        field_compiler_type.IsFloatingPointType(count, is_complex)) {
755      aggregate_field_offsets.push_back(field_byte_offset);
756      aggregate_compiler_types.push_back(field_compiler_type);
757    } else if (field_type_flags & eTypeHasChildren) {
758      if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
759                                field_byte_offset, aggregate_field_offsets,
760                                aggregate_compiler_types)) {
761        return false;
762      }
763    }
764  }
765  return true;
766}
767
768ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
769    Thread &thread, CompilerType &return_compiler_type) const {
770  ValueObjectSP return_valobj_sp;
771
772  if (!return_compiler_type)
773    return return_valobj_sp;
774
775  ExecutionContext exe_ctx(thread.shared_from_this());
776  return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
777  if (return_valobj_sp)
778    return return_valobj_sp;
779
780  RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
781  if (!reg_ctx_sp)
782    return return_valobj_sp;
783
784  llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
785  if (!bit_width)
786    return return_valobj_sp;
787  if (return_compiler_type.IsAggregateType()) {
788    Target *target = exe_ctx.GetTargetPtr();
789    bool is_memory = true;
790    std::vector<uint32_t> aggregate_field_offsets;
791    std::vector<CompilerType> aggregate_compiler_types;
792    if (return_compiler_type.GetTypeSystem()->CanPassInRegisters(
793          return_compiler_type) &&
794      *bit_width <= 128 &&
795      FlattenAggregateType(thread, exe_ctx, return_compiler_type,
796                          0, aggregate_field_offsets,
797                          aggregate_compiler_types)) {
798      ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
799      DataBufferSP data_sp(new DataBufferHeap(16, 0));
800      DataExtractor return_ext(data_sp, byte_order,
801                               target->GetArchitecture().GetAddressByteSize());
802
803      const RegisterInfo *rax_info =
804          reg_ctx_sp->GetRegisterInfoByName("rax", 0);
805      const RegisterInfo *rdx_info =
806          reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
807      const RegisterInfo *xmm0_info =
808          reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
809      const RegisterInfo *xmm1_info =
810          reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
811
812      RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
813      reg_ctx_sp->ReadRegister(rax_info, rax_value);
814      reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
815      reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value);
816      reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value);
817
818      DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
819
820      rax_value.GetData(rax_data);
821      rdx_value.GetData(rdx_data);
822      xmm0_value.GetData(xmm0_data);
823      xmm1_value.GetData(xmm1_data);
824
825      uint32_t fp_bytes =
826          0; // Tracks how much of the xmm registers we've consumed so far
827      uint32_t integer_bytes =
828          0; // Tracks how much of the rax/rds registers we've consumed so far
829
830      // in case of the returned type is a subclass of non-abstract-base class
831      // it will have a padding to skip the base content
832      if (aggregate_field_offsets.size()) {
833        fp_bytes = aggregate_field_offsets[0];
834        integer_bytes = aggregate_field_offsets[0];
835      }
836
837      const uint32_t num_children = aggregate_compiler_types.size();
838
839      // Since we are in the small struct regime, assume we are not in memory.
840      is_memory = false;
841      for (uint32_t idx = 0; idx < num_children; idx++) {
842        bool is_signed;
843        uint32_t count;
844        bool is_complex;
845
846        CompilerType field_compiler_type = aggregate_compiler_types[idx];
847        uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread));
848        uint32_t field_byte_offset = aggregate_field_offsets[idx];
849
850        uint32_t field_bit_width = field_byte_width * 8;
851
852        DataExtractor *copy_from_extractor = nullptr;
853        uint32_t copy_from_offset = 0;
854
855        if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
856            field_compiler_type.IsPointerType()) {
857          if (integer_bytes < 8) {
858            if (integer_bytes + field_byte_width <= 8) {
859              // This is in RAX, copy from register to our result structure:
860              copy_from_extractor = &rax_data;
861              copy_from_offset = integer_bytes;
862              integer_bytes += field_byte_width;
863            } else {
864              // The next field wouldn't fit in the remaining space, so we
865              // pushed it to rdx.
866              copy_from_extractor = &rdx_data;
867              copy_from_offset = 0;
868              integer_bytes = 8 + field_byte_width;
869            }
870          } else if (integer_bytes + field_byte_width <= 16) {
871            copy_from_extractor = &rdx_data;
872            copy_from_offset = integer_bytes - 8;
873            integer_bytes += field_byte_width;
874          } else {
875            // The last field didn't fit.  I can't see how that would happen
876            // w/o the overall size being greater than 16 bytes.  For now,
877            // return a nullptr return value object.
878            return return_valobj_sp;
879          }
880        } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
881          // Structs with long doubles are always passed in memory.
882          if (field_bit_width == 128) {
883            is_memory = true;
884            break;
885          } else if (field_bit_width == 64) {
886            // These have to be in a single xmm register.
887            if (fp_bytes == 0)
888              copy_from_extractor = &xmm0_data;
889            else
890              copy_from_extractor = &xmm1_data;
891
892            copy_from_offset = 0;
893            fp_bytes += field_byte_width;
894          } else if (field_bit_width == 32) {
895            // This one is kind of complicated.  If we are in an "eightbyte"
896            // with another float, we'll be stuffed into an xmm register with
897            // it.  If we are in an "eightbyte" with one or more ints, then we
898            // will be stuffed into the appropriate GPR with them.
899            bool in_gpr;
900            if (field_byte_offset % 8 == 0) {
901              // We are at the beginning of one of the eightbytes, so check the
902              // next element (if any)
903              if (idx == num_children - 1) {
904                in_gpr = false;
905              } else {
906                CompilerType next_field_compiler_type =
907                    aggregate_compiler_types[idx + 1];
908                if (next_field_compiler_type.IsIntegerOrEnumerationType(
909                        is_signed)) {
910                  in_gpr = true;
911                } else {
912                  copy_from_offset = 0;
913                  in_gpr = false;
914                }
915              }
916            } else if (field_byte_offset % 4 == 0) {
917              // We are inside of an eightbyte, so see if the field before us
918              // is floating point: This could happen if somebody put padding
919              // in the structure.
920              if (idx == 0) {
921                in_gpr = false;
922              } else {
923                CompilerType prev_field_compiler_type =
924                    aggregate_compiler_types[idx - 1];
925                if (prev_field_compiler_type.IsIntegerOrEnumerationType(
926                        is_signed)) {
927                  in_gpr = true;
928                } else {
929                  copy_from_offset = 4;
930                  in_gpr = false;
931                }
932              }
933            } else {
934              is_memory = true;
935              continue;
936            }
937
938            // Okay, we've figured out whether we are in GPR or XMM, now figure
939            // out which one.
940            if (in_gpr) {
941              if (integer_bytes < 8) {
942                // This is in RAX, copy from register to our result structure:
943                copy_from_extractor = &rax_data;
944                copy_from_offset = integer_bytes;
945                integer_bytes += field_byte_width;
946              } else {
947                copy_from_extractor = &rdx_data;
948                copy_from_offset = integer_bytes - 8;
949                integer_bytes += field_byte_width;
950              }
951            } else {
952              if (fp_bytes < 8)
953                copy_from_extractor = &xmm0_data;
954              else
955                copy_from_extractor = &xmm1_data;
956
957              fp_bytes += field_byte_width;
958            }
959          }
960        }
961        // These two tests are just sanity checks.  If I somehow get the type
962        // calculation wrong above it is better to just return nothing than to
963        // assert or crash.
964        if (!copy_from_extractor)
965          return return_valobj_sp;
966        if (copy_from_offset + field_byte_width >
967            copy_from_extractor->GetByteSize())
968          return return_valobj_sp;
969        copy_from_extractor->CopyByteOrderedData(
970            copy_from_offset, field_byte_width,
971            data_sp->GetBytes() + field_byte_offset, field_byte_width,
972            byte_order);
973      }
974      if (!is_memory) {
975        // The result is in our data buffer.  Let's make a variable object out
976        // of it:
977        return_valobj_sp = ValueObjectConstResult::Create(
978            &thread, return_compiler_type, ConstString(""), return_ext);
979      }
980    }
981
982    // FIXME: This is just taking a guess, rax may very well no longer hold the
983    // return storage location.
984    // If we are going to do this right, when we make a new frame we should
985    // check to see if it uses a memory return, and if we are at the first
986    // instruction and if so stash away the return location.  Then we would
987    // only return the memory return value if we know it is valid.
988
989    if (is_memory) {
990      unsigned rax_id =
991          reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
992      lldb::addr_t storage_addr =
993          (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
994                                                                        0);
995      return_valobj_sp = ValueObjectMemory::Create(
996          &thread, "", Address(storage_addr, nullptr), return_compiler_type);
997    }
998  }
999
1000  return return_valobj_sp;
1001}
1002
1003// This defines the CFA as rsp+8
1004// the saved pc is at CFA-8 (i.e. rsp+0)
1005// The saved rsp is CFA+0
1006
1007bool ABISysV_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1008  unwind_plan.Clear();
1009  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1010
1011  uint32_t sp_reg_num = dwarf_rsp;
1012  uint32_t pc_reg_num = dwarf_rip;
1013
1014  UnwindPlan::RowSP row(new UnwindPlan::Row);
1015  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
1016  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
1017  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1018  unwind_plan.AppendRow(row);
1019  unwind_plan.SetSourceName("x86_64 at-func-entry default");
1020  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1021  return true;
1022}
1023
1024// This defines the CFA as rbp+16
1025// The saved pc is at CFA-8 (i.e. rbp+8)
1026// The saved rbp is at CFA-16 (i.e. rbp+0)
1027// The saved rsp is CFA+0
1028
1029bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1030  unwind_plan.Clear();
1031  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1032
1033  uint32_t fp_reg_num = dwarf_rbp;
1034  uint32_t sp_reg_num = dwarf_rsp;
1035  uint32_t pc_reg_num = dwarf_rip;
1036
1037  UnwindPlan::RowSP row(new UnwindPlan::Row);
1038
1039  const int32_t ptr_size = 8;
1040  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
1041  row->SetOffset(0);
1042
1043  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1044  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1045  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1046
1047  unwind_plan.AppendRow(row);
1048  unwind_plan.SetSourceName("x86_64 default unwind plan");
1049  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1050  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1051  unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1052  return true;
1053}
1054
1055bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1056  return !RegisterIsCalleeSaved(reg_info);
1057}
1058
1059// See "Register Usage" in the
1060// "System V Application Binary Interface"
1061// "AMD64 Architecture Processor Supplement" (or "x86-64(tm) Architecture
1062// Processor Supplement" in earlier revisions) (this doc is also commonly
1063// referred to as the x86-64/AMD64 psABI) Edited by Michael Matz, Jan Hubicka,
1064// Andreas Jaeger, and Mark Mitchell current version is 0.99.6 released
1065// 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
1066// It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
1067
1068bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1069  if (!reg_info)
1070    return false;
1071  assert(reg_info->name != nullptr && "unnamed register?");
1072  std::string Name = std::string(reg_info->name);
1073  bool IsCalleeSaved =
1074      llvm::StringSwitch<bool>(Name)
1075          .Cases("r12", "r13", "r14", "r15", "rbp", "ebp", "rbx", "ebx", true)
1076          .Cases("rip", "eip", "rsp", "esp", "sp", "fp", "pc", true)
1077          .Default(false);
1078  return IsCalleeSaved;
1079}
1080
1081void ABISysV_x86_64::Initialize() {
1082  PluginManager::RegisterPlugin(
1083      GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance);
1084}
1085
1086void ABISysV_x86_64::Terminate() {
1087  PluginManager::UnregisterPlugin(CreateInstance);
1088}
1089
1090lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() {
1091  static ConstString g_name("sysv-x86_64");
1092  return g_name;
1093}
1094
1095// PluginInterface protocol
1096
1097lldb_private::ConstString ABISysV_x86_64::GetPluginName() {
1098  return GetPluginNameStatic();
1099}
1100
1101uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; }
1102