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
21 using namespace lldb_private;
22 using namespace lldb;
23
24 enum
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.
82 enum
83 {
84 k_num_register_sets = 2
85 };
86
87 static const
88 uint32_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
111 static const uint32_t
112 g_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
141 static const RegisterSet
142 g_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
190 static RegisterInfo
191 g_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
244 static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
245 #endif
246
GetRegOffset(unsigned reg)247 static unsigned GetRegOffset(unsigned reg)
248 {
249 assert(reg < k_num_registers && "Invalid register number.");
250 return g_register_infos[reg].byte_offset;
251 }
252
GetRegSize(unsigned reg)253 static unsigned GetRegSize(unsigned reg)
254 {
255 assert(reg < k_num_registers && "Invalid register number.");
256 return g_register_infos[reg].byte_size;
257 }
258
RegisterContext_i386(Thread & thread,uint32_t concrete_frame_idx)259 RegisterContext_i386::RegisterContext_i386(Thread &thread,
260 uint32_t concrete_frame_idx)
261 : RegisterContextPOSIX(thread, concrete_frame_idx)
262 {
263 }
264
~RegisterContext_i386()265 RegisterContext_i386::~RegisterContext_i386()
266 {
267 }
268
269 ProcessMonitor &
GetMonitor()270 RegisterContext_i386::GetMonitor()
271 {
272 ProcessSP base = CalculateProcess();
273 ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
274 return process->GetMonitor();
275 }
276
277 void
Invalidate()278 RegisterContext_i386::Invalidate()
279 {
280 }
281
282 void
InvalidateAllRegisters()283 RegisterContext_i386::InvalidateAllRegisters()
284 {
285 }
286
287 size_t
GetRegisterCount()288 RegisterContext_i386::GetRegisterCount()
289 {
290 assert(k_num_register_infos == k_num_registers);
291 return k_num_registers;
292 }
293
294 const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)295 RegisterContext_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
304 size_t
GetRegisterSetCount()305 RegisterContext_i386::GetRegisterSetCount()
306 {
307 return k_num_register_sets;
308 }
309
310 const RegisterSet *
GetRegisterSet(size_t set)311 RegisterContext_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
319 unsigned
GetRegisterIndexFromOffset(unsigned offset)320 RegisterContext_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
332 const char *
GetRegisterName(unsigned reg)333 RegisterContext_i386::GetRegisterName(unsigned reg)
334 {
335 assert(reg < k_num_registers && "Invalid register offset.");
336 return g_register_infos[reg].name;
337 }
338
339 bool
ReadRegister(const RegisterInfo * reg_info,RegisterValue & value)340 RegisterContext_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
349 bool
ReadAllRegisterValues(DataBufferSP & data_sp)350 RegisterContext_i386::ReadAllRegisterValues(DataBufferSP &data_sp)
351 {
352 return false;
353 }
354
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)355 bool 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
364 bool
WriteAllRegisterValues(const DataBufferSP & data)365 RegisterContext_i386::WriteAllRegisterValues(const DataBufferSP &data)
366 {
367 return false;
368 }
369
370 bool
UpdateAfterBreakpoint()371 RegisterContext_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
383 uint32_t
ConvertRegisterKindToRegisterNumber(uint32_t kind,uint32_t num)384 RegisterContext_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
492 bool
HardwareSingleStep(bool enable)493 RegisterContext_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
519 void
LogGPR(const char * title)520 RegisterContext_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
535 bool
ReadGPR()536 RegisterContext_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
546 bool
ReadFPR()547 RegisterContext_i386::ReadFPR()
548 {
549 ProcessMonitor &monitor = GetMonitor();
550 return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
551 }
552