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_rax; 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 RegisterInfo orig_ax = { "orig_rax", NULL, sizeof(((GPR*)NULL)->orig_rax), (LLVM_EXTENSION offsetof(GPR, orig_rax)), eEncodingUint, \ 175 eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL }; 176 d_register_infos.push_back(orig_ax); 177 } 178 179 size_t 180 RegisterContextLinux_x86_64::GetGPRSize() const 181 { 182 return sizeof(GPR); 183 } 184 185 const std::vector<lldb_private::RegisterInfo> * 186 RegisterContextLinux_x86_64::GetDynamicRegisterInfoP() const 187 { 188 return &d_register_infos; 189 } 190 191 const RegisterInfo * 192 RegisterContextLinux_x86_64::GetRegisterInfo() const 193 { 194 return m_register_info_p; 195 } 196 197 uint32_t 198 RegisterContextLinux_x86_64::GetRegisterCount () const 199 { 200 return m_register_info_count; 201 } 202 203 uint32_t 204 RegisterContextLinux_x86_64::GetUserRegisterCount () const 205 { 206 return m_user_register_count; 207 } 208