1//===-- RegisterContextPOSIX_i386.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 "lldb/Core/DataExtractor.h" 11#include "lldb/Target/Thread.h" 12#include "lldb/Host/Endian.h" 13#include "llvm/Support/Compiler.h" 14 15#include "ProcessPOSIX.h" 16#include "ProcessPOSIXLog.h" 17#include "ProcessMonitor.h" 18#include "RegisterContext_i386.h" 19#include "RegisterContext_x86.h" 20 21using namespace lldb_private; 22using namespace lldb; 23 24enum 25{ 26 k_first_gpr, 27 gpr_eax = k_first_gpr, 28 gpr_ebx, 29 gpr_ecx, 30 gpr_edx, 31 gpr_edi, 32 gpr_esi, 33 gpr_ebp, 34 gpr_esp, 35 gpr_ss, 36 gpr_eflags, 37#ifdef __FreeBSD__ 38 gpr_orig_ax, 39#endif 40 gpr_eip, 41 gpr_cs, 42 gpr_ds, 43 gpr_es, 44 gpr_fs, 45 gpr_gs, 46 k_last_gpr = gpr_gs, 47 48 k_first_fpr, 49 fpu_fcw = k_first_fpr, 50 fpu_fsw, 51 fpu_ftw, 52 fpu_fop, 53 fpu_ip, 54 fpu_cs, 55 fpu_foo, 56 fpu_fos, 57 fpu_mxcsr, 58 fpu_stmm0, 59 fpu_stmm1, 60 fpu_stmm2, 61 fpu_stmm3, 62 fpu_stmm4, 63 fpu_stmm5, 64 fpu_stmm6, 65 fpu_stmm7, 66 fpu_xmm0, 67 fpu_xmm1, 68 fpu_xmm2, 69 fpu_xmm3, 70 fpu_xmm4, 71 fpu_xmm5, 72 fpu_xmm6, 73 fpu_xmm7, 74 k_last_fpr = fpu_xmm7, 75 76 k_num_registers, 77 k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, 78 k_num_fpu_registers = k_last_fpr - k_first_fpr + 1 79}; 80 81// Number of register sets provided by this context. 82enum 83{ 84 k_num_register_sets = 2 85}; 86 87static const 88uint32_t g_gpr_regnums[k_num_gpr_registers] = 89{ 90 gpr_eax, 91 gpr_ebx, 92 gpr_ecx, 93 gpr_edx, 94 gpr_edi, 95 gpr_esi, 96 gpr_ebp, 97 gpr_esp, 98 gpr_ss, 99 gpr_eflags, 100#ifdef __FreeBSD__ 101 gpr_orig_ax, 102#endif 103 gpr_eip, 104 gpr_cs, 105 gpr_ds, 106 gpr_es, 107 gpr_fs, 108 gpr_gs, 109}; 110 111static const uint32_t 112g_fpu_regnums[k_num_fpu_registers] = 113{ 114 fpu_fcw, 115 fpu_fsw, 116 fpu_ftw, 117 fpu_fop, 118 fpu_ip, 119 fpu_cs, 120 fpu_foo, 121 fpu_fos, 122 fpu_mxcsr, 123 fpu_stmm0, 124 fpu_stmm1, 125 fpu_stmm2, 126 fpu_stmm3, 127 fpu_stmm4, 128 fpu_stmm5, 129 fpu_stmm6, 130 fpu_stmm7, 131 fpu_xmm0, 132 fpu_xmm1, 133 fpu_xmm2, 134 fpu_xmm3, 135 fpu_xmm4, 136 fpu_xmm5, 137 fpu_xmm6, 138 fpu_xmm7, 139}; 140 141static const RegisterSet 142g_reg_sets[k_num_register_sets] = 143{ 144 { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums }, 145 { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums } 146}; 147 148// Computes the offset of the given GPR in the user data area. 149#define GPR_OFFSET(regname) \ 150 (offsetof(RegisterContext_i386::UserArea, regs) + \ 151 offsetof(RegisterContext_i386::GPR, regname)) 152 153// Computes the offset of the given FPR in the user data area. 154#define FPR_OFFSET(regname) \ 155 (offsetof(RegisterContext_i386::UserArea, i387) + \ 156 offsetof(RegisterContext_i386::FPU, regname)) 157 158// Number of bytes needed to represent a GPR. 159#define GPR_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg) 160 161// Number of bytes needed to represent a FPR. 162#define FPR_SIZE(reg) sizeof(((RegisterContext_i386::FPU*)NULL)->reg) 163 164// Number of bytes needed to represent the i'th FP register. 165#define FP_SIZE sizeof(((RegisterContext_i386::MMSReg*)NULL)->bytes) 166 167// Number of bytes needed to represent an XMM register. 168#define XMM_SIZE sizeof(RegisterContext_i386::XMMReg) 169 170#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ 171 { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \ 172 eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg }, NULL, NULL } 173 174#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \ 175 { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ 176 eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg }, NULL, NULL } 177 178#define DEFINE_FP(reg, i) \ 179 { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \ 180 eEncodingVector, eFormatVectorOfUInt8, \ 181 { dwarf_##reg##i, dwarf_##reg##i, \ 182 LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i }, NULL, NULL } 183 184#define DEFINE_XMM(reg, i) \ 185 { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \ 186 eEncodingVector, eFormatVectorOfUInt8, \ 187 { dwarf_##reg##i, dwarf_##reg##i, \ 188 LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i }, NULL, NULL } 189 190static RegisterInfo 191g_register_infos[k_num_registers] = 192{ 193 // General purpose registers. 194 DEFINE_GPR(eax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax), 195 DEFINE_GPR(ebx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx), 196 DEFINE_GPR(ecx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx), 197 DEFINE_GPR(edx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx), 198 DEFINE_GPR(edi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi), 199 DEFINE_GPR(esi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi), 200 DEFINE_GPR(ebp, "fp", gcc_ebp, dwarf_ebp, LLDB_INVALID_REGNUM, gdb_ebp), 201 DEFINE_GPR(esp, "sp", gcc_esp, dwarf_esp, LLDB_INVALID_REGNUM, gdb_esp), 202 DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ss), 203 DEFINE_GPR(eflags, "flags", gcc_eflags, dwarf_eflags, LLDB_INVALID_REGNUM, gdb_eflags), 204 DEFINE_GPR(eip, "pc", gcc_eip, dwarf_eip, LLDB_INVALID_REGNUM, gdb_eip), 205 DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_cs), 206 DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ds), 207 DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_es), 208 DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fs), 209 DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gs), 210 211 // Floating point registers. 212 DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fcw), 213 DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fsw), 214 DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftw), 215 DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop), 216 DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ip), 217 DEFINE_FPR(cs, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs), 218 DEFINE_FPR(foo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_dp), 219 DEFINE_FPR(fos, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds), 220 DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_mxcsr), 221 222 DEFINE_FP(stmm, 0), 223 DEFINE_FP(stmm, 1), 224 DEFINE_FP(stmm, 2), 225 DEFINE_FP(stmm, 3), 226 DEFINE_FP(stmm, 4), 227 DEFINE_FP(stmm, 5), 228 DEFINE_FP(stmm, 6), 229 DEFINE_FP(stmm, 7), 230 231 // XMM registers 232 DEFINE_XMM(xmm, 0), 233 DEFINE_XMM(xmm, 1), 234 DEFINE_XMM(xmm, 2), 235 DEFINE_XMM(xmm, 3), 236 DEFINE_XMM(xmm, 4), 237 DEFINE_XMM(xmm, 5), 238 DEFINE_XMM(xmm, 6), 239 DEFINE_XMM(xmm, 7), 240 241}; 242 243#ifndef NDEBUG 244static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); 245#endif 246 247static unsigned GetRegOffset(unsigned reg) 248{ 249 assert(reg < k_num_registers && "Invalid register number."); 250 return g_register_infos[reg].byte_offset; 251} 252 253static unsigned GetRegSize(unsigned reg) 254{ 255 assert(reg < k_num_registers && "Invalid register number."); 256 return g_register_infos[reg].byte_size; 257} 258 259RegisterContext_i386::RegisterContext_i386(Thread &thread, 260 uint32_t concrete_frame_idx) 261 : RegisterContextPOSIX(thread, concrete_frame_idx) 262{ 263} 264 265RegisterContext_i386::~RegisterContext_i386() 266{ 267} 268 269ProcessMonitor & 270RegisterContext_i386::GetMonitor() 271{ 272 ProcessSP base = CalculateProcess(); 273 ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); 274 return process->GetMonitor(); 275} 276 277void 278RegisterContext_i386::Invalidate() 279{ 280} 281 282void 283RegisterContext_i386::InvalidateAllRegisters() 284{ 285} 286 287size_t 288RegisterContext_i386::GetRegisterCount() 289{ 290 assert(k_num_register_infos == k_num_registers); 291 return k_num_registers; 292} 293 294const RegisterInfo * 295RegisterContext_i386::GetRegisterInfoAtIndex(size_t reg) 296{ 297 assert(k_num_register_infos == k_num_registers); 298 if (reg < k_num_registers) 299 return &g_register_infos[reg]; 300 else 301 return NULL; 302} 303 304size_t 305RegisterContext_i386::GetRegisterSetCount() 306{ 307 return k_num_register_sets; 308} 309 310const RegisterSet * 311RegisterContext_i386::GetRegisterSet(size_t set) 312{ 313 if (set < k_num_register_sets) 314 return &g_reg_sets[set]; 315 else 316 return NULL; 317} 318 319unsigned 320RegisterContext_i386::GetRegisterIndexFromOffset(unsigned offset) 321{ 322 unsigned reg; 323 for (reg = 0; reg < k_num_registers; reg++) 324 { 325 if (g_register_infos[reg].byte_offset == offset) 326 break; 327 } 328 assert(reg < k_num_registers && "Invalid register offset."); 329 return reg; 330} 331 332const char * 333RegisterContext_i386::GetRegisterName(unsigned reg) 334{ 335 assert(reg < k_num_registers && "Invalid register offset."); 336 return g_register_infos[reg].name; 337} 338 339bool 340RegisterContext_i386::ReadRegister(const RegisterInfo *reg_info, 341 RegisterValue &value) 342{ 343 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 344 ProcessMonitor &monitor = GetMonitor(); 345 return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg), 346 GetRegisterName(reg), GetRegSize(reg), value); 347} 348 349bool 350RegisterContext_i386::ReadAllRegisterValues(DataBufferSP &data_sp) 351{ 352 return false; 353} 354 355bool RegisterContext_i386::WriteRegister(const RegisterInfo *reg_info, 356 const RegisterValue &value) 357{ 358 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 359 ProcessMonitor &monitor = GetMonitor(); 360 return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), 361 GetRegisterName(reg), value); 362} 363 364bool 365RegisterContext_i386::WriteAllRegisterValues(const DataBufferSP &data) 366{ 367 return false; 368} 369 370bool 371RegisterContext_i386::UpdateAfterBreakpoint() 372{ 373 // PC points one byte past the int3 responsible for the breakpoint. 374 lldb::addr_t pc; 375 376 if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) 377 return false; 378 379 SetPC(pc - 1); 380 return true; 381} 382 383uint32_t 384RegisterContext_i386::ConvertRegisterKindToRegisterNumber(uint32_t kind, 385 uint32_t num) 386{ 387 if (kind == eRegisterKindGeneric) 388 { 389 switch (num) 390 { 391 case LLDB_REGNUM_GENERIC_PC: return gpr_eip; 392 case LLDB_REGNUM_GENERIC_SP: return gpr_esp; 393 case LLDB_REGNUM_GENERIC_FP: return gpr_ebp; 394 case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags; 395 case LLDB_REGNUM_GENERIC_RA: 396 default: 397 return LLDB_INVALID_REGNUM; 398 } 399 } 400 401 if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF) 402 { 403 switch (num) 404 { 405 case dwarf_eax: return gpr_eax; 406 case dwarf_edx: return gpr_edx; 407 case dwarf_ecx: return gpr_ecx; 408 case dwarf_ebx: return gpr_ebx; 409 case dwarf_esi: return gpr_esi; 410 case dwarf_edi: return gpr_edi; 411 case dwarf_ebp: return gpr_ebp; 412 case dwarf_esp: return gpr_esp; 413 case dwarf_eip: return gpr_eip; 414 case dwarf_xmm0: return fpu_xmm0; 415 case dwarf_xmm1: return fpu_xmm1; 416 case dwarf_xmm2: return fpu_xmm2; 417 case dwarf_xmm3: return fpu_xmm3; 418 case dwarf_xmm4: return fpu_xmm4; 419 case dwarf_xmm5: return fpu_xmm5; 420 case dwarf_xmm6: return fpu_xmm6; 421 case dwarf_xmm7: return fpu_xmm7; 422 case dwarf_stmm0: return fpu_stmm0; 423 case dwarf_stmm1: return fpu_stmm1; 424 case dwarf_stmm2: return fpu_stmm2; 425 case dwarf_stmm3: return fpu_stmm3; 426 case dwarf_stmm4: return fpu_stmm4; 427 case dwarf_stmm5: return fpu_stmm5; 428 case dwarf_stmm6: return fpu_stmm6; 429 case dwarf_stmm7: return fpu_stmm7; 430 default: 431 return LLDB_INVALID_REGNUM; 432 } 433 } 434 435 if (kind == eRegisterKindGDB) 436 { 437 switch (num) 438 { 439 case gdb_eax : return gpr_eax; 440 case gdb_ebx : return gpr_ebx; 441 case gdb_ecx : return gpr_ecx; 442 case gdb_edx : return gpr_edx; 443 case gdb_esi : return gpr_esi; 444 case gdb_edi : return gpr_edi; 445 case gdb_ebp : return gpr_ebp; 446 case gdb_esp : return gpr_esp; 447 case gdb_eip : return gpr_eip; 448 case gdb_eflags : return gpr_eflags; 449 case gdb_cs : return gpr_cs; 450 case gdb_ss : return gpr_ss; 451 case gdb_ds : return gpr_ds; 452 case gdb_es : return gpr_es; 453 case gdb_fs : return gpr_fs; 454 case gdb_gs : return gpr_gs; 455 case gdb_stmm0 : return fpu_stmm0; 456 case gdb_stmm1 : return fpu_stmm1; 457 case gdb_stmm2 : return fpu_stmm2; 458 case gdb_stmm3 : return fpu_stmm3; 459 case gdb_stmm4 : return fpu_stmm4; 460 case gdb_stmm5 : return fpu_stmm5; 461 case gdb_stmm6 : return fpu_stmm6; 462 case gdb_stmm7 : return fpu_stmm7; 463 case gdb_fcw : return fpu_fcw; 464 case gdb_fsw : return fpu_fsw; 465 case gdb_ftw : return fpu_ftw; 466 case gdb_fpu_cs : return fpu_cs; 467 case gdb_ip : return fpu_ip; 468 case gdb_fpu_ds : return fpu_fos; 469 case gdb_dp : return fpu_foo; 470 case gdb_fop : return fpu_fop; 471 case gdb_xmm0 : return fpu_xmm0; 472 case gdb_xmm1 : return fpu_xmm1; 473 case gdb_xmm2 : return fpu_xmm2; 474 case gdb_xmm3 : return fpu_xmm3; 475 case gdb_xmm4 : return fpu_xmm4; 476 case gdb_xmm5 : return fpu_xmm5; 477 case gdb_xmm6 : return fpu_xmm6; 478 case gdb_xmm7 : return fpu_xmm7; 479 case gdb_mxcsr : return fpu_mxcsr; 480 default: 481 return LLDB_INVALID_REGNUM; 482 } 483 } 484 else if (kind == eRegisterKindLLDB) 485 { 486 return num; 487 } 488 489 return LLDB_INVALID_REGNUM; 490} 491 492bool 493RegisterContext_i386::HardwareSingleStep(bool enable) 494{ 495 enum { TRACE_BIT = 0x100 }; 496 uint64_t eflags; 497 498 if ((eflags = ReadRegisterAsUnsigned(gpr_eflags, -1UL)) == -1UL) 499 return false; 500 501 if (enable) 502 { 503 if (eflags & TRACE_BIT) 504 return true; 505 506 eflags |= TRACE_BIT; 507 } 508 else 509 { 510 if (!(eflags & TRACE_BIT)) 511 return false; 512 513 eflags &= ~TRACE_BIT; 514 } 515 516 return WriteRegisterFromUnsigned(gpr_eflags, eflags); 517} 518 519void 520RegisterContext_i386::LogGPR(const char *title) 521{ 522 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); 523 if (log) 524 { 525 if (title) 526 log->Printf ("%s", title); 527 for (uint32_t i=0; i<k_num_gpr_registers; i++) 528 { 529 uint32_t reg = gpr_eax + i; 530 log->Printf("%12s = 0x%8.8" PRIx64, g_register_infos[reg].name, ((uint64_t*)&user.regs)[reg]); 531 } 532 } 533} 534 535bool 536RegisterContext_i386::ReadGPR() 537{ 538 bool result; 539 540 ProcessMonitor &monitor = GetMonitor(); 541 result = monitor.ReadGPR(m_thread.GetID(), &user.regs, sizeof(user.regs)); 542 LogGPR("RegisterContext_i386::ReadGPR()"); 543 return result; 544} 545 546bool 547RegisterContext_i386::ReadFPR() 548{ 549 ProcessMonitor &monitor = GetMonitor(); 550 return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387)); 551} 552