1 //===-- RegisterContextWindows_arm64.cpp ----------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #if defined(__aarch64__) || defined(_M_ARM64) 10 11 #include "lldb/Host/windows/HostThreadWindows.h" 12 #include "lldb/Host/windows/windows.h" 13 #include "lldb/Utility/RegisterValue.h" 14 #include "lldb/Utility/Status.h" 15 #include "lldb/lldb-private-types.h" 16 17 #include "RegisterContextWindows_arm64.h" 18 #include "TargetThreadWindows.h" 19 20 #include "llvm/ADT/STLExtras.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 #define GPR_OFFSET(idx) 0 26 #define GPR_OFFSET_NAME(reg) 0 27 28 #define FPU_OFFSET(idx) 0 29 #define FPU_OFFSET_NAME(reg) 0 30 31 #define EXC_OFFSET_NAME(reg) 0 32 #define DBG_OFFSET_NAME(reg) 0 33 34 #define DEFINE_DBG(reg, i) \ 35 #reg, NULL, \ 36 0, DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \ 37 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 38 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 39 LLDB_INVALID_REGNUM }, \ 40 NULL, NULL, NULL, 0 41 42 // Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure. 43 #define DECLARE_REGISTER_INFOS_ARM64_STRUCT 44 #include "Plugins/Process/Utility/RegisterInfos_arm64.h" 45 #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT 46 47 static size_t k_num_register_infos = 48 llvm::array_lengthof(g_register_infos_arm64_le); 49 50 // Array of lldb register numbers used to define the set of all General Purpose 51 // Registers 52 uint32_t g_gpr_reg_indices[] = { 53 gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6, gpr_x7, 54 gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13, gpr_x14, gpr_x15, 55 gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20, gpr_x21, gpr_x22, gpr_x23, 56 gpr_x24, gpr_x25, gpr_x26, gpr_x27, gpr_x28, gpr_fp, gpr_lr, gpr_sp, 57 gpr_pc, gpr_cpsr, 58 59 gpr_w0, gpr_w1, gpr_w2, gpr_w3, gpr_w4, gpr_w5, gpr_w6, gpr_w7, 60 gpr_w8, gpr_w9, gpr_w10, gpr_w11, gpr_w12, gpr_w13, gpr_w14, gpr_w15, 61 gpr_w16, gpr_w17, gpr_w18, gpr_w19, gpr_w20, gpr_w21, gpr_w22, gpr_w23, 62 gpr_w24, gpr_w25, gpr_w26, gpr_w27, gpr_w28, 63 }; 64 65 uint32_t g_fpu_reg_indices[] = { 66 fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6, fpu_v7, 67 fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13, fpu_v14, fpu_v15, 68 fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20, fpu_v21, fpu_v22, fpu_v23, 69 fpu_v24, fpu_v25, fpu_v26, fpu_v27, fpu_v28, fpu_v29, fpu_v30, fpu_v31, 70 71 fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, 72 fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13, fpu_s14, fpu_s15, 73 fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20, fpu_s21, fpu_s22, fpu_s23, 74 fpu_s24, fpu_s25, fpu_s26, fpu_s27, fpu_s28, fpu_s29, fpu_s30, fpu_s31, 75 76 fpu_d0, fpu_d1, fpu_d2, fpu_d3, fpu_d4, fpu_d5, fpu_d6, fpu_d7, 77 fpu_d8, fpu_d9, fpu_d10, fpu_d11, fpu_d12, fpu_d13, fpu_d14, fpu_d15, 78 fpu_d16, fpu_d17, fpu_d18, fpu_d19, fpu_d20, fpu_d21, fpu_d22, fpu_d23, 79 fpu_d24, fpu_d25, fpu_d26, fpu_d27, fpu_d28, fpu_d29, fpu_d30, fpu_d31, 80 81 fpu_fpsr, fpu_fpcr, 82 }; 83 84 RegisterSet g_register_sets[] = { 85 {"General Purpose Registers", "gpr", 86 llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, 87 {"Floating Point Registers", "fpu", llvm::array_lengthof(g_fpu_reg_indices), 88 g_fpu_reg_indices}, 89 }; 90 91 // Constructors and Destructors 92 RegisterContextWindows_arm64::RegisterContextWindows_arm64( 93 Thread &thread, uint32_t concrete_frame_idx) 94 : RegisterContextWindows(thread, concrete_frame_idx) {} 95 96 RegisterContextWindows_arm64::~RegisterContextWindows_arm64() {} 97 98 size_t RegisterContextWindows_arm64::GetRegisterCount() { 99 return llvm::array_lengthof(g_register_infos_arm64_le); 100 } 101 102 const RegisterInfo * 103 RegisterContextWindows_arm64::GetRegisterInfoAtIndex(size_t reg) { 104 if (reg < k_num_register_infos) 105 return &g_register_infos_arm64_le[reg]; 106 return NULL; 107 } 108 109 size_t RegisterContextWindows_arm64::GetRegisterSetCount() { 110 return llvm::array_lengthof(g_register_sets); 111 } 112 113 const RegisterSet * 114 RegisterContextWindows_arm64::GetRegisterSet(size_t reg_set) { 115 return &g_register_sets[reg_set]; 116 } 117 118 bool RegisterContextWindows_arm64::ReadRegister(const RegisterInfo *reg_info, 119 RegisterValue ®_value) { 120 if (!CacheAllRegisterValues()) 121 return false; 122 123 if (reg_info == nullptr) 124 return false; 125 126 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 127 128 switch (reg) { 129 case gpr_x0: 130 case gpr_x1: 131 case gpr_x2: 132 case gpr_x3: 133 case gpr_x4: 134 case gpr_x5: 135 case gpr_x6: 136 case gpr_x7: 137 case gpr_x8: 138 case gpr_x9: 139 case gpr_x10: 140 case gpr_x11: 141 case gpr_x12: 142 case gpr_x13: 143 case gpr_x14: 144 case gpr_x15: 145 case gpr_x16: 146 case gpr_x17: 147 case gpr_x18: 148 case gpr_x19: 149 case gpr_x20: 150 case gpr_x21: 151 case gpr_x22: 152 case gpr_x23: 153 case gpr_x24: 154 case gpr_x25: 155 case gpr_x26: 156 case gpr_x27: 157 case gpr_x28: 158 reg_value.SetUInt64(m_context.X[reg - gpr_x0]); 159 break; 160 161 case gpr_fp: 162 reg_value.SetUInt64(m_context.Fp); 163 break; 164 case gpr_sp: 165 reg_value.SetUInt64(m_context.Sp); 166 break; 167 case gpr_lr: 168 reg_value.SetUInt64(m_context.Lr); 169 break; 170 case gpr_pc: 171 reg_value.SetUInt64(m_context.Pc); 172 break; 173 case gpr_cpsr: 174 reg_value.SetUInt64(m_context.Cpsr); 175 break; 176 177 case gpr_w0: 178 case gpr_w1: 179 case gpr_w2: 180 case gpr_w3: 181 case gpr_w4: 182 case gpr_w5: 183 case gpr_w6: 184 case gpr_w7: 185 case gpr_w8: 186 case gpr_w9: 187 case gpr_w10: 188 case gpr_w11: 189 case gpr_w12: 190 case gpr_w13: 191 case gpr_w14: 192 case gpr_w15: 193 case gpr_w16: 194 case gpr_w17: 195 case gpr_w18: 196 case gpr_w19: 197 case gpr_w20: 198 case gpr_w21: 199 case gpr_w22: 200 case gpr_w23: 201 case gpr_w24: 202 case gpr_w25: 203 case gpr_w26: 204 case gpr_w27: 205 case gpr_w28: 206 reg_value.SetUInt32( 207 static_cast<uint32_t>(m_context.X[reg - gpr_w0] & 0xffffffff)); 208 break; 209 210 case fpu_v0: 211 case fpu_v1: 212 case fpu_v2: 213 case fpu_v3: 214 case fpu_v4: 215 case fpu_v5: 216 case fpu_v6: 217 case fpu_v7: 218 case fpu_v8: 219 case fpu_v9: 220 case fpu_v10: 221 case fpu_v11: 222 case fpu_v12: 223 case fpu_v13: 224 case fpu_v14: 225 case fpu_v15: 226 case fpu_v16: 227 case fpu_v17: 228 case fpu_v18: 229 case fpu_v19: 230 case fpu_v20: 231 case fpu_v21: 232 case fpu_v22: 233 case fpu_v23: 234 case fpu_v24: 235 case fpu_v25: 236 case fpu_v26: 237 case fpu_v27: 238 case fpu_v28: 239 case fpu_v29: 240 case fpu_v30: 241 case fpu_v31: 242 reg_value.SetBytes(m_context.V[reg - fpu_v0].B, reg_info->byte_size, 243 endian::InlHostByteOrder()); 244 break; 245 246 case fpu_s0: 247 case fpu_s1: 248 case fpu_s2: 249 case fpu_s3: 250 case fpu_s4: 251 case fpu_s5: 252 case fpu_s6: 253 case fpu_s7: 254 case fpu_s8: 255 case fpu_s9: 256 case fpu_s10: 257 case fpu_s11: 258 case fpu_s12: 259 case fpu_s13: 260 case fpu_s14: 261 case fpu_s15: 262 case fpu_s16: 263 case fpu_s17: 264 case fpu_s18: 265 case fpu_s19: 266 case fpu_s20: 267 case fpu_s21: 268 case fpu_s22: 269 case fpu_s23: 270 case fpu_s24: 271 case fpu_s25: 272 case fpu_s26: 273 case fpu_s27: 274 case fpu_s28: 275 case fpu_s29: 276 case fpu_s30: 277 case fpu_s31: 278 reg_value.SetFloat(m_context.V[reg - fpu_s0].S[0]); 279 break; 280 281 case fpu_d0: 282 case fpu_d1: 283 case fpu_d2: 284 case fpu_d3: 285 case fpu_d4: 286 case fpu_d5: 287 case fpu_d6: 288 case fpu_d7: 289 case fpu_d8: 290 case fpu_d9: 291 case fpu_d10: 292 case fpu_d11: 293 case fpu_d12: 294 case fpu_d13: 295 case fpu_d14: 296 case fpu_d15: 297 case fpu_d16: 298 case fpu_d17: 299 case fpu_d18: 300 case fpu_d19: 301 case fpu_d20: 302 case fpu_d21: 303 case fpu_d22: 304 case fpu_d23: 305 case fpu_d24: 306 case fpu_d25: 307 case fpu_d26: 308 case fpu_d27: 309 case fpu_d28: 310 case fpu_d29: 311 case fpu_d30: 312 case fpu_d31: 313 reg_value.SetDouble(m_context.V[reg - fpu_d0].D[0]); 314 break; 315 316 case fpu_fpsr: 317 reg_value.SetUInt32(m_context.Fpsr); 318 break; 319 320 case fpu_fpcr: 321 reg_value.SetUInt32(m_context.Fpcr); 322 break; 323 324 default: 325 reg_value.SetValueToInvalid(); 326 return false; 327 } 328 return true; 329 } 330 331 bool RegisterContextWindows_arm64::WriteRegister( 332 const RegisterInfo *reg_info, const RegisterValue ®_value) { 333 // Since we cannot only write a single register value to the inferior, we 334 // need to make sure our cached copy of the register values are fresh. 335 // Otherwise when writing one register, we may also overwrite some other 336 // register with a stale value. 337 if (!CacheAllRegisterValues()) 338 return false; 339 340 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 341 342 switch (reg) { 343 case gpr_x0: 344 case gpr_x1: 345 case gpr_x2: 346 case gpr_x3: 347 case gpr_x4: 348 case gpr_x5: 349 case gpr_x6: 350 case gpr_x7: 351 case gpr_x8: 352 case gpr_x9: 353 case gpr_x10: 354 case gpr_x11: 355 case gpr_x12: 356 case gpr_x13: 357 case gpr_x14: 358 case gpr_x15: 359 case gpr_x16: 360 case gpr_x17: 361 case gpr_x18: 362 case gpr_x19: 363 case gpr_x20: 364 case gpr_x21: 365 case gpr_x22: 366 case gpr_x23: 367 case gpr_x24: 368 case gpr_x25: 369 case gpr_x26: 370 case gpr_x27: 371 case gpr_x28: 372 m_context.X[reg - gpr_x0] = reg_value.GetAsUInt64(); 373 break; 374 375 case gpr_fp: 376 m_context.Fp = reg_value.GetAsUInt64(); 377 break; 378 case gpr_sp: 379 m_context.Sp = reg_value.GetAsUInt64(); 380 break; 381 case gpr_lr: 382 m_context.Lr = reg_value.GetAsUInt64(); 383 break; 384 case gpr_pc: 385 m_context.Pc = reg_value.GetAsUInt64(); 386 break; 387 case gpr_cpsr: 388 m_context.Cpsr = reg_value.GetAsUInt64(); 389 break; 390 391 case fpu_v0: 392 case fpu_v1: 393 case fpu_v2: 394 case fpu_v3: 395 case fpu_v4: 396 case fpu_v5: 397 case fpu_v6: 398 case fpu_v7: 399 case fpu_v8: 400 case fpu_v9: 401 case fpu_v10: 402 case fpu_v11: 403 case fpu_v12: 404 case fpu_v13: 405 case fpu_v14: 406 case fpu_v15: 407 case fpu_v16: 408 case fpu_v17: 409 case fpu_v18: 410 case fpu_v19: 411 case fpu_v20: 412 case fpu_v21: 413 case fpu_v22: 414 case fpu_v23: 415 case fpu_v24: 416 case fpu_v25: 417 case fpu_v26: 418 case fpu_v27: 419 case fpu_v28: 420 case fpu_v29: 421 case fpu_v30: 422 case fpu_v31: 423 memcpy(m_context.V[reg - fpu_v0].B, reg_value.GetBytes(), 16); 424 break; 425 426 case fpu_fpsr: 427 m_context.Fpsr = reg_value.GetAsUInt32(); 428 break; 429 430 case fpu_fpcr: 431 m_context.Fpcr = reg_value.GetAsUInt32(); 432 break; 433 434 default: 435 return false; 436 } 437 438 // Physically update the registers in the target process. 439 return ApplyAllRegisterValues(); 440 } 441 442 #endif // defined(__aarch64__) || defined(_M_ARM64) 443