1 //===-- RegisterContextWindows_arm.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(__arm__) || defined(_M_ARM) 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_arm.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 FPU_OFFSET(idx) 0 27 #define FPSCR_OFFSET 0 28 #define EXC_OFFSET(reg) 0 29 #define DBG_OFFSET_NAME(reg) 0 30 31 #define DEFINE_DBG(reg, i) \ 32 #reg, NULL, \ 33 0, DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \ 34 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 35 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ 36 LLDB_INVALID_REGNUM }, \ 37 NULL, NULL 38 39 // Include RegisterInfos_arm to declare our g_register_infos_arm structure. 40 #define DECLARE_REGISTER_INFOS_ARM_STRUCT 41 #include "Plugins/Process/Utility/RegisterInfos_arm.h" 42 #undef DECLARE_REGISTER_INFOS_ARM_STRUCT 43 44 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos_arm); 45 46 // Array of lldb register numbers used to define the set of all General Purpose 47 // Registers 48 uint32_t g_gpr_reg_indices[] = { 49 gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8, 50 gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr, 51 }; 52 53 uint32_t g_fpu_reg_indices[] = { 54 fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, 55 fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13, fpu_s14, fpu_s15, 56 fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20, fpu_s21, fpu_s22, fpu_s23, 57 fpu_s24, fpu_s25, fpu_s26, fpu_s27, fpu_s28, fpu_s29, fpu_s30, fpu_s31, 58 59 fpu_d0, fpu_d1, fpu_d2, fpu_d3, fpu_d4, fpu_d5, fpu_d6, fpu_d7, 60 fpu_d8, fpu_d9, fpu_d10, fpu_d11, fpu_d12, fpu_d13, fpu_d14, fpu_d15, 61 fpu_d16, fpu_d17, fpu_d18, fpu_d19, fpu_d20, fpu_d21, fpu_d22, fpu_d23, 62 fpu_d24, fpu_d25, fpu_d26, fpu_d27, fpu_d28, fpu_d29, fpu_d30, fpu_d31, 63 64 fpu_q0, fpu_q1, fpu_q2, fpu_q3, fpu_q4, fpu_q5, fpu_q6, fpu_q7, 65 fpu_q8, fpu_q9, fpu_q10, fpu_q11, fpu_q12, fpu_q13, fpu_q14, fpu_q15, 66 67 fpu_fpscr, 68 }; 69 70 RegisterSet g_register_sets[] = { 71 {"General Purpose Registers", "gpr", 72 llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, 73 {"Floating Point Registers", "fpu", llvm::array_lengthof(g_fpu_reg_indices), 74 g_fpu_reg_indices}, 75 }; 76 77 // Constructors and Destructors 78 RegisterContextWindows_arm::RegisterContextWindows_arm( 79 Thread &thread, uint32_t concrete_frame_idx) 80 : RegisterContextWindows(thread, concrete_frame_idx) {} 81 82 RegisterContextWindows_arm::~RegisterContextWindows_arm() {} 83 84 size_t RegisterContextWindows_arm::GetRegisterCount() { 85 return llvm::array_lengthof(g_register_infos_arm); 86 } 87 88 const RegisterInfo * 89 RegisterContextWindows_arm::GetRegisterInfoAtIndex(size_t reg) { 90 if (reg < k_num_register_infos) 91 return &g_register_infos_arm[reg]; 92 return NULL; 93 } 94 95 size_t RegisterContextWindows_arm::GetRegisterSetCount() { 96 return llvm::array_lengthof(g_register_sets); 97 } 98 99 const RegisterSet *RegisterContextWindows_arm::GetRegisterSet(size_t reg_set) { 100 return &g_register_sets[reg_set]; 101 } 102 103 bool RegisterContextWindows_arm::ReadRegister(const RegisterInfo *reg_info, 104 RegisterValue ®_value) { 105 if (!CacheAllRegisterValues()) 106 return false; 107 108 if (reg_info == nullptr) 109 return false; 110 111 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 112 113 switch (reg) { 114 case gpr_r0: 115 reg_value.SetUInt32(m_context.R0); 116 break; 117 case gpr_r1: 118 reg_value.SetUInt32(m_context.R1); 119 break; 120 case gpr_r2: 121 reg_value.SetUInt32(m_context.R2); 122 break; 123 case gpr_r3: 124 reg_value.SetUInt32(m_context.R3); 125 break; 126 case gpr_r4: 127 reg_value.SetUInt32(m_context.R4); 128 break; 129 case gpr_r5: 130 reg_value.SetUInt32(m_context.R5); 131 break; 132 case gpr_r6: 133 reg_value.SetUInt32(m_context.R6); 134 break; 135 case gpr_r7: 136 reg_value.SetUInt32(m_context.R7); 137 break; 138 case gpr_r8: 139 reg_value.SetUInt32(m_context.R8); 140 break; 141 case gpr_r9: 142 reg_value.SetUInt32(m_context.R9); 143 break; 144 case gpr_r10: 145 reg_value.SetUInt32(m_context.R10); 146 break; 147 case gpr_r11: 148 reg_value.SetUInt32(m_context.R11); 149 break; 150 case gpr_r12: 151 reg_value.SetUInt32(m_context.R12); 152 break; 153 case gpr_sp: 154 reg_value.SetUInt32(m_context.Sp); 155 break; 156 case gpr_lr: 157 reg_value.SetUInt32(m_context.Lr); 158 break; 159 case gpr_pc: 160 reg_value.SetUInt32(m_context.Pc); 161 break; 162 case gpr_cpsr: 163 reg_value.SetUInt32(m_context.Cpsr); 164 break; 165 166 case fpu_s0: 167 case fpu_s1: 168 case fpu_s2: 169 case fpu_s3: 170 case fpu_s4: 171 case fpu_s5: 172 case fpu_s6: 173 case fpu_s7: 174 case fpu_s8: 175 case fpu_s9: 176 case fpu_s10: 177 case fpu_s11: 178 case fpu_s12: 179 case fpu_s13: 180 case fpu_s14: 181 case fpu_s15: 182 case fpu_s16: 183 case fpu_s17: 184 case fpu_s18: 185 case fpu_s19: 186 case fpu_s20: 187 case fpu_s21: 188 case fpu_s22: 189 case fpu_s23: 190 case fpu_s24: 191 case fpu_s25: 192 case fpu_s26: 193 case fpu_s27: 194 case fpu_s28: 195 case fpu_s29: 196 case fpu_s30: 197 case fpu_s31: 198 reg_value.SetUInt32(m_context.S[reg - fpu_s0], RegisterValue::eTypeFloat); 199 break; 200 201 case fpu_d0: 202 case fpu_d1: 203 case fpu_d2: 204 case fpu_d3: 205 case fpu_d4: 206 case fpu_d5: 207 case fpu_d6: 208 case fpu_d7: 209 case fpu_d8: 210 case fpu_d9: 211 case fpu_d10: 212 case fpu_d11: 213 case fpu_d12: 214 case fpu_d13: 215 case fpu_d14: 216 case fpu_d15: 217 case fpu_d16: 218 case fpu_d17: 219 case fpu_d18: 220 case fpu_d19: 221 case fpu_d20: 222 case fpu_d21: 223 case fpu_d22: 224 case fpu_d23: 225 case fpu_d24: 226 case fpu_d25: 227 case fpu_d26: 228 case fpu_d27: 229 case fpu_d28: 230 case fpu_d29: 231 case fpu_d30: 232 case fpu_d31: 233 reg_value.SetUInt64(m_context.D[reg - fpu_d0], RegisterValue::eTypeDouble); 234 break; 235 236 case fpu_q0: 237 case fpu_q1: 238 case fpu_q2: 239 case fpu_q3: 240 case fpu_q4: 241 case fpu_q5: 242 case fpu_q6: 243 case fpu_q7: 244 case fpu_q8: 245 case fpu_q9: 246 case fpu_q10: 247 case fpu_q11: 248 case fpu_q12: 249 case fpu_q13: 250 case fpu_q14: 251 case fpu_q15: 252 reg_value.SetBytes(&m_context.Q[reg - fpu_q0], reg_info->byte_size, 253 endian::InlHostByteOrder()); 254 break; 255 256 case fpu_fpscr: 257 reg_value.SetUInt32(m_context.Fpscr); 258 break; 259 260 default: 261 reg_value.SetValueToInvalid(); 262 return false; 263 } 264 return true; 265 } 266 267 bool RegisterContextWindows_arm::WriteRegister(const RegisterInfo *reg_info, 268 const RegisterValue ®_value) { 269 // Since we cannot only write a single register value to the inferior, we 270 // need to make sure our cached copy of the register values are fresh. 271 // Otherwise when writing EAX, for example, we may also overwrite some other 272 // register with a stale value. 273 if (!CacheAllRegisterValues()) 274 return false; 275 276 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 277 278 switch (reg) { 279 case gpr_r0: 280 m_context.R0 = reg_value.GetAsUInt32(); 281 break; 282 case gpr_r1: 283 m_context.R1 = reg_value.GetAsUInt32(); 284 break; 285 case gpr_r2: 286 m_context.R2 = reg_value.GetAsUInt32(); 287 break; 288 case gpr_r3: 289 m_context.R3 = reg_value.GetAsUInt32(); 290 break; 291 case gpr_r4: 292 m_context.R4 = reg_value.GetAsUInt32(); 293 break; 294 case gpr_r5: 295 m_context.R5 = reg_value.GetAsUInt32(); 296 break; 297 case gpr_r6: 298 m_context.R6 = reg_value.GetAsUInt32(); 299 break; 300 case gpr_r7: 301 m_context.R7 = reg_value.GetAsUInt32(); 302 break; 303 case gpr_r8: 304 m_context.R8 = reg_value.GetAsUInt32(); 305 break; 306 case gpr_r9: 307 m_context.R9 = reg_value.GetAsUInt32(); 308 break; 309 case gpr_r10: 310 m_context.R10 = reg_value.GetAsUInt32(); 311 break; 312 case gpr_r11: 313 m_context.R11 = reg_value.GetAsUInt32(); 314 break; 315 case gpr_r12: 316 m_context.R12 = reg_value.GetAsUInt32(); 317 break; 318 case gpr_sp: 319 m_context.Sp = reg_value.GetAsUInt32(); 320 break; 321 case gpr_lr: 322 m_context.Lr = reg_value.GetAsUInt32(); 323 break; 324 case gpr_pc: 325 m_context.Pc = reg_value.GetAsUInt32(); 326 break; 327 case gpr_cpsr: 328 m_context.Cpsr = reg_value.GetAsUInt32(); 329 break; 330 331 case fpu_s0: 332 case fpu_s1: 333 case fpu_s2: 334 case fpu_s3: 335 case fpu_s4: 336 case fpu_s5: 337 case fpu_s6: 338 case fpu_s7: 339 case fpu_s8: 340 case fpu_s9: 341 case fpu_s10: 342 case fpu_s11: 343 case fpu_s12: 344 case fpu_s13: 345 case fpu_s14: 346 case fpu_s15: 347 case fpu_s16: 348 case fpu_s17: 349 case fpu_s18: 350 case fpu_s19: 351 case fpu_s20: 352 case fpu_s21: 353 case fpu_s22: 354 case fpu_s23: 355 case fpu_s24: 356 case fpu_s25: 357 case fpu_s26: 358 case fpu_s27: 359 case fpu_s28: 360 case fpu_s29: 361 case fpu_s30: 362 case fpu_s31: 363 m_context.S[reg - fpu_s0] = reg_value.GetAsUInt32(); 364 break; 365 366 case fpu_d0: 367 case fpu_d1: 368 case fpu_d2: 369 case fpu_d3: 370 case fpu_d4: 371 case fpu_d5: 372 case fpu_d6: 373 case fpu_d7: 374 case fpu_d8: 375 case fpu_d9: 376 case fpu_d10: 377 case fpu_d11: 378 case fpu_d12: 379 case fpu_d13: 380 case fpu_d14: 381 case fpu_d15: 382 case fpu_d16: 383 case fpu_d17: 384 case fpu_d18: 385 case fpu_d19: 386 case fpu_d20: 387 case fpu_d21: 388 case fpu_d22: 389 case fpu_d23: 390 case fpu_d24: 391 case fpu_d25: 392 case fpu_d26: 393 case fpu_d27: 394 case fpu_d28: 395 case fpu_d29: 396 case fpu_d30: 397 case fpu_d31: 398 m_context.D[reg - fpu_d0] = reg_value.GetAsUInt64(); 399 break; 400 401 case fpu_q0: 402 case fpu_q1: 403 case fpu_q2: 404 case fpu_q3: 405 case fpu_q4: 406 case fpu_q5: 407 case fpu_q6: 408 case fpu_q7: 409 case fpu_q8: 410 case fpu_q9: 411 case fpu_q10: 412 case fpu_q11: 413 case fpu_q12: 414 case fpu_q13: 415 case fpu_q14: 416 case fpu_q15: 417 memcpy(&m_context.Q[reg - fpu_q0], reg_value.GetBytes(), 16); 418 break; 419 420 case fpu_fpscr: 421 m_context.Fpscr = reg_value.GetAsUInt32(); 422 break; 423 424 default: 425 return false; 426 } 427 428 // Physically update the registers in the target process. 429 return ApplyAllRegisterValues(); 430 } 431 432 #endif // defined(__arm__) || defined(_M_ARM) 433