1254721Semaste//===-- RegisterContextLinux_x86_64.h --------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===---------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "llvm/Support/Compiler.h"
11254721Semaste#include "RegisterContextLinux_x86_64.h"
12254721Semaste#include <vector>
13254721Semaste
14254721Semasteusing namespace lldb_private;
15254721Semaste
16254721Semaste// Computes the offset of the given GPR in the user data area.
17254721Semaste#define GPR_OFFSET(regname)                                                 \
18254721Semaste    (offsetof(GPR, regname))
19254721Semaste
20254721Semaste// Update the Linux specific information (offset and size).
21254721Semaste#define UPDATE_GPR_INFO(reg)                                                \
22254721Semastedo {                                                                        \
23254721Semaste    GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg);               \
24254721Semaste    GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
25254721Semaste} while(false);
26254721Semaste
27254721Semaste#define UPDATE_I386_GPR_INFO(i386_reg, reg)                                 \
28254721Semastedo {                                                                        \
29254721Semaste    GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
30254721Semaste} while(false);
31254721Semaste
32254721Semaste#define DR_OFFSET(reg_index)                                                \
33254721Semaste    (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
34254721Semaste
35254721Semaste#define UPDATE_DR_INFO(reg_index)                                                \
36254721Semastedo {                                                                             \
37254721Semaste    GetRegisterContext()[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \
38254721Semaste    GetRegisterContext()[dr##reg_index].byte_offset = DR_OFFSET(reg_index);          \
39254721Semaste} while(false);
40254721Semaste
41254721Semastetypedef struct _GPR
42254721Semaste{
43254721Semaste    uint64_t r15;
44254721Semaste    uint64_t r14;
45254721Semaste    uint64_t r13;
46254721Semaste    uint64_t r12;
47254721Semaste    uint64_t rbp;
48254721Semaste    uint64_t rbx;
49254721Semaste    uint64_t r11;
50254721Semaste    uint64_t r10;
51254721Semaste    uint64_t r9;
52254721Semaste    uint64_t r8;
53254721Semaste    uint64_t rax;
54254721Semaste    uint64_t rcx;
55254721Semaste    uint64_t rdx;
56254721Semaste    uint64_t rsi;
57254721Semaste    uint64_t rdi;
58254721Semaste    uint64_t orig_ax;
59254721Semaste    uint64_t rip;
60254721Semaste    uint64_t cs;
61254721Semaste    uint64_t rflags;
62254721Semaste    uint64_t rsp;
63254721Semaste    uint64_t ss;
64254721Semaste    uint64_t fs_base;
65254721Semaste    uint64_t gs_base;
66254721Semaste    uint64_t ds;
67254721Semaste    uint64_t es;
68254721Semaste    uint64_t fs;
69254721Semaste    uint64_t gs;
70254721Semaste} GPR;
71254721Semaste
72254721Semastetypedef RegisterContext_x86_64::FXSAVE FXSAVE;
73254721Semaste
74254721Semastestruct UserArea
75254721Semaste{
76254721Semaste    GPR      gpr;           // General purpose registers.
77254721Semaste    int32_t  fpvalid;       // True if FPU is being used.
78254721Semaste    int32_t  pad0;
79254721Semaste    FXSAVE   i387;          // General purpose floating point registers (see FPR for extended register sets).
80254721Semaste    uint64_t tsize;         // Text segment size.
81254721Semaste    uint64_t dsize;         // Data segment size.
82254721Semaste    uint64_t ssize;         // Stack segment size.
83254721Semaste    uint64_t start_code;    // VM address of text.
84254721Semaste    uint64_t start_stack;   // VM address of stack bottom (top in rsp).
85254721Semaste    int64_t  signal;        // Signal causing core dump.
86254721Semaste    int32_t  reserved;      // Unused.
87254721Semaste    int32_t  pad1;
88254721Semaste    uint64_t ar0;           // Location of GPR's.
89254721Semaste    FXSAVE*  fpstate;       // Location of FPR's.
90254721Semaste    uint64_t magic;         // Identifier for core dumps.
91254721Semaste    char     u_comm[32];    // Command causing core dump.
92254721Semaste    uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7).
93254721Semaste    uint64_t error_code;    // CPU error code.
94254721Semaste    uint64_t fault_address; // Control register CR3.
95254721Semaste};
96254721Semaste
97254721Semaste// Use a singleton function to avoid global constructors in shared libraries.
98254721Semastestatic std::vector<RegisterInfo> & GetRegisterContext () {
99254721Semaste    static std::vector<RegisterInfo> g_register_infos;
100254721Semaste    return g_register_infos;
101254721Semaste}
102254721Semaste
103254721SemasteRegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx):
104254721Semaste    RegisterContext_x86_64(thread, concrete_frame_idx)
105254721Semaste{
106254721Semaste}
107254721Semaste
108254721Semastesize_t
109254721SemasteRegisterContextLinux_x86_64::GetGPRSize()
110254721Semaste{
111254721Semaste    return sizeof(GPR);
112254721Semaste}
113254721Semaste
114254721Semasteconst RegisterInfo *
115254721SemasteRegisterContextLinux_x86_64::GetRegisterInfo()
116254721Semaste{
117254721Semaste    // Allocate RegisterInfo only once
118254721Semaste    if (GetRegisterContext().empty())
119254721Semaste    {
120254721Semaste        // Copy the register information from base class
121254721Semaste        const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo();
122254721Semaste        if (base_info)
123254721Semaste        {
124254721Semaste            GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]);
125254721Semaste            // Update the Linux specific register information (offset and size).
126254721Semaste            UpdateRegisterInfo();
127254721Semaste        }
128254721Semaste    }
129254721Semaste    return &GetRegisterContext()[0];
130254721Semaste}
131254721Semaste
132254721Semastevoid
133254721SemasteRegisterContextLinux_x86_64::UpdateRegisterInfo()
134254721Semaste{
135254721Semaste    UPDATE_GPR_INFO(rax);
136254721Semaste    UPDATE_GPR_INFO(rbx);
137254721Semaste    UPDATE_GPR_INFO(rcx);
138254721Semaste    UPDATE_GPR_INFO(rdx);
139254721Semaste    UPDATE_GPR_INFO(rdi);
140254721Semaste    UPDATE_GPR_INFO(rsi);
141254721Semaste    UPDATE_GPR_INFO(rbp);
142254721Semaste    UPDATE_GPR_INFO(rsp);
143254721Semaste    UPDATE_GPR_INFO(r8);
144254721Semaste    UPDATE_GPR_INFO(r9);
145254721Semaste    UPDATE_GPR_INFO(r10);
146254721Semaste    UPDATE_GPR_INFO(r11);
147254721Semaste    UPDATE_GPR_INFO(r12);
148254721Semaste    UPDATE_GPR_INFO(r13);
149254721Semaste    UPDATE_GPR_INFO(r14);
150254721Semaste    UPDATE_GPR_INFO(r15);
151254721Semaste    UPDATE_GPR_INFO(rip);
152254721Semaste    UPDATE_GPR_INFO(rflags);
153254721Semaste    UPDATE_GPR_INFO(cs);
154254721Semaste    UPDATE_GPR_INFO(fs);
155254721Semaste    UPDATE_GPR_INFO(gs);
156254721Semaste    UPDATE_GPR_INFO(ss);
157254721Semaste    UPDATE_GPR_INFO(ds);
158254721Semaste    UPDATE_GPR_INFO(es);
159254721Semaste
160254721Semaste    UPDATE_I386_GPR_INFO(eax, rax);
161254721Semaste    UPDATE_I386_GPR_INFO(ebx, rbx);
162254721Semaste    UPDATE_I386_GPR_INFO(ecx, rcx);
163254721Semaste    UPDATE_I386_GPR_INFO(edx, rdx);
164254721Semaste    UPDATE_I386_GPR_INFO(edi, rdi);
165254721Semaste    UPDATE_I386_GPR_INFO(esi, rsi);
166254721Semaste    UPDATE_I386_GPR_INFO(ebp, rbp);
167254721Semaste    UPDATE_I386_GPR_INFO(esp, rsp);
168254721Semaste    UPDATE_I386_GPR_INFO(eip, rip);
169254721Semaste    UPDATE_I386_GPR_INFO(eflags, rflags);
170254721Semaste
171254721Semaste    UPDATE_DR_INFO(0);
172254721Semaste    UPDATE_DR_INFO(1);
173254721Semaste    UPDATE_DR_INFO(2);
174254721Semaste    UPDATE_DR_INFO(3);
175254721Semaste    UPDATE_DR_INFO(4);
176254721Semaste    UPDATE_DR_INFO(5);
177254721Semaste    UPDATE_DR_INFO(6);
178254721Semaste    UPDATE_DR_INFO(7);
179254721Semaste}
180254721Semaste
181