• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- RegisterContextLinux_x86_64.h --------------------------*- 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 "llvm/Support/Compiler.h"
11 #include "RegisterContextLinux_x86_64.h"
12 #include <vector>
13 
14 using namespace lldb_private;
15 
16 // Computes the offset of the given GPR in the user data area.
17 #define GPR_OFFSET(regname)                                                 \
18     (offsetof(GPR, regname))
19 
20 // Update the Linux specific information (offset and size).
21 #define UPDATE_GPR_INFO(reg)                                                \
22 do {                                                                        \
23     GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg);               \
24     GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
25 } while(false);
26 
27 #define UPDATE_I386_GPR_INFO(i386_reg, reg)                                 \
28 do {                                                                        \
29     GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
30 } while(false);
31 
32 #define DR_OFFSET(reg_index)                                                \
33     (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
34 
35 #define UPDATE_DR_INFO(reg_index)                                                \
36 do {                                                                             \
37     GetRegisterContext()[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \
38     GetRegisterContext()[dr##reg_index].byte_offset = DR_OFFSET(reg_index);          \
39 } while(false);
40 
41 typedef struct _GPR
42 {
43     uint64_t r15;
44     uint64_t r14;
45     uint64_t r13;
46     uint64_t r12;
47     uint64_t rbp;
48     uint64_t rbx;
49     uint64_t r11;
50     uint64_t r10;
51     uint64_t r9;
52     uint64_t r8;
53     uint64_t rax;
54     uint64_t rcx;
55     uint64_t rdx;
56     uint64_t rsi;
57     uint64_t rdi;
58     uint64_t orig_ax;
59     uint64_t rip;
60     uint64_t cs;
61     uint64_t rflags;
62     uint64_t rsp;
63     uint64_t ss;
64     uint64_t fs_base;
65     uint64_t gs_base;
66     uint64_t ds;
67     uint64_t es;
68     uint64_t fs;
69     uint64_t gs;
70 } GPR;
71 
72 typedef RegisterContext_x86_64::FXSAVE FXSAVE;
73 
74 struct UserArea
75 {
76     GPR      gpr;           // General purpose registers.
77     int32_t  fpvalid;       // True if FPU is being used.
78     int32_t  pad0;
79     FXSAVE   i387;          // General purpose floating point registers (see FPR for extended register sets).
80     uint64_t tsize;         // Text segment size.
81     uint64_t dsize;         // Data segment size.
82     uint64_t ssize;         // Stack segment size.
83     uint64_t start_code;    // VM address of text.
84     uint64_t start_stack;   // VM address of stack bottom (top in rsp).
85     int64_t  signal;        // Signal causing core dump.
86     int32_t  reserved;      // Unused.
87     int32_t  pad1;
88     uint64_t ar0;           // Location of GPR's.
89     FXSAVE*  fpstate;       // Location of FPR's.
90     uint64_t magic;         // Identifier for core dumps.
91     char     u_comm[32];    // Command causing core dump.
92     uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7).
93     uint64_t error_code;    // CPU error code.
94     uint64_t fault_address; // Control register CR3.
95 };
96 
97 // Use a singleton function to avoid global constructors in shared libraries.
GetRegisterContext()98 static std::vector<RegisterInfo> & GetRegisterContext () {
99     static std::vector<RegisterInfo> g_register_infos;
100     return g_register_infos;
101 }
102 
RegisterContextLinux_x86_64(Thread & thread,uint32_t concrete_frame_idx)103 RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx):
104     RegisterContext_x86_64(thread, concrete_frame_idx)
105 {
106 }
107 
108 size_t
GetGPRSize()109 RegisterContextLinux_x86_64::GetGPRSize()
110 {
111     return sizeof(GPR);
112 }
113 
114 const RegisterInfo *
GetRegisterInfo()115 RegisterContextLinux_x86_64::GetRegisterInfo()
116 {
117     // Allocate RegisterInfo only once
118     if (GetRegisterContext().empty())
119     {
120         // Copy the register information from base class
121         const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo();
122         if (base_info)
123         {
124             GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]);
125             // Update the Linux specific register information (offset and size).
126             UpdateRegisterInfo();
127         }
128     }
129     return &GetRegisterContext()[0];
130 }
131 
132 void
UpdateRegisterInfo()133 RegisterContextLinux_x86_64::UpdateRegisterInfo()
134 {
135     UPDATE_GPR_INFO(rax);
136     UPDATE_GPR_INFO(rbx);
137     UPDATE_GPR_INFO(rcx);
138     UPDATE_GPR_INFO(rdx);
139     UPDATE_GPR_INFO(rdi);
140     UPDATE_GPR_INFO(rsi);
141     UPDATE_GPR_INFO(rbp);
142     UPDATE_GPR_INFO(rsp);
143     UPDATE_GPR_INFO(r8);
144     UPDATE_GPR_INFO(r9);
145     UPDATE_GPR_INFO(r10);
146     UPDATE_GPR_INFO(r11);
147     UPDATE_GPR_INFO(r12);
148     UPDATE_GPR_INFO(r13);
149     UPDATE_GPR_INFO(r14);
150     UPDATE_GPR_INFO(r15);
151     UPDATE_GPR_INFO(rip);
152     UPDATE_GPR_INFO(rflags);
153     UPDATE_GPR_INFO(cs);
154     UPDATE_GPR_INFO(fs);
155     UPDATE_GPR_INFO(gs);
156     UPDATE_GPR_INFO(ss);
157     UPDATE_GPR_INFO(ds);
158     UPDATE_GPR_INFO(es);
159 
160     UPDATE_I386_GPR_INFO(eax, rax);
161     UPDATE_I386_GPR_INFO(ebx, rbx);
162     UPDATE_I386_GPR_INFO(ecx, rcx);
163     UPDATE_I386_GPR_INFO(edx, rdx);
164     UPDATE_I386_GPR_INFO(edi, rdi);
165     UPDATE_I386_GPR_INFO(esi, rsi);
166     UPDATE_I386_GPR_INFO(ebp, rbp);
167     UPDATE_I386_GPR_INFO(esp, rsp);
168     UPDATE_I386_GPR_INFO(eip, rip);
169     UPDATE_I386_GPR_INFO(eflags, rflags);
170 
171     UPDATE_DR_INFO(0);
172     UPDATE_DR_INFO(1);
173     UPDATE_DR_INFO(2);
174     UPDATE_DR_INFO(3);
175     UPDATE_DR_INFO(4);
176     UPDATE_DR_INFO(5);
177     UPDATE_DR_INFO(6);
178     UPDATE_DR_INFO(7);
179 }
180 
181