]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
Upgrade to OpenSSH 6.9p1.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / RegisterContextLinux_x86_64.cpp
1 //===-- RegisterContextLinux_x86_64.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 <vector>
11 #include "RegisterContextPOSIX_x86.h"
12 #include "RegisterContextLinux_i386.h"
13 #include "RegisterContextLinux_x86_64.h"
14
15 using namespace lldb_private;
16 using namespace lldb;
17
18 typedef struct _GPR
19 {
20     uint64_t r15;
21     uint64_t r14;
22     uint64_t r13;
23     uint64_t r12;
24     uint64_t rbp;
25     uint64_t rbx;
26     uint64_t r11;
27     uint64_t r10;
28     uint64_t r9;
29     uint64_t r8;
30     uint64_t rax;
31     uint64_t rcx;
32     uint64_t rdx;
33     uint64_t rsi;
34     uint64_t rdi;
35     uint64_t orig_ax;
36     uint64_t rip;
37     uint64_t cs;
38     uint64_t rflags;
39     uint64_t rsp;
40     uint64_t ss;
41     uint64_t fs_base;
42     uint64_t gs_base;
43     uint64_t ds;
44     uint64_t es;
45     uint64_t fs;
46     uint64_t gs;
47 } GPR;
48
49 struct DBG {
50     uint64_t dr[8];
51 };
52
53 struct UserArea
54 {
55     GPR      gpr;           // General purpose registers.
56     int32_t  fpvalid;       // True if FPU is being used.
57     int32_t  pad0;
58     FXSAVE   fpr;           // General purpose floating point registers (see FPR for extended register sets).
59     uint64_t tsize;         // Text segment size.
60     uint64_t dsize;         // Data segment size.
61     uint64_t ssize;         // Stack segment size.
62     uint64_t start_code;    // VM address of text.
63     uint64_t start_stack;   // VM address of stack bottom (top in rsp).
64     int64_t  signal;        // Signal causing core dump.
65     int32_t  reserved;      // Unused.
66     int32_t  pad1;
67     uint64_t ar0;           // Location of GPR's.
68     FXSAVE*  fpstate;       // Location of FPR's.
69     uint64_t magic;         // Identifier for core dumps.
70     char     u_comm[32];    // Command causing core dump.
71     DBG      dbg;           // Debug registers.
72     uint64_t error_code;    // CPU error code.
73     uint64_t fault_address; // Control register CR3.
74 };
75
76
77 #define DR_OFFSET(reg_index) \
78     (LLVM_EXTENSION offsetof(UserArea, dbg) + \
79      LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
80
81 //---------------------------------------------------------------------------
82 // Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
83 //---------------------------------------------------------------------------
84 #define DECLARE_REGISTER_INFOS_X86_64_STRUCT
85 #include "RegisterInfos_x86_64.h"
86 #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
87
88 static std::vector<lldb_private::RegisterInfo>&
89 GetPrivateRegisterInfoVector ()
90 {
91     static std::vector<lldb_private::RegisterInfo> g_register_infos;
92     return g_register_infos;
93 }
94
95 static const RegisterInfo *
96 GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
97 {
98     std::vector<lldb_private::RegisterInfo> &g_register_infos = GetPrivateRegisterInfoVector ();
99
100     // Allocate RegisterInfo only once
101     if (g_register_infos.empty())
102     {
103         // Copy the register information from base class
104         std::unique_ptr<RegisterContextLinux_i386> reg_interface(new RegisterContextLinux_i386 (arch));
105         const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
106         g_register_infos.insert(g_register_infos.end(), &base_info[0], &base_info[k_num_registers_i386]);
107
108         //---------------------------------------------------------------------------
109         // Include RegisterInfos_x86_64 to update the g_register_infos structure
110         //  with x86_64 offsets.
111         //---------------------------------------------------------------------------
112         #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
113         #include "RegisterInfos_x86_64.h"
114         #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
115     }
116
117     return &g_register_infos[0];
118 }
119
120 static const RegisterInfo *
121 GetRegisterInfoPtr (const ArchSpec &target_arch)
122 {
123     switch (target_arch.GetMachine())
124     {
125         case llvm::Triple::x86:
126             return GetRegisterInfo_i386 (target_arch);
127         case llvm::Triple::x86_64:
128             return g_register_infos_x86_64;
129         default:
130             assert(false && "Unhandled target architecture.");
131             return nullptr;
132     }
133 }
134
135 static uint32_t
136 GetRegisterInfoCount (const ArchSpec &target_arch)
137 {
138     switch (target_arch.GetMachine())
139     {
140         case llvm::Triple::x86:
141             {
142                 assert (!GetPrivateRegisterInfoVector ().empty () && "i386 register info not yet filled.");
143                 return static_cast<uint32_t> (GetPrivateRegisterInfoVector ().size ());
144             }
145         case llvm::Triple::x86_64:
146             return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
147         default:
148             assert(false && "Unhandled target architecture.");
149             return 0;
150     }
151 }
152
153 static uint32_t
154 GetUserRegisterInfoCount (const ArchSpec &target_arch)
155 {
156     switch (target_arch.GetMachine())
157     {
158         case llvm::Triple::x86:
159             return static_cast<uint32_t> (k_num_user_registers_i386);
160         case llvm::Triple::x86_64:
161             return static_cast<uint32_t> (k_num_user_registers_x86_64);
162         default:
163             assert(false && "Unhandled target architecture.");
164             return 0;
165     }
166 }
167
168 RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
169     lldb_private::RegisterInfoInterface(target_arch),
170     m_register_info_p (GetRegisterInfoPtr (target_arch)),
171     m_register_info_count (GetRegisterInfoCount (target_arch)),
172     m_user_register_count (GetUserRegisterInfoCount (target_arch))
173 {
174 }
175
176 size_t
177 RegisterContextLinux_x86_64::GetGPRSize() const
178 {
179     return sizeof(GPR);
180 }
181
182 const RegisterInfo *
183 RegisterContextLinux_x86_64::GetRegisterInfo() const
184 {
185     return m_register_info_p;
186 }
187
188 uint32_t
189 RegisterContextLinux_x86_64::GetRegisterCount () const
190 {
191     return m_register_info_count;
192 }
193
194 uint32_t
195 RegisterContextLinux_x86_64::GetUserRegisterCount () const
196 {
197     return m_user_register_count;
198 }