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