]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
MFV ntp 4.2.8p2 (r281348)
[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 UserArea
50 {
51     GPR      gpr;           // General purpose registers.
52     int32_t  fpvalid;       // True if FPU is being used.
53     int32_t  pad0;
54     FXSAVE   i387;          // General purpose floating point registers (see FPR for extended register sets).
55     uint64_t tsize;         // Text segment size.
56     uint64_t dsize;         // Data segment size.
57     uint64_t ssize;         // Stack segment size.
58     uint64_t start_code;    // VM address of text.
59     uint64_t start_stack;   // VM address of stack bottom (top in rsp).
60     int64_t  signal;        // Signal causing core dump.
61     int32_t  reserved;      // Unused.
62     int32_t  pad1;
63     uint64_t ar0;           // Location of GPR's.
64     FXSAVE*  fpstate;       // Location of FPR's.
65     uint64_t magic;         // Identifier for core dumps.
66     char     u_comm[32];    // Command causing core dump.
67     uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7).
68     uint64_t error_code;    // CPU error code.
69     uint64_t fault_address; // Control register CR3.
70 };
71
72 #define DR_SIZE sizeof(((UserArea*)NULL)->u_debugreg[0])
73 #define DR_OFFSET(reg_index) \
74     (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
75
76 //---------------------------------------------------------------------------
77 // Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
78 //---------------------------------------------------------------------------
79 #define DECLARE_REGISTER_INFOS_X86_64_STRUCT
80 #include "RegisterInfos_x86_64.h"
81 #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
82
83 static std::vector<lldb_private::RegisterInfo>&
84 GetPrivateRegisterInfoVector ()
85 {
86     static std::vector<lldb_private::RegisterInfo> g_register_infos;
87     return g_register_infos;
88 }
89
90 static const RegisterInfo *
91 GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
92 {
93     std::vector<lldb_private::RegisterInfo> &g_register_infos = GetPrivateRegisterInfoVector ();
94
95     // Allocate RegisterInfo only once
96     if (g_register_infos.empty())
97     {
98         // Copy the register information from base class
99         std::unique_ptr<RegisterContextLinux_i386> reg_interface(new RegisterContextLinux_i386 (arch));
100         const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
101         g_register_infos.insert(g_register_infos.end(), &base_info[0], &base_info[k_num_registers_i386]);
102
103         //---------------------------------------------------------------------------
104         // Include RegisterInfos_x86_64 to update the g_register_infos structure
105         //  with x86_64 offsets.
106         //---------------------------------------------------------------------------
107         #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
108         #include "RegisterInfos_x86_64.h"
109         #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
110     }
111
112     return &g_register_infos[0];
113 }
114
115 static const RegisterInfo *
116 GetRegisterInfoPtr (const ArchSpec &target_arch)
117 {
118     switch (target_arch.GetMachine())
119     {
120         case llvm::Triple::x86:
121             return GetRegisterInfo_i386 (target_arch);
122         case llvm::Triple::x86_64:
123             return g_register_infos_x86_64;
124         default:
125             assert(false && "Unhandled target architecture.");
126             return nullptr;
127     }
128 }
129
130 static uint32_t
131 GetRegisterInfoCount (const ArchSpec &target_arch)
132 {
133     switch (target_arch.GetMachine())
134     {
135         case llvm::Triple::x86:
136             {
137                 assert (!GetPrivateRegisterInfoVector ().empty () && "i386 register info not yet filled.");
138                 return static_cast<uint32_t> (GetPrivateRegisterInfoVector ().size ());
139             }
140         case llvm::Triple::x86_64:
141             return static_cast<uint32_t> (sizeof (g_register_infos_x86_64) / sizeof (g_register_infos_x86_64 [0]));
142         default:
143             assert(false && "Unhandled target architecture.");
144             return 0;
145     }
146 }
147
148 RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
149     lldb_private::RegisterInfoInterface(target_arch),
150     m_register_info_p (GetRegisterInfoPtr (target_arch)),
151     m_register_info_count (GetRegisterInfoCount (target_arch))
152 {
153 }
154
155 size_t
156 RegisterContextLinux_x86_64::GetGPRSize() const
157 {
158     return sizeof(GPR);
159 }
160
161 const RegisterInfo *
162 RegisterContextLinux_x86_64::GetRegisterInfo() const
163 {
164     return m_register_info_p;
165 }
166
167 uint32_t
168 RegisterContextLinux_x86_64::GetRegisterCount () const
169 {
170     return m_register_info_count;
171 }