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 // 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 static uint32_t 149 GetUserRegisterInfoCount (const ArchSpec &target_arch) 150 { 151 switch (target_arch.GetMachine()) 152 { 153 case llvm::Triple::x86: 154 return static_cast<uint32_t> (k_num_user_registers_i386); 155 case llvm::Triple::x86_64: 156 return static_cast<uint32_t> (k_num_user_registers_x86_64); 157 default: 158 assert(false && "Unhandled target architecture."); 159 return 0; 160 } 161 } 162 163 RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) : 164 lldb_private::RegisterInfoInterface(target_arch), 165 m_register_info_p (GetRegisterInfoPtr (target_arch)), 166 m_register_info_count (GetRegisterInfoCount (target_arch)), 167 m_user_register_count (GetUserRegisterInfoCount (target_arch)) 168 { 169 } 170 171 size_t 172 RegisterContextLinux_x86_64::GetGPRSize() const 173 { 174 return sizeof(GPR); 175 } 176 177 const RegisterInfo * 178 RegisterContextLinux_x86_64::GetRegisterInfo() const 179 { 180 return m_register_info_p; 181 } 182 183 uint32_t 184 RegisterContextLinux_x86_64::GetRegisterCount () const 185 { 186 return m_register_info_count; 187 } 188 189 uint32_t 190 RegisterContextLinux_x86_64::GetUserRegisterCount () const 191 { 192 return m_user_register_count; 193 } 194