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