1//===-- RegisterContextLinux_x86_64.h --------------------------*- 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 "llvm/Support/Compiler.h" 11#include "RegisterContextLinux_x86_64.h" 12#include <vector> 13 14using namespace lldb_private; 15 16// Computes the offset of the given GPR in the user data area. 17#define GPR_OFFSET(regname) \ 18 (offsetof(GPR, regname)) 19 20// Update the Linux specific information (offset and size). 21#define UPDATE_GPR_INFO(reg) \ 22do { \ 23 GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg); \ 24 GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg); \ 25} while(false); 26 27#define UPDATE_I386_GPR_INFO(i386_reg, reg) \ 28do { \ 29 GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg); \ 30} while(false); 31 32#define DR_OFFSET(reg_index) \ 33 (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index])) 34 35#define UPDATE_DR_INFO(reg_index) \ 36do { \ 37 GetRegisterContext()[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \ 38 GetRegisterContext()[dr##reg_index].byte_offset = DR_OFFSET(reg_index); \ 39} while(false); 40 41typedef struct _GPR 42{ 43 uint64_t r15; 44 uint64_t r14; 45 uint64_t r13; 46 uint64_t r12; 47 uint64_t rbp; 48 uint64_t rbx; 49 uint64_t r11; 50 uint64_t r10; 51 uint64_t r9; 52 uint64_t r8; 53 uint64_t rax; 54 uint64_t rcx; 55 uint64_t rdx; 56 uint64_t rsi; 57 uint64_t rdi; 58 uint64_t orig_ax; 59 uint64_t rip; 60 uint64_t cs; 61 uint64_t rflags; 62 uint64_t rsp; 63 uint64_t ss; 64 uint64_t fs_base; 65 uint64_t gs_base; 66 uint64_t ds; 67 uint64_t es; 68 uint64_t fs; 69 uint64_t gs; 70} GPR; 71 72typedef RegisterContext_x86_64::FXSAVE FXSAVE; 73 74struct UserArea 75{ 76 GPR gpr; // General purpose registers. 77 int32_t fpvalid; // True if FPU is being used. 78 int32_t pad0; 79 FXSAVE i387; // General purpose floating point registers (see FPR for extended register sets). 80 uint64_t tsize; // Text segment size. 81 uint64_t dsize; // Data segment size. 82 uint64_t ssize; // Stack segment size. 83 uint64_t start_code; // VM address of text. 84 uint64_t start_stack; // VM address of stack bottom (top in rsp). 85 int64_t signal; // Signal causing core dump. 86 int32_t reserved; // Unused. 87 int32_t pad1; 88 uint64_t ar0; // Location of GPR's. 89 FXSAVE* fpstate; // Location of FPR's. 90 uint64_t magic; // Identifier for core dumps. 91 char u_comm[32]; // Command causing core dump. 92 uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7). 93 uint64_t error_code; // CPU error code. 94 uint64_t fault_address; // Control register CR3. 95}; 96 97// Use a singleton function to avoid global constructors in shared libraries. 98static std::vector<RegisterInfo> & GetRegisterContext () { 99 static std::vector<RegisterInfo> g_register_infos; 100 return g_register_infos; 101} 102 103RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx): 104 RegisterContext_x86_64(thread, concrete_frame_idx) 105{ 106} 107 108size_t 109RegisterContextLinux_x86_64::GetGPRSize() 110{ 111 return sizeof(GPR); 112} 113 114const RegisterInfo * 115RegisterContextLinux_x86_64::GetRegisterInfo() 116{ 117 // Allocate RegisterInfo only once 118 if (GetRegisterContext().empty()) 119 { 120 // Copy the register information from base class 121 const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo(); 122 if (base_info) 123 { 124 GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]); 125 // Update the Linux specific register information (offset and size). 126 UpdateRegisterInfo(); 127 } 128 } 129 return &GetRegisterContext()[0]; 130} 131 132void 133RegisterContextLinux_x86_64::UpdateRegisterInfo() 134{ 135 UPDATE_GPR_INFO(rax); 136 UPDATE_GPR_INFO(rbx); 137 UPDATE_GPR_INFO(rcx); 138 UPDATE_GPR_INFO(rdx); 139 UPDATE_GPR_INFO(rdi); 140 UPDATE_GPR_INFO(rsi); 141 UPDATE_GPR_INFO(rbp); 142 UPDATE_GPR_INFO(rsp); 143 UPDATE_GPR_INFO(r8); 144 UPDATE_GPR_INFO(r9); 145 UPDATE_GPR_INFO(r10); 146 UPDATE_GPR_INFO(r11); 147 UPDATE_GPR_INFO(r12); 148 UPDATE_GPR_INFO(r13); 149 UPDATE_GPR_INFO(r14); 150 UPDATE_GPR_INFO(r15); 151 UPDATE_GPR_INFO(rip); 152 UPDATE_GPR_INFO(rflags); 153 UPDATE_GPR_INFO(cs); 154 UPDATE_GPR_INFO(fs); 155 UPDATE_GPR_INFO(gs); 156 UPDATE_GPR_INFO(ss); 157 UPDATE_GPR_INFO(ds); 158 UPDATE_GPR_INFO(es); 159 160 UPDATE_I386_GPR_INFO(eax, rax); 161 UPDATE_I386_GPR_INFO(ebx, rbx); 162 UPDATE_I386_GPR_INFO(ecx, rcx); 163 UPDATE_I386_GPR_INFO(edx, rdx); 164 UPDATE_I386_GPR_INFO(edi, rdi); 165 UPDATE_I386_GPR_INFO(esi, rsi); 166 UPDATE_I386_GPR_INFO(ebp, rbp); 167 UPDATE_I386_GPR_INFO(esp, rsp); 168 UPDATE_I386_GPR_INFO(eip, rip); 169 UPDATE_I386_GPR_INFO(eflags, rflags); 170 171 UPDATE_DR_INFO(0); 172 UPDATE_DR_INFO(1); 173 UPDATE_DR_INFO(2); 174 UPDATE_DR_INFO(3); 175 UPDATE_DR_INFO(4); 176 UPDATE_DR_INFO(5); 177 UPDATE_DR_INFO(6); 178 UPDATE_DR_INFO(7); 179} 180 181