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