]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Plugins / Process / POSIX / RegisterContext_i386.cpp
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
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
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
259 RegisterContext_i386::RegisterContext_i386(Thread &thread,
260                                                      uint32_t concrete_frame_idx)
261     : RegisterContextPOSIX(thread, concrete_frame_idx)
262 {
263 }
264
265 RegisterContext_i386::~RegisterContext_i386()
266 {
267 }
268
269 ProcessMonitor &
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
278 RegisterContext_i386::Invalidate()
279 {
280 }
281
282 void
283 RegisterContext_i386::InvalidateAllRegisters()
284 {
285 }
286
287 size_t
288 RegisterContext_i386::GetRegisterCount()
289 {
290     assert(k_num_register_infos == k_num_registers);
291     return k_num_registers;
292 }
293
294 const RegisterInfo *
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
305 RegisterContext_i386::GetRegisterSetCount()
306 {
307     return k_num_register_sets;
308 }
309
310 const RegisterSet *
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
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 *
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
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
350 RegisterContext_i386::ReadAllRegisterValues(DataBufferSP &data_sp)
351 {
352     return false;
353 }
354
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
365 RegisterContext_i386::WriteAllRegisterValues(const DataBufferSP &data)
366 {
367     return false;
368 }
369
370 bool
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
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
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
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
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
547 RegisterContext_i386::ReadFPR()
548 {
549     ProcessMonitor &monitor = GetMonitor();
550     return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
551 }