]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Plugins / ABI / SysV-x86_64 / ABISysV_x86_64.cpp
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
33 using namespace lldb;
34 using namespace lldb_private;
35
36 enum 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
97 enum 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
175 static 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
254 static const uint32_t k_num_register_infos = sizeof(g_register_infos)/sizeof(RegisterInfo);
255 static bool g_register_info_names_constified = false;
256
257 const lldb_private::RegisterInfo *
258 ABISysV_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
279 size_t
280 ABISysV_x86_64::GetRedZoneSize () const
281 {
282     return 128;
283 }
284
285 //------------------------------------------------------------------
286 // Static Functions
287 //------------------------------------------------------------------
288 ABISP
289 ABISysV_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
301 bool
302 ABISysV_x86_64::PrepareTrivialCall (Thread &thread, 
303                                     addr_t sp, 
304                                     addr_t func_addr, 
305                                     addr_t return_addr, 
306                                     llvm::ArrayRef<addr_t> args) const
307 {
308     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
309     
310     if (log)
311     {
312         StreamString s;
313         s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
314                     thread.GetID(),
315                     (uint64_t)sp,
316                     (uint64_t)func_addr,
317                     (uint64_t)return_addr);
318
319         for (int i = 0; i < args.size(); ++i)
320             s.Printf (", arg%d = 0x%" PRIx64, i + 1, args[i]);
321         s.PutCString (")");
322         log->PutCString(s.GetString().c_str());
323     }
324     
325     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
326     if (!reg_ctx)
327         return false;
328     
329     const RegisterInfo *reg_info = NULL;
330     
331     if (args.size() > 6) // TODO handle more than 6 arguments
332         return false;
333     
334     for (int i = 0; i < args.size(); ++i)
335     {
336         reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
337         if (log)
338             log->Printf("About to write arg%d (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
339         if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
340             return false;
341     }
342
343     // First, align the SP
344
345     if (log)
346         log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
347
348     sp &= ~(0xfull); // 16-byte alignment
349
350     sp -= 8;
351
352     Error error;
353     const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
354     const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
355     ProcessSP process_sp (thread.GetProcess());
356
357     RegisterValue reg_value;
358
359 #if 0
360     // This code adds an extra frame so that we don't lose the function that we came from
361     // by pushing the PC and the FP and then writing the current FP to point to the FP value
362     // we just pushed. It is disabled for now until the stack backtracing code can be debugged.
363
364     // Save current PC
365     const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
366     if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
367     {
368         if (log)
369             log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
370         
371         if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
372             return false;
373
374         sp -= 8;
375         
376         // Save current FP
377         if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
378         {
379             if (log)
380                 log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());
381             
382             if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
383                 return false;
384         }
385         // Setup FP backchain
386         reg_value.SetUInt64 (sp);
387         
388         if (log)
389             log->Printf("Writing FP:  0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());
390
391         if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
392         {
393             return false;
394         }
395         
396         sp -= 8;
397     }
398 #endif 
399     
400     if (log)
401         log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
402
403     // Save return address onto the stack
404     if (!process_sp->WritePointerToMemory(sp, return_addr, error))
405         return false;
406
407     // %rsp is set to the actual stack value.
408
409     if (log)
410         log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
411     
412     if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
413         return false;
414
415     // %rip is set to the address of the called function.
416     
417     if (log)
418         log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
419
420     if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
421         return false;
422
423     return true;
424 }
425
426 static bool ReadIntegerArgument(Scalar           &scalar,
427                                 unsigned int     bit_width,
428                                 bool             is_signed,
429                                 Thread           &thread,
430                                 uint32_t         *argument_register_ids,
431                                 unsigned int     &current_argument_register,
432                                 addr_t           &current_stack_argument)
433 {
434     if (bit_width > 64)
435         return false; // Scalar can't hold large integer arguments
436     
437     if (current_argument_register < 6)
438     {
439         scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
440         current_argument_register++;
441         if (is_signed)
442             scalar.SignExtend (bit_width);
443     }
444     else
445     {
446         uint32_t byte_size = (bit_width + (8-1))/8;
447         Error error;
448         if (thread.GetProcess()->ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error))
449         {
450             current_stack_argument += byte_size;
451             return true;
452         }
453         return false;
454     }
455     return true;
456 }
457
458 bool
459 ABISysV_x86_64::GetArgumentValues (Thread &thread,
460                                    ValueList &values) const
461 {
462     unsigned int num_values = values.GetSize();
463     unsigned int value_index;
464         
465     // Extract the register context so we can read arguments from registers
466     
467     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
468     
469     if (!reg_ctx)
470         return false;
471     
472     // Get the pointer to the first stack argument so we have a place to start 
473     // when reading data
474     
475     addr_t sp = reg_ctx->GetSP(0);
476     
477     if (!sp)
478         return false;
479     
480     addr_t current_stack_argument = sp + 8; // jump over return address
481     
482     uint32_t argument_register_ids[6];
483     
484     argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
485     argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
486     argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
487     argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
488     argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
489     argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
490     
491     unsigned int current_argument_register = 0;
492     
493     for (value_index = 0;
494          value_index < num_values;
495          ++value_index)
496     {
497         Value *value = values.GetValueAtIndex(value_index);
498     
499         if (!value)
500             return false;
501         
502         // We currently only support extracting values with Clang QualTypes.
503         // Do we care about others?
504         ClangASTType clang_type = value->GetClangType();
505         if (!clang_type)
506             return false;
507         bool is_signed;
508         
509         if (clang_type.IsIntegerType (is_signed))
510         {
511             ReadIntegerArgument(value->GetScalar(),
512                                 clang_type.GetBitSize(),
513                                 is_signed,
514                                 thread, 
515                                 argument_register_ids, 
516                                 current_argument_register,
517                                 current_stack_argument);
518         }
519         else if (clang_type.IsPointerType ())
520         {
521             ReadIntegerArgument(value->GetScalar(),
522                                 clang_type.GetBitSize(),
523                                 false,
524                                 thread,
525                                 argument_register_ids, 
526                                 current_argument_register,
527                                 current_stack_argument);
528         }
529     }
530     
531     return true;
532 }
533
534 Error
535 ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
536 {
537     Error error;
538     if (!new_value_sp)
539     {
540         error.SetErrorString("Empty value object for return value.");
541         return error;
542     }
543     
544     ClangASTType clang_type = new_value_sp->GetClangType();
545     if (!clang_type)
546     {
547         error.SetErrorString ("Null clang type for return value.");
548         return error;
549     }
550     
551     Thread *thread = frame_sp->GetThread().get();
552     
553     bool is_signed;
554     uint32_t count;
555     bool is_complex;
556     
557     RegisterContext *reg_ctx = thread->GetRegisterContext().get();
558
559     bool set_it_simple = false;
560     if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
561     {
562         const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
563
564         DataExtractor data;
565         size_t num_bytes = new_value_sp->GetData(data);
566         lldb::offset_t offset = 0;
567         if (num_bytes <= 8)
568         {
569             uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
570             
571             if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
572                 set_it_simple = true;
573         }
574         else
575         {
576             error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
577         }
578
579     }
580     else if (clang_type.IsFloatingPointType (count, is_complex))
581     {
582         if (is_complex)
583             error.SetErrorString ("We don't support returning complex values at present");
584         else
585         {
586             size_t bit_width = clang_type.GetBitSize();
587             if (bit_width <= 64)
588             {
589                 const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
590                 RegisterValue xmm0_value;
591                 DataExtractor data;
592                 size_t num_bytes = new_value_sp->GetData(data);
593
594                 unsigned char buffer[16];
595                 ByteOrder byte_order = data.GetByteOrder();
596                 
597                 data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
598                 xmm0_value.SetBytes(buffer, 16, byte_order);
599                 reg_ctx->WriteRegister(xmm0_info, xmm0_value);
600                 set_it_simple = true;
601             }
602             else
603             {
604                 // FIXME - don't know how to do 80 bit long doubles yet.
605                 error.SetErrorString ("We don't support returning float values > 64 bits at present");
606             }
607         }
608     }
609     
610     if (!set_it_simple)
611     {
612         // Okay we've got a structure or something that doesn't fit in a simple register.
613         // We should figure out where it really goes, but we don't support this yet.
614         error.SetErrorString ("We only support setting simple integer and float return types at present.");
615     }
616     
617     return error;
618 }
619
620
621 ValueObjectSP
622 ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
623                                             ClangASTType &return_clang_type) const
624 {
625     ValueObjectSP return_valobj_sp;
626     Value value;
627     
628     if (!return_clang_type)
629         return return_valobj_sp;
630
631     //value.SetContext (Value::eContextTypeClangType, return_value_type);
632     value.SetClangType (return_clang_type);
633     
634     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
635     if (!reg_ctx)
636         return return_valobj_sp;
637     
638     const uint32_t type_flags = return_clang_type.GetTypeInfo ();
639     if (type_flags & ClangASTType::eTypeIsScalar)
640     {
641         value.SetValueType(Value::eValueTypeScalar);
642
643         bool success = false;
644         if (type_flags & ClangASTType::eTypeIsInteger)
645         {
646             // Extract the register context so we can read arguments from registers
647             
648             const size_t byte_size = return_clang_type.GetByteSize();
649             uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
650             const bool is_signed = (type_flags & ClangASTType::eTypeIsSigned) != 0;
651             switch (byte_size)
652             {
653             default:
654                 break;
655
656             case sizeof(uint64_t):
657                 if (is_signed)
658                     value.GetScalar() = (int64_t)(raw_value);
659                 else
660                     value.GetScalar() = (uint64_t)(raw_value);
661                 success = true;
662                 break;
663
664             case sizeof(uint32_t):
665                 if (is_signed)
666                     value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
667                 else
668                     value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
669                 success = true;
670                 break;
671
672             case sizeof(uint16_t):
673                 if (is_signed)
674                     value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
675                 else
676                     value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
677                 success = true;
678                 break;
679
680             case sizeof(uint8_t):
681                 if (is_signed)
682                     value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
683                 else
684                     value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
685                 success = true;
686                 break;
687             }
688         }
689         else if (type_flags & ClangASTType::eTypeIsFloat)
690         {
691             if (type_flags & ClangASTType::eTypeIsComplex)
692             {
693                 // Don't handle complex yet.
694             }
695             else
696             {
697                 const size_t byte_size = return_clang_type.GetByteSize();
698                 if (byte_size <= sizeof(long double))
699                 {
700                     const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
701                     RegisterValue xmm0_value;
702                     if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
703                     {
704                         DataExtractor data;
705                         if (xmm0_value.GetData(data))
706                         {
707                             lldb::offset_t offset = 0;
708                             if (byte_size == sizeof(float))
709                             {
710                                 value.GetScalar() = (float) data.GetFloat(&offset);
711                                 success = true;
712                             }
713                             else if (byte_size == sizeof(double))
714                             {
715                                 value.GetScalar() = (double) data.GetDouble(&offset);
716                                 success = true;
717                             }
718                             else if (byte_size == sizeof(long double))
719                             {
720                                 // Don't handle long double since that can be encoded as 80 bit floats...
721                             }
722                         }
723                     }
724                 }
725             }
726         }
727         
728         if (success)
729             return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
730                                                                value,
731                                                                ConstString(""));
732
733     }
734     else if (type_flags & ClangASTType::eTypeIsPointer)
735     {
736         unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
737         value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
738         value.SetValueType(Value::eValueTypeScalar);
739         return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
740                                                            value,
741                                                            ConstString(""));
742     }
743     else if (type_flags & ClangASTType::eTypeIsVector)
744     {
745         const size_t byte_size = return_clang_type.GetByteSize();
746         if (byte_size > 0)
747         {
748
749             const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("ymm0", 0);
750             if (altivec_reg == NULL)
751             {
752                 altivec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
753                 if (altivec_reg == NULL)
754                     altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
755             }
756             
757             if (altivec_reg)
758             {
759                 if (byte_size <= altivec_reg->byte_size)
760                 {
761                     ProcessSP process_sp (thread.GetProcess());
762                     if (process_sp)
763                     {
764                         std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
765                         const ByteOrder byte_order = process_sp->GetByteOrder();
766                         RegisterValue reg_value;
767                         if (reg_ctx->ReadRegister(altivec_reg, reg_value))
768                         {
769                             Error error;
770                             if (reg_value.GetAsMemoryData (altivec_reg,
771                                                            heap_data_ap->GetBytes(),
772                                                            heap_data_ap->GetByteSize(),
773                                                            byte_order,
774                                                            error))
775                             {
776                                 DataExtractor data (DataBufferSP (heap_data_ap.release()),
777                                                     byte_order,
778                                                     process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
779                                 return_valobj_sp = ValueObjectConstResult::Create (&thread,
780                                                                                    return_clang_type,
781                                                                                    ConstString(""),
782                                                                                    data);
783                             }
784                         }
785                     }
786                 }
787             }
788         }
789     }
790     
791     return return_valobj_sp;
792 }
793
794 ValueObjectSP
795 ABISysV_x86_64::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
796 {
797     ValueObjectSP return_valobj_sp;
798
799     if (!return_clang_type)
800         return return_valobj_sp;
801     
802     ExecutionContext exe_ctx (thread.shared_from_this());
803     return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
804     if (return_valobj_sp)
805         return return_valobj_sp;
806     
807     RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
808     if (!reg_ctx_sp)
809         return return_valobj_sp;
810         
811     const size_t bit_width = return_clang_type.GetBitSize();
812     if (return_clang_type.IsAggregateType())
813     {
814         Target *target = exe_ctx.GetTargetPtr();
815         bool is_memory = true;
816         if (bit_width <= 128)
817         {
818             ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
819             DataBufferSP data_sp (new DataBufferHeap(16, 0));
820             DataExtractor return_ext (data_sp, 
821                                       target_byte_order, 
822                                       target->GetArchitecture().GetAddressByteSize());
823                                                            
824             const RegisterInfo *rax_info = reg_ctx_sp->GetRegisterInfoByName("rax", 0);
825             const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
826             const RegisterInfo *xmm0_info = reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
827             const RegisterInfo *xmm1_info = reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
828             
829             RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
830             reg_ctx_sp->ReadRegister (rax_info, rax_value);
831             reg_ctx_sp->ReadRegister (rdx_info, rdx_value);
832             reg_ctx_sp->ReadRegister (xmm0_info, xmm0_value);
833             reg_ctx_sp->ReadRegister (xmm1_info, xmm1_value);
834
835             DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
836             
837             rax_value.GetData(rax_data);
838             rdx_value.GetData(rdx_data);
839             xmm0_value.GetData(xmm0_data);
840             xmm1_value.GetData(xmm1_data);
841             
842             uint32_t fp_bytes = 0;       // Tracks how much of the xmm registers we've consumed so far
843             uint32_t integer_bytes = 0;  // Tracks how much of the rax/rds registers we've consumed so far
844             
845             const uint32_t num_children = return_clang_type.GetNumFields ();
846             
847             // Since we are in the small struct regime, assume we are not in memory.
848             is_memory = false;
849             
850             for (uint32_t idx = 0; idx < num_children; idx++)
851             {
852                 std::string name;
853                 uint64_t field_bit_offset = 0;
854                 bool is_signed;
855                 bool is_complex;
856                 uint32_t count;
857                 
858                 ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
859                 const size_t field_bit_width = field_clang_type.GetBitSize();
860
861                 // If there are any unaligned fields, this is stored in memory.
862                 if (field_bit_offset % field_bit_width != 0)
863                 {
864                     is_memory = true;
865                     break;
866                 }
867                 
868                 uint32_t field_byte_width = field_bit_width/8;
869                 uint32_t field_byte_offset = field_bit_offset/8;
870                 
871
872                 DataExtractor *copy_from_extractor = NULL;
873                 uint32_t       copy_from_offset    = 0;
874                 
875                 if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ())
876                 {
877                     if (integer_bytes < 8)
878                     {
879                         if (integer_bytes + field_byte_width <= 8)
880                         {
881                             // This is in RAX, copy from register to our result structure:
882                             copy_from_extractor = &rax_data;
883                             copy_from_offset = integer_bytes;
884                             integer_bytes += field_byte_width;
885                         }
886                         else
887                         {
888                             // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
889                             copy_from_extractor = &rdx_data;
890                             copy_from_offset = 0;
891                             integer_bytes = 8 + field_byte_width;
892                         
893                         }
894                     }
895                     else if (integer_bytes + field_byte_width <= 16)
896                     {
897                         copy_from_extractor = &rdx_data;
898                         copy_from_offset = integer_bytes - 8;
899                         integer_bytes += field_byte_width;
900                     }
901                     else
902                     {
903                         // The last field didn't fit.  I can't see how that would happen w/o the overall size being 
904                         // greater than 16 bytes.  For now, return a NULL return value object.
905                         return return_valobj_sp;
906                     }
907                 }
908                 else if (field_clang_type.IsFloatingPointType (count, is_complex))
909                 {
910                     // Structs with long doubles are always passed in memory.
911                     if (field_bit_width == 128)
912                     {
913                         is_memory = true;
914                         break;
915                     }
916                     else if (field_bit_width == 64)
917                     {
918                         // These have to be in a single xmm register.
919                         if (fp_bytes == 0)
920                             copy_from_extractor = &xmm0_data;
921                         else
922                             copy_from_extractor = &xmm1_data;
923
924                         copy_from_offset = 0;
925                         fp_bytes += field_byte_width;
926                     }
927                     else if (field_bit_width == 32)
928                     {
929                         // This one is kind of complicated.  If we are in an "eightbyte" with another float, we'll
930                         // be stuffed into an xmm register with it.  If we are in an "eightbyte" with one or more ints,
931                         // then we will be stuffed into the appropriate GPR with them.
932                         bool in_gpr;
933                         if (field_byte_offset % 8 == 0) 
934                         {
935                             // We are at the beginning of one of the eightbytes, so check the next element (if any)
936                             if (idx == num_children - 1)
937                                 in_gpr = false;
938                             else
939                             {
940                                 uint64_t next_field_bit_offset = 0;
941                                 ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1,
942                                                                                                         name,
943                                                                                                         &next_field_bit_offset,
944                                                                                                         NULL,
945                                                                                                         NULL);
946                                 if (next_field_clang_type.IsIntegerType (is_signed))
947                                     in_gpr = true;
948                                 else
949                                 {
950                                     copy_from_offset = 0;
951                                     in_gpr = false;
952                                 }
953                             }
954                                 
955                         }
956                         else if (field_byte_offset % 4 == 0)
957                         {
958                             // We are inside of an eightbyte, so see if the field before us is floating point:
959                             // This could happen if somebody put padding in the structure.
960                             if (idx == 0)
961                                 in_gpr = false;
962                             else
963                             {
964                                 uint64_t prev_field_bit_offset = 0;
965                                 ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1,
966                                                                                                         name,
967                                                                                                         &prev_field_bit_offset,
968                                                                                                         NULL,
969                                                                                                         NULL);
970                                 if (prev_field_clang_type.IsIntegerType (is_signed))
971                                     in_gpr = true;
972                                 else
973                                 {
974                                     copy_from_offset = 4;
975                                     in_gpr = false;
976                                 }
977                             }
978                             
979                         }
980                         else
981                         {
982                             is_memory = true;
983                             continue;
984                         }
985                         
986                         // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
987                         if (in_gpr)
988                         {
989                             if (integer_bytes < 8)
990                             {
991                                 // This is in RAX, copy from register to our result structure:
992                                 copy_from_extractor = &rax_data;
993                                 copy_from_offset = integer_bytes;
994                                 integer_bytes += field_byte_width;
995                             }
996                             else
997                             {
998                                 copy_from_extractor = &rdx_data;
999                                 copy_from_offset = integer_bytes - 8;
1000                                 integer_bytes += field_byte_width;
1001                             }
1002                         }
1003                         else
1004                         {
1005                             if (fp_bytes < 8)
1006                                 copy_from_extractor = &xmm0_data;
1007                             else
1008                                 copy_from_extractor = &xmm1_data;
1009
1010                             fp_bytes += field_byte_width;
1011                         }
1012                     } 
1013                 }
1014                 
1015                 // These two tests are just sanity checks.  If I somehow get the
1016                 // type calculation wrong above it is better to just return nothing
1017                 // than to assert or crash.
1018                 if (!copy_from_extractor)
1019                     return return_valobj_sp;
1020                 if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
1021                     return return_valobj_sp;
1022                     
1023                 copy_from_extractor->CopyByteOrderedData (copy_from_offset, 
1024                                                           field_byte_width, 
1025                                                           data_sp->GetBytes() + field_byte_offset, 
1026                                                           field_byte_width, 
1027                                                           target_byte_order);
1028             }
1029             
1030             if (!is_memory)
1031             {
1032                 // The result is in our data buffer.  Let's make a variable object out of it:
1033                 return_valobj_sp = ValueObjectConstResult::Create (&thread, 
1034                                                                    return_clang_type,
1035                                                                    ConstString(""),
1036                                                                    return_ext);
1037             }
1038         }
1039         
1040         
1041         // FIXME: This is just taking a guess, rax may very well no longer hold the return storage location.
1042         // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
1043         // return, and if we are at the first instruction and if so stash away the return location.  Then we would
1044         // only return the memory return value if we know it is valid.
1045         
1046         if (is_memory)
1047         {
1048             unsigned rax_id = reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1049             lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
1050             return_valobj_sp = ValueObjectMemory::Create (&thread,
1051                                                           "",
1052                                                           Address (storage_addr, NULL),
1053                                                           return_clang_type); 
1054         }
1055     }
1056         
1057     return return_valobj_sp;
1058 }
1059
1060 bool
1061 ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
1062 {
1063     unwind_plan.Clear();
1064     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
1065     
1066     uint32_t sp_reg_num = gcc_dwarf_rsp;
1067     uint32_t pc_reg_num = gcc_dwarf_rip;
1068     
1069     UnwindPlan::RowSP row(new UnwindPlan::Row);
1070     row->SetCFARegister (sp_reg_num);
1071     row->SetCFAOffset (8);
1072     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
1073     unwind_plan.AppendRow (row);
1074     unwind_plan.SetSourceName ("x86_64 at-func-entry default");
1075     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
1076     return true;
1077 }
1078
1079 bool
1080 ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
1081 {
1082     unwind_plan.Clear();
1083     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
1084
1085     uint32_t fp_reg_num = gcc_dwarf_rbp;
1086     uint32_t sp_reg_num = gcc_dwarf_rsp;
1087     uint32_t pc_reg_num = gcc_dwarf_rip;
1088     
1089     UnwindPlan::RowSP row(new UnwindPlan::Row);
1090
1091     const int32_t ptr_size = 8;
1092     row->SetCFARegister (gcc_dwarf_rbp);
1093     row->SetCFAOffset (2 * ptr_size);
1094     row->SetOffset (0);
1095     
1096     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1097     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1098     row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1099
1100     unwind_plan.AppendRow (row);
1101     unwind_plan.SetSourceName ("x86_64 default unwind plan");
1102     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
1103     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
1104     return true;
1105 }
1106
1107 bool
1108 ABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
1109 {
1110     return !RegisterIsCalleeSaved (reg_info);
1111 }
1112
1113
1114
1115 // See "Register Usage" in the 
1116 // "System V Application Binary Interface"
1117 // "AMD64 Architecture Processor Supplement" 
1118 // (or "x86-64(tm) Architecture Processor Supplement" in earlier revisions)
1119 // (this doc is also commonly referred to as the x86-64/AMD64 psABI)
1120 // Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
1121 // current version is 0.99.6 released 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
1122
1123 bool
1124 ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
1125 {
1126     if (reg_info)
1127     {
1128         // Preserved registers are :
1129         //    rbx, rsp, rbp, r12, r13, r14, r15
1130         //    mxcsr (partially preserved)
1131         //    x87 control word
1132
1133         const char *name = reg_info->name;
1134         if (name[0] == 'r')
1135         {
1136             switch (name[1])
1137             {
1138             case '1': // r12, r13, r14, r15
1139                 if (name[2] >= '2' && name[2] <= '5')
1140                     return name[3] == '\0';
1141                 break;
1142
1143             default:
1144                 break;
1145             }
1146         }
1147
1148         // Accept shorter-variant versions, rbx/ebx, rip/ eip, etc.
1149         if (name[0] == 'r' || name[0] == 'e')
1150         {
1151             switch (name[1])
1152             {
1153             case 'b': // rbp, rbx
1154                 if (name[2] == 'p' || name[2] == 'x')
1155                     return name[3] == '\0';
1156                 break;
1157
1158             case 'i': // rip
1159                 if (name[2] == 'p')
1160                     return name[3] == '\0'; 
1161                 break;
1162
1163             case 's': // rsp
1164                 if (name[2] == 'p')
1165                     return name[3] == '\0';
1166                 break;
1167
1168             }
1169         }
1170         if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')   // sp
1171             return true;
1172         if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0')   // fp
1173             return true;
1174         if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0')   // pc
1175             return true;
1176     }
1177     return false;
1178 }
1179
1180
1181
1182 void
1183 ABISysV_x86_64::Initialize()
1184 {
1185     PluginManager::RegisterPlugin (GetPluginNameStatic(),
1186                                    "System V ABI for x86_64 targets",
1187                                    CreateInstance);
1188 }
1189
1190 void
1191 ABISysV_x86_64::Terminate()
1192 {
1193     PluginManager::UnregisterPlugin (CreateInstance);
1194 }
1195
1196 lldb_private::ConstString
1197 ABISysV_x86_64::GetPluginNameStatic()
1198 {
1199     static ConstString g_name("sysv-x86_64");
1200     return g_name;
1201 }
1202
1203 //------------------------------------------------------------------
1204 // PluginInterface protocol
1205 //------------------------------------------------------------------
1206 lldb_private::ConstString
1207 ABISysV_x86_64::GetPluginName()
1208 {
1209     return GetPluginNameStatic();
1210 }
1211
1212 uint32_t
1213 ABISysV_x86_64::GetPluginVersion()
1214 {
1215     return 1;
1216 }
1217