ABISysV_x86_64.cpp revision 263363
1//===-- ABISysV_x86_64.cpp --------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ABISysV_x86_64.h"
11
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/DataExtractor.h"
14#include "lldb/Core/Error.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/Module.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/RegisterValue.h"
19#include "lldb/Core/Value.h"
20#include "lldb/Core/ValueObjectConstResult.h"
21#include "lldb/Core/ValueObjectRegister.h"
22#include "lldb/Core/ValueObjectMemory.h"
23#include "lldb/Symbol/ClangASTContext.h"
24#include "lldb/Symbol/UnwindPlan.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Target/Process.h"
27#include "lldb/Target/RegisterContext.h"
28#include "lldb/Target/StackFrame.h"
29#include "lldb/Target/Thread.h"
30
31#include "llvm/ADT/Triple.h"
32
33using namespace lldb;
34using namespace lldb_private;
35
36enum gcc_dwarf_regnums
37{
38    gcc_dwarf_rax = 0,
39    gcc_dwarf_rdx,
40    gcc_dwarf_rcx,
41    gcc_dwarf_rbx,
42    gcc_dwarf_rsi,
43    gcc_dwarf_rdi,
44    gcc_dwarf_rbp,
45    gcc_dwarf_rsp,
46    gcc_dwarf_r8,
47    gcc_dwarf_r9,
48    gcc_dwarf_r10,
49    gcc_dwarf_r11,
50    gcc_dwarf_r12,
51    gcc_dwarf_r13,
52    gcc_dwarf_r14,
53    gcc_dwarf_r15,
54    gcc_dwarf_rip,
55    gcc_dwarf_xmm0,
56    gcc_dwarf_xmm1,
57    gcc_dwarf_xmm2,
58    gcc_dwarf_xmm3,
59    gcc_dwarf_xmm4,
60    gcc_dwarf_xmm5,
61    gcc_dwarf_xmm6,
62    gcc_dwarf_xmm7,
63    gcc_dwarf_xmm8,
64    gcc_dwarf_xmm9,
65    gcc_dwarf_xmm10,
66    gcc_dwarf_xmm11,
67    gcc_dwarf_xmm12,
68    gcc_dwarf_xmm13,
69    gcc_dwarf_xmm14,
70    gcc_dwarf_xmm15,
71    gcc_dwarf_stmm0,
72    gcc_dwarf_stmm1,
73    gcc_dwarf_stmm2,
74    gcc_dwarf_stmm3,
75    gcc_dwarf_stmm4,
76    gcc_dwarf_stmm5,
77    gcc_dwarf_stmm6,
78    gcc_dwarf_stmm7,
79    gcc_dwarf_ymm0,
80    gcc_dwarf_ymm1,
81    gcc_dwarf_ymm2,
82    gcc_dwarf_ymm3,
83    gcc_dwarf_ymm4,
84    gcc_dwarf_ymm5,
85    gcc_dwarf_ymm6,
86    gcc_dwarf_ymm7,
87    gcc_dwarf_ymm8,
88    gcc_dwarf_ymm9,
89    gcc_dwarf_ymm10,
90    gcc_dwarf_ymm11,
91    gcc_dwarf_ymm12,
92    gcc_dwarf_ymm13,
93    gcc_dwarf_ymm14,
94    gcc_dwarf_ymm15
95};
96
97enum gdb_regnums
98{
99    gdb_rax     =   0,
100    gdb_rbx     =   1,
101    gdb_rcx     =   2,
102    gdb_rdx     =   3,
103    gdb_rsi     =   4,
104    gdb_rdi     =   5,
105    gdb_rbp     =   6,
106    gdb_rsp     =   7,
107    gdb_r8      =   8,
108    gdb_r9      =   9,
109    gdb_r10     =  10,
110    gdb_r11     =  11,
111    gdb_r12     =  12,
112    gdb_r13     =  13,
113    gdb_r14     =  14,
114    gdb_r15     =  15,
115    gdb_rip     =  16,
116    gdb_rflags  =  17,
117    gdb_cs      =  18,
118    gdb_ss      =  19,
119    gdb_ds      =  20,
120    gdb_es      =  21,
121    gdb_fs      =  22,
122    gdb_gs      =  23,
123    gdb_stmm0   =  24,
124    gdb_stmm1   =  25,
125    gdb_stmm2   =  26,
126    gdb_stmm3   =  27,
127    gdb_stmm4   =  28,
128    gdb_stmm5   =  29,
129    gdb_stmm6   =  30,
130    gdb_stmm7   =  31,
131    gdb_fctrl   =  32,  gdb_fcw = gdb_fctrl,
132    gdb_fstat   =  33,  gdb_fsw = gdb_fstat,
133    gdb_ftag    =  34,  gdb_ftw = gdb_ftag,
134    gdb_fiseg   =  35,  gdb_fpu_cs  = gdb_fiseg,
135    gdb_fioff   =  36,  gdb_ip  = gdb_fioff,
136    gdb_foseg   =  37,  gdb_fpu_ds  = gdb_foseg,
137    gdb_fooff   =  38,  gdb_dp  = gdb_fooff,
138    gdb_fop     =  39,
139    gdb_xmm0    =  40,
140    gdb_xmm1    =  41,
141    gdb_xmm2    =  42,
142    gdb_xmm3    =  43,
143    gdb_xmm4    =  44,
144    gdb_xmm5    =  45,
145    gdb_xmm6    =  46,
146    gdb_xmm7    =  47,
147    gdb_xmm8    =  48,
148    gdb_xmm9    =  49,
149    gdb_xmm10   =  50,
150    gdb_xmm11   =  51,
151    gdb_xmm12   =  52,
152    gdb_xmm13   =  53,
153    gdb_xmm14   =  54,
154    gdb_xmm15   =  55,
155    gdb_mxcsr   =  56,
156    gdb_ymm0    =  57,
157    gdb_ymm1    =  58,
158    gdb_ymm2    =  59,
159    gdb_ymm3    =  60,
160    gdb_ymm4    =  61,
161    gdb_ymm5    =  62,
162    gdb_ymm6    =  63,
163    gdb_ymm7    =  64,
164    gdb_ymm8    =  65,
165    gdb_ymm9    =  66,
166    gdb_ymm10   =  67,
167    gdb_ymm11   =  68,
168    gdb_ymm12   =  69,
169    gdb_ymm13   =  70,
170    gdb_ymm14   =  71,
171    gdb_ymm15   =  72
172};
173
174
175static RegisterInfo g_register_infos[] =
176{
177  //  NAME      ALT      SZ OFF ENCODING         FORMAT              COMPILER                DWARF                 GENERIC                     GDB                   LLDB NATIVE            VALUE REGS    INVALIDATE REGS
178  //  ========  =======  == === =============    =================== ======================= ===================== =========================== ===================== ====================== ==========    ===============
179    { "rax"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rax       , gcc_dwarf_rax       , LLDB_INVALID_REGNUM       , gdb_rax            , LLDB_INVALID_REGNUM },      NULL,              NULL},
180    { "rbx"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rbx       , gcc_dwarf_rbx       , LLDB_INVALID_REGNUM       , gdb_rbx            , LLDB_INVALID_REGNUM },      NULL,              NULL},
181    { "rcx"   , "arg4",  8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rcx       , gcc_dwarf_rcx       , LLDB_REGNUM_GENERIC_ARG4  , gdb_rcx            , LLDB_INVALID_REGNUM },      NULL,              NULL},
182    { "rdx"   , "arg3",  8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rdx       , gcc_dwarf_rdx       , LLDB_REGNUM_GENERIC_ARG3  , gdb_rdx            , LLDB_INVALID_REGNUM },      NULL,              NULL},
183    { "rsi"   , "arg2",  8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rsi       , gcc_dwarf_rsi       , LLDB_REGNUM_GENERIC_ARG2  , gdb_rsi            , LLDB_INVALID_REGNUM },      NULL,              NULL},
184    { "rdi"   , "arg1",  8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rdi       , gcc_dwarf_rdi       , LLDB_REGNUM_GENERIC_ARG1  , gdb_rdi            , LLDB_INVALID_REGNUM },      NULL,              NULL},
185    { "rbp"   , "fp",    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rbp       , gcc_dwarf_rbp       , LLDB_REGNUM_GENERIC_FP    , gdb_rbp            , LLDB_INVALID_REGNUM },      NULL,              NULL},
186    { "rsp"   , "sp",    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rsp       , gcc_dwarf_rsp       , LLDB_REGNUM_GENERIC_SP    , gdb_rsp            , LLDB_INVALID_REGNUM },      NULL,              NULL},
187    { "r8"    , "arg5",  8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r8        , gcc_dwarf_r8        , LLDB_REGNUM_GENERIC_ARG5  , gdb_r8             , LLDB_INVALID_REGNUM },      NULL,              NULL},
188    { "r9"    , "arg6",  8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r9        , gcc_dwarf_r9        , LLDB_REGNUM_GENERIC_ARG6  , gdb_r9             , LLDB_INVALID_REGNUM },      NULL,              NULL},
189    { "r10"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r10       , gcc_dwarf_r10       , LLDB_INVALID_REGNUM       , gdb_r10            , LLDB_INVALID_REGNUM },      NULL,              NULL},
190    { "r11"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r11       , gcc_dwarf_r11       , LLDB_INVALID_REGNUM       , gdb_r11            , LLDB_INVALID_REGNUM },      NULL,              NULL},
191    { "r12"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r12       , gcc_dwarf_r12       , LLDB_INVALID_REGNUM       , gdb_r12            , LLDB_INVALID_REGNUM },      NULL,              NULL},
192    { "r13"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r13       , gcc_dwarf_r13       , LLDB_INVALID_REGNUM       , gdb_r13            , LLDB_INVALID_REGNUM },      NULL,              NULL},
193    { "r14"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r14       , gcc_dwarf_r14       , LLDB_INVALID_REGNUM       , gdb_r14            , LLDB_INVALID_REGNUM },      NULL,              NULL},
194    { "r15"   , NULL,    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_r15       , gcc_dwarf_r15       , LLDB_INVALID_REGNUM       , gdb_r15            , LLDB_INVALID_REGNUM },      NULL,              NULL},
195    { "rip"   , "pc",    8,  0, eEncodingUint  , eFormatHex          , { gcc_dwarf_rip       , gcc_dwarf_rip       , LLDB_REGNUM_GENERIC_PC    , gdb_rip            , LLDB_INVALID_REGNUM },      NULL,              NULL},
196    { "rflags", NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_REGNUM_GENERIC_FLAGS , gdb_rflags         , LLDB_INVALID_REGNUM },      NULL,              NULL},
197    { "cs"    , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_cs             , LLDB_INVALID_REGNUM },      NULL,              NULL},
198    { "ss"    , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_ss             , LLDB_INVALID_REGNUM },      NULL,              NULL},
199    { "ds"    , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_ds             , LLDB_INVALID_REGNUM },      NULL,              NULL},
200    { "es"    , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_es             , LLDB_INVALID_REGNUM },      NULL,              NULL},
201    { "fs"    , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_fs             , LLDB_INVALID_REGNUM },      NULL,              NULL},
202    { "gs"    , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_gs             , LLDB_INVALID_REGNUM },      NULL,              NULL},
203    { "stmm0" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm0     , gcc_dwarf_stmm0     , LLDB_INVALID_REGNUM       , gdb_stmm0          , LLDB_INVALID_REGNUM },      NULL,              NULL},
204    { "stmm1" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm1     , gcc_dwarf_stmm1     , LLDB_INVALID_REGNUM       , gdb_stmm1          , LLDB_INVALID_REGNUM },      NULL,              NULL},
205    { "stmm2" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm2     , gcc_dwarf_stmm2     , LLDB_INVALID_REGNUM       , gdb_stmm2          , LLDB_INVALID_REGNUM },      NULL,              NULL},
206    { "stmm3" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm3     , gcc_dwarf_stmm3     , LLDB_INVALID_REGNUM       , gdb_stmm3          , LLDB_INVALID_REGNUM },      NULL,              NULL},
207    { "stmm4" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm4     , gcc_dwarf_stmm4     , LLDB_INVALID_REGNUM       , gdb_stmm4          , LLDB_INVALID_REGNUM },      NULL,              NULL},
208    { "stmm5" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm5     , gcc_dwarf_stmm5     , LLDB_INVALID_REGNUM       , gdb_stmm5          , LLDB_INVALID_REGNUM },      NULL,              NULL},
209    { "stmm6" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm6     , gcc_dwarf_stmm6     , LLDB_INVALID_REGNUM       , gdb_stmm6          , LLDB_INVALID_REGNUM },      NULL,              NULL},
210    { "stmm7" , NULL,   10,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_stmm7     , gcc_dwarf_stmm7     , LLDB_INVALID_REGNUM       , gdb_stmm7          , LLDB_INVALID_REGNUM },      NULL,              NULL},
211    { "fctrl" , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_fctrl          , LLDB_INVALID_REGNUM },      NULL,              NULL},
212    { "fstat" , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_fstat          , LLDB_INVALID_REGNUM },      NULL,              NULL},
213    { "ftag"  , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_ftag           , LLDB_INVALID_REGNUM },      NULL,              NULL},
214    { "fiseg" , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_fiseg          , LLDB_INVALID_REGNUM },      NULL,              NULL},
215    { "fioff" , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_fioff          , LLDB_INVALID_REGNUM },      NULL,              NULL},
216    { "foseg" , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_foseg          , LLDB_INVALID_REGNUM },      NULL,              NULL},
217    { "fooff" , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_fooff          , LLDB_INVALID_REGNUM },      NULL,              NULL},
218    { "fop"   , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_fop            , LLDB_INVALID_REGNUM },      NULL,              NULL},
219    { "xmm0"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm0      , gcc_dwarf_xmm0      , LLDB_INVALID_REGNUM       , gdb_xmm0           , LLDB_INVALID_REGNUM },      NULL,              NULL},
220    { "xmm1"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm1      , gcc_dwarf_xmm1      , LLDB_INVALID_REGNUM       , gdb_xmm1           , LLDB_INVALID_REGNUM },      NULL,              NULL},
221    { "xmm2"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm2      , gcc_dwarf_xmm2      , LLDB_INVALID_REGNUM       , gdb_xmm2           , LLDB_INVALID_REGNUM },      NULL,              NULL},
222    { "xmm3"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm3      , gcc_dwarf_xmm3      , LLDB_INVALID_REGNUM       , gdb_xmm3           , LLDB_INVALID_REGNUM },      NULL,              NULL},
223    { "xmm4"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm4      , gcc_dwarf_xmm4      , LLDB_INVALID_REGNUM       , gdb_xmm4           , LLDB_INVALID_REGNUM },      NULL,              NULL},
224    { "xmm5"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm5      , gcc_dwarf_xmm5      , LLDB_INVALID_REGNUM       , gdb_xmm5           , LLDB_INVALID_REGNUM },      NULL,              NULL},
225    { "xmm6"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm6      , gcc_dwarf_xmm6      , LLDB_INVALID_REGNUM       , gdb_xmm6           , LLDB_INVALID_REGNUM },      NULL,              NULL},
226    { "xmm7"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm7      , gcc_dwarf_xmm7      , LLDB_INVALID_REGNUM       , gdb_xmm7           , LLDB_INVALID_REGNUM },      NULL,              NULL},
227    { "xmm8"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm8      , gcc_dwarf_xmm8      , LLDB_INVALID_REGNUM       , gdb_xmm8           , LLDB_INVALID_REGNUM },      NULL,              NULL},
228    { "xmm9"  , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm9      , gcc_dwarf_xmm9      , LLDB_INVALID_REGNUM       , gdb_xmm9           , LLDB_INVALID_REGNUM },      NULL,              NULL},
229    { "xmm10" , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm10     , gcc_dwarf_xmm10     , LLDB_INVALID_REGNUM       , gdb_xmm10          , LLDB_INVALID_REGNUM },      NULL,              NULL},
230    { "xmm11" , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm11     , gcc_dwarf_xmm11     , LLDB_INVALID_REGNUM       , gdb_xmm11          , LLDB_INVALID_REGNUM },      NULL,              NULL},
231    { "xmm12" , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm12     , gcc_dwarf_xmm12     , LLDB_INVALID_REGNUM       , gdb_xmm12          , LLDB_INVALID_REGNUM },      NULL,              NULL},
232    { "xmm13" , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm13     , gcc_dwarf_xmm13     , LLDB_INVALID_REGNUM       , gdb_xmm13          , LLDB_INVALID_REGNUM },      NULL,              NULL},
233    { "xmm14" , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm14     , gcc_dwarf_xmm14     , LLDB_INVALID_REGNUM       , gdb_xmm14          , LLDB_INVALID_REGNUM },      NULL,              NULL},
234    { "xmm15" , NULL,   16,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_xmm15     , gcc_dwarf_xmm15     , LLDB_INVALID_REGNUM       , gdb_xmm15          , LLDB_INVALID_REGNUM },      NULL,              NULL},
235    { "mxcsr" , NULL,    4,  0, eEncodingUint  , eFormatHex          , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM       , gdb_mxcsr          , LLDB_INVALID_REGNUM },      NULL,              NULL},
236    { "ymm0"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm0      , gcc_dwarf_ymm0      , LLDB_INVALID_REGNUM       , gdb_ymm0           , LLDB_INVALID_REGNUM },      NULL,              NULL},
237    { "ymm1"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm1      , gcc_dwarf_ymm1      , LLDB_INVALID_REGNUM       , gdb_ymm1           , LLDB_INVALID_REGNUM },      NULL,              NULL},
238    { "ymm2"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm2      , gcc_dwarf_ymm2      , LLDB_INVALID_REGNUM       , gdb_ymm2           , LLDB_INVALID_REGNUM },      NULL,              NULL},
239    { "ymm3"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm3      , gcc_dwarf_ymm3      , LLDB_INVALID_REGNUM       , gdb_ymm3           , LLDB_INVALID_REGNUM },      NULL,              NULL},
240    { "ymm4"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm4      , gcc_dwarf_ymm4      , LLDB_INVALID_REGNUM       , gdb_ymm4           , LLDB_INVALID_REGNUM },      NULL,              NULL},
241    { "ymm5"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm5      , gcc_dwarf_ymm5      , LLDB_INVALID_REGNUM       , gdb_ymm5           , LLDB_INVALID_REGNUM },      NULL,              NULL},
242    { "ymm6"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm6      , gcc_dwarf_ymm6      , LLDB_INVALID_REGNUM       , gdb_ymm6           , LLDB_INVALID_REGNUM },      NULL,              NULL},
243    { "ymm7"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm7      , gcc_dwarf_ymm7      , LLDB_INVALID_REGNUM       , gdb_ymm7           , LLDB_INVALID_REGNUM },      NULL,              NULL},
244    { "ymm8"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm8      , gcc_dwarf_ymm8      , LLDB_INVALID_REGNUM       , gdb_ymm8           , LLDB_INVALID_REGNUM },      NULL,              NULL},
245    { "ymm9"  , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm9      , gcc_dwarf_ymm9      , LLDB_INVALID_REGNUM       , gdb_ymm9           , LLDB_INVALID_REGNUM },      NULL,              NULL},
246    { "ymm10" , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm10     , gcc_dwarf_ymm10     , LLDB_INVALID_REGNUM       , gdb_ymm10          , LLDB_INVALID_REGNUM },      NULL,              NULL},
247    { "ymm11" , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm11     , gcc_dwarf_ymm11     , LLDB_INVALID_REGNUM       , gdb_ymm11          , LLDB_INVALID_REGNUM },      NULL,              NULL},
248    { "ymm12" , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm12     , gcc_dwarf_ymm12     , LLDB_INVALID_REGNUM       , gdb_ymm12          , LLDB_INVALID_REGNUM },      NULL,              NULL},
249    { "ymm13" , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm13     , gcc_dwarf_ymm13     , LLDB_INVALID_REGNUM       , gdb_ymm13          , LLDB_INVALID_REGNUM },      NULL,              NULL},
250    { "ymm14" , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm14     , gcc_dwarf_ymm14     , LLDB_INVALID_REGNUM       , gdb_ymm14          , LLDB_INVALID_REGNUM },      NULL,              NULL},
251    { "ymm15" , NULL,   32,  0, eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_ymm15     , gcc_dwarf_ymm15     , LLDB_INVALID_REGNUM       , gdb_ymm15          , LLDB_INVALID_REGNUM },      NULL,              NULL}
252};
253
254static const uint32_t k_num_register_infos = sizeof(g_register_infos)/sizeof(RegisterInfo);
255static bool g_register_info_names_constified = false;
256
257const lldb_private::RegisterInfo *
258ABISysV_x86_64::GetRegisterInfoArray (uint32_t &count)
259{
260    // Make the C-string names and alt_names for the register infos into const
261    // C-string values by having the ConstString unique the names in the global
262    // constant C-string pool.
263    if (!g_register_info_names_constified)
264    {
265        g_register_info_names_constified = true;
266        for (uint32_t i=0; i<k_num_register_infos; ++i)
267        {
268            if (g_register_infos[i].name)
269                g_register_infos[i].name = ConstString(g_register_infos[i].name).GetCString();
270            if (g_register_infos[i].alt_name)
271                g_register_infos[i].alt_name = ConstString(g_register_infos[i].alt_name).GetCString();
272        }
273    }
274    count = k_num_register_infos;
275    return g_register_infos;
276}
277
278
279size_t
280ABISysV_x86_64::GetRedZoneSize () const
281{
282    return 128;
283}
284
285//------------------------------------------------------------------
286// Static Functions
287//------------------------------------------------------------------
288ABISP
289ABISysV_x86_64::CreateInstance (const ArchSpec &arch)
290{
291    static ABISP g_abi_sp;
292    if (arch.GetTriple().getArch() == llvm::Triple::x86_64)
293    {
294        if (!g_abi_sp)
295            g_abi_sp.reset (new ABISysV_x86_64);
296        return g_abi_sp;
297    }
298    return ABISP();
299}
300
301bool
302ABISysV_x86_64::PrepareTrivialCall (Thread &thread,
303                                    addr_t sp,
304                                    addr_t func_addr,
305                                    addr_t return_addr,
306                                    addr_t *arg1_ptr,
307                                    addr_t *arg2_ptr,
308                                    addr_t *arg3_ptr,
309                                    addr_t *arg4_ptr,
310                                    addr_t *arg5_ptr,
311                                    addr_t *arg6_ptr) const
312{
313    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
314
315    if (log)
316    {
317        StreamString s;
318        s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
319                    thread.GetID(),
320                    (uint64_t)sp,
321                    (uint64_t)func_addr,
322                    (uint64_t)return_addr);
323
324        if (arg1_ptr)
325        {
326            s.Printf (", arg1 = 0x%" PRIx64, (uint64_t)*arg1_ptr);
327            if (arg2_ptr)
328            {
329                s.Printf (", arg2 = 0x%" PRIx64, (uint64_t)*arg2_ptr);
330                if (arg3_ptr)
331                {
332                    s.Printf (", arg3 = 0x%" PRIx64, (uint64_t)*arg3_ptr);
333                    if (arg4_ptr)
334                    {
335                        s.Printf (", arg4 = 0x%" PRIx64, (uint64_t)*arg4_ptr);
336                        if (arg5_ptr)
337                        {
338                            s.Printf (", arg5 = 0x%" PRIx64, (uint64_t)*arg5_ptr);
339                            if (arg6_ptr)
340                                s.Printf (", arg6 = 0x%" PRIx64, (uint64_t)*arg6_ptr);
341                        }
342                    }
343                }
344            }
345        }
346        s.PutCString (")");
347        log->PutCString(s.GetString().c_str());
348    }
349
350    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
351    if (!reg_ctx)
352        return false;
353
354    const RegisterInfo *reg_info = NULL;
355    if (arg1_ptr)
356    {
357        reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
358        if (log)
359            log->Printf("About to write arg1 (0x%" PRIx64 ") into %s", (uint64_t)*arg1_ptr, reg_info->name);
360
361        if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg1_ptr))
362            return false;
363
364        if (arg2_ptr)
365        {
366            reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
367            if (log)
368                log->Printf("About to write arg2 (0x%" PRIx64 ") into %s", (uint64_t)*arg2_ptr, reg_info->name);
369            if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg2_ptr))
370                return false;
371
372            if (arg3_ptr)
373            {
374                reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3);
375                if (log)
376                    log->Printf("About to write arg3 (0x%" PRIx64 ") into %s", (uint64_t)*arg3_ptr, reg_info->name);
377                if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg3_ptr))
378                    return false;
379
380                if (arg4_ptr)
381                {
382                    reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4);
383                    if (log)
384                        log->Printf("About to write arg4 (0x%" PRIx64 ") into %s", (uint64_t)*arg4_ptr, reg_info->name);
385                    if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg4_ptr))
386                        return false;
387
388                    if (arg5_ptr)
389                    {
390                        reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5);
391                        if (log)
392                            log->Printf("About to write arg5 (0x%" PRIx64 ") into %s", (uint64_t)*arg5_ptr, reg_info->name);
393                        if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg5_ptr))
394                            return false;
395
396                        if (arg6_ptr)
397                        {
398                            reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6);
399                            if (log)
400                                log->Printf("About to write arg6 (0x%" PRIx64 ") into %s", (uint64_t)*arg6_ptr, reg_info->name);
401                            if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg6_ptr))
402                                return false;
403                        }
404                    }
405                }
406            }
407        }
408    }
409
410
411    // First, align the SP
412
413    if (log)
414        log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
415
416    sp &= ~(0xfull); // 16-byte alignment
417
418    sp -= 8;
419
420    Error error;
421    const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
422    const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
423    ProcessSP process_sp (thread.GetProcess());
424
425    RegisterValue reg_value;
426
427#if 0
428    // This code adds an extra frame so that we don't lose the function that we came from
429    // by pushing the PC and the FP and then writing the current FP to point to the FP value
430    // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
431
432    // Save current PC
433    const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
434    if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
435    {
436        if (log)
437            log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
438
439        if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
440            return false;
441
442        sp -= 8;
443
444        // Save current FP
445        if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
446        {
447            if (log)
448                log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
449
450            if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
451                return false;
452        }
453        // Setup FP backchain
454        reg_value.SetUInt64 (sp);
455
456        if (log)
457            log->Printf("Writing FP:  0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
458
459        if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
460        {
461            return false;
462        }
463
464        sp -= 8;
465    }
466#endif
467
468    if (log)
469        log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
470
471    // Save return address onto the stack
472    if (!process_sp->WritePointerToMemory(sp, return_addr, error))
473        return false;
474
475    // %rsp is set to the actual stack value.
476
477    if (log)
478        log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
479
480    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
481        return false;
482
483    // %rip is set to the address of the called function.
484
485    if (log)
486        log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
487
488    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
489        return false;
490
491    return true;
492}
493
494static bool ReadIntegerArgument(Scalar           &scalar,
495                                unsigned int     bit_width,
496                                bool             is_signed,
497                                Thread           &thread,
498                                uint32_t         *argument_register_ids,
499                                unsigned int     &current_argument_register,
500                                addr_t           &current_stack_argument)
501{
502    if (bit_width > 64)
503        return false; // Scalar can't hold large integer arguments
504
505    if (current_argument_register < 6)
506    {
507        scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
508        current_argument_register++;
509        if (is_signed)
510            scalar.SignExtend (bit_width);
511    }
512    else
513    {
514        uint32_t byte_size = (bit_width + (8-1))/8;
515        Error error;
516        if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
517        {
518            current_stack_argument += byte_size;
519            return true;
520        }
521        return false;
522    }
523    return true;
524}
525
526bool
527ABISysV_x86_64::GetArgumentValues (Thread &thread,
528                                   ValueList &values) const
529{
530    unsigned int num_values = values.GetSize();
531    unsigned int value_index;
532
533    // Extract the register context so we can read arguments from registers
534
535    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
536
537    if (!reg_ctx)
538        return false;
539
540    // Get the pointer to the first stack argument so we have a place to start
541    // when reading data
542
543    addr_t sp = reg_ctx->GetSP(0);
544
545    if (!sp)
546        return false;
547
548    addr_t current_stack_argument = sp + 8; // jump over return address
549
550    uint32_t argument_register_ids[6];
551
552    argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
553    argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
554    argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
555    argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
556    argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
557    argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
558
559    unsigned int current_argument_register = 0;
560
561    for (value_index = 0;
562         value_index < num_values;
563         ++value_index)
564    {
565        Value *value = values.GetValueAtIndex(value_index);
566
567        if (!value)
568            return false;
569
570        // We currently only support extracting values with Clang QualTypes.
571        // Do we care about others?
572        ClangASTType clang_type = value->GetClangType();
573        if (!clang_type)
574            return false;
575        bool is_signed;
576
577        if (clang_type.IsIntegerType (is_signed))
578        {
579            ReadIntegerArgument(value->GetScalar(),
580                                clang_type.GetBitSize(),
581                                is_signed,
582                                thread,
583                                argument_register_ids,
584                                current_argument_register,
585                                current_stack_argument);
586        }
587        else if (clang_type.IsPointerType ())
588        {
589            ReadIntegerArgument(value->GetScalar(),
590                                clang_type.GetBitSize(),
591                                false,
592                                thread,
593                                argument_register_ids,
594                                current_argument_register,
595                                current_stack_argument);
596        }
597    }
598
599    return true;
600}
601
602Error
603ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
604{
605    Error error;
606    if (!new_value_sp)
607    {
608        error.SetErrorString("Empty value object for return value.");
609        return error;
610    }
611
612    ClangASTType clang_type = new_value_sp->GetClangType();
613    if (!clang_type)
614    {
615        error.SetErrorString ("Null clang type for return value.");
616        return error;
617    }
618
619    Thread *thread = frame_sp->GetThread().get();
620
621    bool is_signed;
622    uint32_t count;
623    bool is_complex;
624
625    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
626
627    bool set_it_simple = false;
628    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
629    {
630        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
631
632        DataExtractor data;
633        size_t num_bytes = new_value_sp->GetData(data);
634        lldb::offset_t offset = 0;
635        if (num_bytes <= 8)
636        {
637            uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
638
639            if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
640                set_it_simple = true;
641        }
642        else
643        {
644            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
645        }
646
647    }
648    else if (clang_type.IsFloatingPointType (count, is_complex))
649    {
650        if (is_complex)
651            error.SetErrorString ("We don't support returning complex values at present");
652        else
653        {
654            size_t bit_width = clang_type.GetBitSize();
655            if (bit_width <= 64)
656            {
657                const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
658                RegisterValue xmm0_value;
659                DataExtractor data;
660                size_t num_bytes = new_value_sp->GetData(data);
661
662                unsigned char buffer[16];
663                ByteOrder byte_order = data.GetByteOrder();
664
665                data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
666                xmm0_value.SetBytes(buffer, 16, byte_order);
667                reg_ctx->WriteRegister(xmm0_info, xmm0_value);
668                set_it_simple = true;
669            }
670            else
671            {
672                // FIXME - don't know how to do 80 bit long doubles yet.
673                error.SetErrorString ("We don't support returning float values > 64 bits at present");
674            }
675        }
676    }
677
678    if (!set_it_simple)
679    {
680        // Okay we've got a structure or something that doesn't fit in a simple register.
681        // We should figure out where it really goes, but we don't support this yet.
682        error.SetErrorString ("We only support setting simple integer and float return types at present.");
683    }
684
685    return error;
686}
687
688
689ValueObjectSP
690ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
691                                            ClangASTType &return_clang_type) const
692{
693    ValueObjectSP return_valobj_sp;
694    Value value;
695
696    if (!return_clang_type)
697        return return_valobj_sp;
698
699    //value.SetContext (Value::eContextTypeClangType, return_value_type);
700    value.SetClangType (return_clang_type);
701
702    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
703    if (!reg_ctx)
704        return return_valobj_sp;
705
706    const uint32_t type_flags = return_clang_type.GetTypeInfo ();
707    if (type_flags & ClangASTType::eTypeIsScalar)
708    {
709        value.SetValueType(Value::eValueTypeScalar);
710
711        bool success = false;
712        if (type_flags & ClangASTType::eTypeIsInteger)
713        {
714            // Extract the register context so we can read arguments from registers
715
716            const size_t byte_size = return_clang_type.GetByteSize();
717            uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
718            const bool is_signed = (type_flags & ClangASTType::eTypeIsSigned) != 0;
719            switch (byte_size)
720            {
721            default:
722                break;
723
724            case sizeof(uint64_t):
725                if (is_signed)
726                    value.GetScalar() = (int64_t)(raw_value);
727                else
728                    value.GetScalar() = (uint64_t)(raw_value);
729                success = true;
730                break;
731
732            case sizeof(uint32_t):
733                if (is_signed)
734                    value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
735                else
736                    value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
737                success = true;
738                break;
739
740            case sizeof(uint16_t):
741                if (is_signed)
742                    value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
743                else
744                    value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
745                success = true;
746                break;
747
748            case sizeof(uint8_t):
749                if (is_signed)
750                    value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
751                else
752                    value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
753                success = true;
754                break;
755            }
756        }
757        else if (type_flags & ClangASTType::eTypeIsFloat)
758        {
759            if (type_flags & ClangASTType::eTypeIsComplex)
760            {
761                // Don't handle complex yet.
762            }
763            else
764            {
765                const size_t byte_size = return_clang_type.GetByteSize();
766                if (byte_size <= sizeof(long double))
767                {
768                    const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
769                    RegisterValue xmm0_value;
770                    if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
771                    {
772                        DataExtractor data;
773                        if (xmm0_value.GetData(data))
774                        {
775                            lldb::offset_t offset = 0;
776                            if (byte_size == sizeof(float))
777                            {
778                                value.GetScalar() = (float) data.GetFloat(&offset);
779                                success = true;
780                            }
781                            else if (byte_size == sizeof(double))
782                            {
783                                value.GetScalar() = (double) data.GetDouble(&offset);
784                                success = true;
785                            }
786                            else if (byte_size == sizeof(long double))
787                            {
788                                // Don't handle long double since that can be encoded as 80 bit floats...
789                            }
790                        }
791                    }
792                }
793            }
794        }
795
796        if (success)
797            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
798                                                               value,
799                                                               ConstString(""));
800
801    }
802    else if (type_flags & ClangASTType::eTypeIsPointer)
803    {
804        unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
805        value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
806        value.SetValueType(Value::eValueTypeScalar);
807        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
808                                                           value,
809                                                           ConstString(""));
810    }
811    else if (type_flags & ClangASTType::eTypeIsVector)
812    {
813        const size_t byte_size = return_clang_type.GetByteSize();
814        if (byte_size > 0)
815        {
816
817            const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("ymm0", 0);
818            if (altivec_reg == NULL)
819            {
820                altivec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
821                if (altivec_reg == NULL)
822                    altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
823            }
824
825            if (altivec_reg)
826            {
827                if (byte_size <= altivec_reg->byte_size)
828                {
829                    ProcessSP process_sp (thread.GetProcess());
830                    if (process_sp)
831                    {
832                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
833                        const ByteOrder byte_order = process_sp->GetByteOrder();
834                        RegisterValue reg_value;
835                        if (reg_ctx->ReadRegister(altivec_reg, reg_value))
836                        {
837                            Error error;
838                            if (reg_value.GetAsMemoryData (altivec_reg,
839                                                           heap_data_ap->GetBytes(),
840                                                           heap_data_ap->GetByteSize(),
841                                                           byte_order,
842                                                           error))
843                            {
844                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
845                                                    byte_order,
846                                                    process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
847                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
848                                                                                   return_clang_type,
849                                                                                   ConstString(""),
850                                                                                   data);
851                            }
852                        }
853                    }
854                }
855            }
856        }
857    }
858
859    return return_valobj_sp;
860}
861
862ValueObjectSP
863ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
864{
865    ValueObjectSP return_valobj_sp;
866
867    if (!return_clang_type)
868        return return_valobj_sp;
869
870    ExecutionContext exe_ctx (thread.shared_from_this());
871    return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
872    if (return_valobj_sp)
873        return return_valobj_sp;
874
875    RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
876    if (!reg_ctx_sp)
877        return return_valobj_sp;
878
879    const size_t bit_width = return_clang_type.GetBitSize();
880    if (return_clang_type.IsAggregateType())
881    {
882        Target *target = exe_ctx.GetTargetPtr();
883        bool is_memory = true;
884        if (bit_width <= 128)
885        {
886            ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
887            DataBufferSP data_sp (new DataBufferHeap(16, 0));
888            DataExtractor return_ext (data_sp,
889                                      target_byte_order,
890                                      target->GetArchitecture().GetAddressByteSize());
891
892            const RegisterInfo *rax_info = reg_ctx_sp->GetRegisterInfoByName("rax", 0);
893            const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
894            const RegisterInfo *xmm0_info = reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
895            const RegisterInfo *xmm1_info = reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
896
897            RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
898            reg_ctx_sp->ReadRegister (rax_info, rax_value);
899            reg_ctx_sp->ReadRegister (rdx_info, rdx_value);
900            reg_ctx_sp->ReadRegister (xmm0_info, xmm0_value);
901            reg_ctx_sp->ReadRegister (xmm1_info, xmm1_value);
902
903            DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
904
905            rax_value.GetData(rax_data);
906            rdx_value.GetData(rdx_data);
907            xmm0_value.GetData(xmm0_data);
908            xmm1_value.GetData(xmm1_data);
909
910            uint32_t fp_bytes = 0;       // Tracks how much of the xmm registers we've consumed so far
911            uint32_t integer_bytes = 0;  // Tracks how much of the rax/rds registers we've consumed so far
912
913            const uint32_t num_children = return_clang_type.GetNumFields ();
914
915            // Since we are in the small struct regime, assume we are not in memory.
916            is_memory = false;
917
918            for (uint32_t idx = 0; idx < num_children; idx++)
919            {
920                std::string name;
921                uint64_t field_bit_offset = 0;
922                bool is_signed;
923                bool is_complex;
924                uint32_t count;
925
926                ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
927                const size_t field_bit_width = field_clang_type.GetBitSize();
928
929                // If there are any unaligned fields, this is stored in memory.
930                if (field_bit_offset % field_bit_width != 0)
931                {
932                    is_memory = true;
933                    break;
934                }
935
936                uint32_t field_byte_width = field_bit_width/8;
937                uint32_t field_byte_offset = field_bit_offset/8;
938
939
940                DataExtractor *copy_from_extractor = NULL;
941                uint32_t       copy_from_offset    = 0;
942
943                if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ())
944                {
945                    if (integer_bytes < 8)
946                    {
947                        if (integer_bytes + field_byte_width <= 8)
948                        {
949                            // This is in RAX, copy from register to our result structure:
950                            copy_from_extractor = &rax_data;
951                            copy_from_offset = integer_bytes;
952                            integer_bytes += field_byte_width;
953                        }
954                        else
955                        {
956                            // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
957                            copy_from_extractor = &rdx_data;
958                            copy_from_offset = 0;
959                            integer_bytes = 8 + field_byte_width;
960
961                        }
962                    }
963                    else if (integer_bytes + field_byte_width <= 16)
964                    {
965                        copy_from_extractor = &rdx_data;
966                        copy_from_offset = integer_bytes - 8;
967                        integer_bytes += field_byte_width;
968                    }
969                    else
970                    {
971                        // The last field didn't fit.  I can't see how that would happen w/o the overall size being
972                        // greater than 16 bytes.  For now, return a NULL return value object.
973                        return return_valobj_sp;
974                    }
975                }
976                else if (field_clang_type.IsFloatingPointType (count, is_complex))
977                {
978                    // Structs with long doubles are always passed in memory.
979                    if (field_bit_width == 128)
980                    {
981                        is_memory = true;
982                        break;
983                    }
984                    else if (field_bit_width == 64)
985                    {
986                        // These have to be in a single xmm register.
987                        if (fp_bytes == 0)
988                            copy_from_extractor = &xmm0_data;
989                        else
990                            copy_from_extractor = &xmm1_data;
991
992                        copy_from_offset = 0;
993                        fp_bytes += field_byte_width;
994                    }
995                    else if (field_bit_width == 32)
996                    {
997                        // This one is kind of complicated.  If we are in an "eightbyte" with another float, we'll
998                        // be stuffed into an xmm register with it.  If we are in an "eightbyte" with one or more ints,
999                        // then we will be stuffed into the appropriate GPR with them.
1000                        bool in_gpr;
1001                        if (field_byte_offset % 8 == 0)
1002                        {
1003                            // We are at the beginning of one of the eightbytes, so check the next element (if any)
1004                            if (idx == num_children - 1)
1005                                in_gpr = false;
1006                            else
1007                            {
1008                                uint64_t next_field_bit_offset = 0;
1009                                ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1,
1010                                                                                                        name,
1011                                                                                                        &next_field_bit_offset,
1012                                                                                                        NULL,
1013                                                                                                        NULL);
1014                                if (next_field_clang_type.IsIntegerType (is_signed))
1015                                    in_gpr = true;
1016                                else
1017                                {
1018                                    copy_from_offset = 0;
1019                                    in_gpr = false;
1020                                }
1021                            }
1022
1023                        }
1024                        else if (field_byte_offset % 4 == 0)
1025                        {
1026                            // We are inside of an eightbyte, so see if the field before us is floating point:
1027                            // This could happen if somebody put padding in the structure.
1028                            if (idx == 0)
1029                                in_gpr = false;
1030                            else
1031                            {
1032                                uint64_t prev_field_bit_offset = 0;
1033                                ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1,
1034                                                                                                        name,
1035                                                                                                        &prev_field_bit_offset,
1036                                                                                                        NULL,
1037                                                                                                        NULL);
1038                                if (prev_field_clang_type.IsIntegerType (is_signed))
1039                                    in_gpr = true;
1040                                else
1041                                {
1042                                    copy_from_offset = 4;
1043                                    in_gpr = false;
1044                                }
1045                            }
1046
1047                        }
1048                        else
1049                        {
1050                            is_memory = true;
1051                            continue;
1052                        }
1053
1054                        // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
1055                        if (in_gpr)
1056                        {
1057                            if (integer_bytes < 8)
1058                            {
1059                                // This is in RAX, copy from register to our result structure:
1060                                copy_from_extractor = &rax_data;
1061                                copy_from_offset = integer_bytes;
1062                                integer_bytes += field_byte_width;
1063                            }
1064                            else
1065                            {
1066                                copy_from_extractor = &rdx_data;
1067                                copy_from_offset = integer_bytes - 8;
1068                                integer_bytes += field_byte_width;
1069                            }
1070                        }
1071                        else
1072                        {
1073                            if (fp_bytes < 8)
1074                                copy_from_extractor = &xmm0_data;
1075                            else
1076                                copy_from_extractor = &xmm1_data;
1077
1078                            fp_bytes += field_byte_width;
1079                        }
1080                    }
1081                }
1082
1083                // These two tests are just sanity checks.  If I somehow get the
1084                // type calculation wrong above it is better to just return nothing
1085                // than to assert or crash.
1086                if (!copy_from_extractor)
1087                    return return_valobj_sp;
1088                if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
1089                    return return_valobj_sp;
1090
1091                copy_from_extractor->CopyByteOrderedData (copy_from_offset,
1092                                                          field_byte_width,
1093                                                          data_sp->GetBytes() + field_byte_offset,
1094                                                          field_byte_width,
1095                                                          target_byte_order);
1096            }
1097
1098            if (!is_memory)
1099            {
1100                // The result is in our data buffer.  Let's make a variable object out of it:
1101                return_valobj_sp = ValueObjectConstResult::Create (&thread,
1102                                                                   return_clang_type,
1103                                                                   ConstString(""),
1104                                                                   return_ext);
1105            }
1106        }
1107
1108
1109        // FIXME: This is just taking a guess, rax may very well no longer hold the return storage location.
1110        // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
1111        // return, and if we are at the first instruction and if so stash away the return location.  Then we would
1112        // only return the memory return value if we know it is valid.
1113
1114        if (is_memory)
1115        {
1116            unsigned rax_id = reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1117            lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
1118            return_valobj_sp = ValueObjectMemory::Create (&thread,
1119                                                          "",
1120                                                          Address (storage_addr, NULL),
1121                                                          return_clang_type);
1122        }
1123    }
1124
1125    return return_valobj_sp;
1126}
1127
1128bool
1129ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
1130{
1131    unwind_plan.Clear();
1132    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
1133
1134    uint32_t sp_reg_num = gcc_dwarf_rsp;
1135    uint32_t pc_reg_num = gcc_dwarf_rip;
1136
1137    UnwindPlan::RowSP row(new UnwindPlan::Row);
1138    row->SetCFARegister (sp_reg_num);
1139    row->SetCFAOffset (8);
1140    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
1141    unwind_plan.AppendRow (row);
1142    unwind_plan.SetSourceName ("x86_64 at-func-entry default");
1143    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
1144    return true;
1145}
1146
1147bool
1148ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
1149{
1150    unwind_plan.Clear();
1151    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
1152
1153    uint32_t fp_reg_num = gcc_dwarf_rbp;
1154    uint32_t sp_reg_num = gcc_dwarf_rsp;
1155    uint32_t pc_reg_num = gcc_dwarf_rip;
1156
1157    UnwindPlan::RowSP row(new UnwindPlan::Row);
1158
1159    const int32_t ptr_size = 8;
1160    row->SetCFARegister (gcc_dwarf_rbp);
1161    row->SetCFAOffset (2 * ptr_size);
1162    row->SetOffset (0);
1163
1164    row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1165    row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1166    row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1167
1168    unwind_plan.AppendRow (row);
1169    unwind_plan.SetSourceName ("x86_64 default unwind plan");
1170    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
1171    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
1172    return true;
1173}
1174
1175bool
1176ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
1177{
1178    return !RegisterIsCalleeSaved (reg_info);
1179}
1180
1181
1182
1183// See "Register Usage" in the
1184// "System V Application Binary Interface"
1185// "AMD64 Architecture Processor Supplement"
1186// (or "x86-64(tm) Architecture Processor Supplement" in earlier revisions)
1187// (this doc is also commonly referred to as the x86-64/AMD64 psABI)
1188// Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
1189// current version is 0.99.6 released 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
1190
1191bool
1192ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
1193{
1194    if (reg_info)
1195    {
1196        // Preserved registers are :
1197        //    rbx, rsp, rbp, r12, r13, r14, r15
1198        //    mxcsr (partially preserved)
1199        //    x87 control word
1200
1201        const char *name = reg_info->name;
1202        if (name[0] == 'r')
1203        {
1204            switch (name[1])
1205            {
1206            case '1': // r12, r13, r14, r15
1207                if (name[2] >= '2' && name[2] <= '5')
1208                    return name[3] == '\0';
1209                break;
1210
1211            default:
1212                break;
1213            }
1214        }
1215
1216        // Accept shorter-variant versions, rbx/ebx, rip/ eip, etc.
1217        if (name[0] == 'r' || name[0] == 'e')
1218        {
1219            switch (name[1])
1220            {
1221            case 'b': // rbp, rbx
1222                if (name[2] == 'p' || name[2] == 'x')
1223                    return name[3] == '\0';
1224                break;
1225
1226            case 'i': // rip
1227                if (name[2] == 'p')
1228                    return name[3] == '\0';
1229                break;
1230
1231            case 's': // rsp
1232                if (name[2] == 'p')
1233                    return name[3] == '\0';
1234                break;
1235
1236            }
1237        }
1238        if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')   // sp
1239            return true;
1240        if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0')   // fp
1241            return true;
1242        if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0')   // pc
1243            return true;
1244    }
1245    return false;
1246}
1247
1248
1249
1250void
1251ABISysV_x86_64::Initialize()
1252{
1253    PluginManager::RegisterPlugin (GetPluginNameStatic(),
1254                                   "System V ABI for x86_64 targets",
1255                                   CreateInstance);
1256}
1257
1258void
1259ABISysV_x86_64::Terminate()
1260{
1261    PluginManager::UnregisterPlugin (CreateInstance);
1262}
1263
1264lldb_private::ConstString
1265ABISysV_x86_64::GetPluginNameStatic()
1266{
1267    static ConstString g_name("sysv-x86_64");
1268    return g_name;
1269}
1270
1271//------------------------------------------------------------------
1272// PluginInterface protocol
1273//------------------------------------------------------------------
1274lldb_private::ConstString
1275ABISysV_x86_64::GetPluginName()
1276{
1277    return GetPluginNameStatic();
1278}
1279
1280uint32_t
1281ABISysV_x86_64::GetPluginVersion()
1282{
1283    return 1;
1284}
1285
1286