1254721Semaste//===-- RegisterContextLinux_x86_64.h --------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===---------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "llvm/Support/Compiler.h" 11254721Semaste#include "RegisterContextLinux_x86_64.h" 12254721Semaste#include <vector> 13254721Semaste 14254721Semasteusing namespace lldb_private; 15254721Semaste 16254721Semaste// Computes the offset of the given GPR in the user data area. 17254721Semaste#define GPR_OFFSET(regname) \ 18254721Semaste (offsetof(GPR, regname)) 19254721Semaste 20254721Semaste// Update the Linux specific information (offset and size). 21254721Semaste#define UPDATE_GPR_INFO(reg) \ 22254721Semastedo { \ 23254721Semaste GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg); \ 24254721Semaste GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg); \ 25254721Semaste} while(false); 26254721Semaste 27254721Semaste#define UPDATE_I386_GPR_INFO(i386_reg, reg) \ 28254721Semastedo { \ 29254721Semaste GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg); \ 30254721Semaste} while(false); 31254721Semaste 32254721Semaste#define DR_OFFSET(reg_index) \ 33254721Semaste (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index])) 34254721Semaste 35254721Semaste#define UPDATE_DR_INFO(reg_index) \ 36254721Semastedo { \ 37254721Semaste GetRegisterContext()[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \ 38254721Semaste GetRegisterContext()[dr##reg_index].byte_offset = DR_OFFSET(reg_index); \ 39254721Semaste} while(false); 40254721Semaste 41254721Semastetypedef struct _GPR 42254721Semaste{ 43254721Semaste uint64_t r15; 44254721Semaste uint64_t r14; 45254721Semaste uint64_t r13; 46254721Semaste uint64_t r12; 47254721Semaste uint64_t rbp; 48254721Semaste uint64_t rbx; 49254721Semaste uint64_t r11; 50254721Semaste uint64_t r10; 51254721Semaste uint64_t r9; 52254721Semaste uint64_t r8; 53254721Semaste uint64_t rax; 54254721Semaste uint64_t rcx; 55254721Semaste uint64_t rdx; 56254721Semaste uint64_t rsi; 57254721Semaste uint64_t rdi; 58254721Semaste uint64_t orig_ax; 59254721Semaste uint64_t rip; 60254721Semaste uint64_t cs; 61254721Semaste uint64_t rflags; 62254721Semaste uint64_t rsp; 63254721Semaste uint64_t ss; 64254721Semaste uint64_t fs_base; 65254721Semaste uint64_t gs_base; 66254721Semaste uint64_t ds; 67254721Semaste uint64_t es; 68254721Semaste uint64_t fs; 69254721Semaste uint64_t gs; 70254721Semaste} GPR; 71254721Semaste 72254721Semastetypedef RegisterContext_x86_64::FXSAVE FXSAVE; 73254721Semaste 74254721Semastestruct UserArea 75254721Semaste{ 76254721Semaste GPR gpr; // General purpose registers. 77254721Semaste int32_t fpvalid; // True if FPU is being used. 78254721Semaste int32_t pad0; 79254721Semaste FXSAVE i387; // General purpose floating point registers (see FPR for extended register sets). 80254721Semaste uint64_t tsize; // Text segment size. 81254721Semaste uint64_t dsize; // Data segment size. 82254721Semaste uint64_t ssize; // Stack segment size. 83254721Semaste uint64_t start_code; // VM address of text. 84254721Semaste uint64_t start_stack; // VM address of stack bottom (top in rsp). 85254721Semaste int64_t signal; // Signal causing core dump. 86254721Semaste int32_t reserved; // Unused. 87254721Semaste int32_t pad1; 88254721Semaste uint64_t ar0; // Location of GPR's. 89254721Semaste FXSAVE* fpstate; // Location of FPR's. 90254721Semaste uint64_t magic; // Identifier for core dumps. 91254721Semaste char u_comm[32]; // Command causing core dump. 92254721Semaste uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7). 93254721Semaste uint64_t error_code; // CPU error code. 94254721Semaste uint64_t fault_address; // Control register CR3. 95254721Semaste}; 96254721Semaste 97254721Semaste// Use a singleton function to avoid global constructors in shared libraries. 98254721Semastestatic std::vector<RegisterInfo> & GetRegisterContext () { 99254721Semaste static std::vector<RegisterInfo> g_register_infos; 100254721Semaste return g_register_infos; 101254721Semaste} 102254721Semaste 103254721SemasteRegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx): 104254721Semaste RegisterContext_x86_64(thread, concrete_frame_idx) 105254721Semaste{ 106254721Semaste} 107254721Semaste 108254721Semastesize_t 109254721SemasteRegisterContextLinux_x86_64::GetGPRSize() 110254721Semaste{ 111254721Semaste return sizeof(GPR); 112254721Semaste} 113254721Semaste 114254721Semasteconst RegisterInfo * 115254721SemasteRegisterContextLinux_x86_64::GetRegisterInfo() 116254721Semaste{ 117254721Semaste // Allocate RegisterInfo only once 118254721Semaste if (GetRegisterContext().empty()) 119254721Semaste { 120254721Semaste // Copy the register information from base class 121254721Semaste const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo(); 122254721Semaste if (base_info) 123254721Semaste { 124254721Semaste GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]); 125254721Semaste // Update the Linux specific register information (offset and size). 126254721Semaste UpdateRegisterInfo(); 127254721Semaste } 128254721Semaste } 129254721Semaste return &GetRegisterContext()[0]; 130254721Semaste} 131254721Semaste 132254721Semastevoid 133254721SemasteRegisterContextLinux_x86_64::UpdateRegisterInfo() 134254721Semaste{ 135254721Semaste UPDATE_GPR_INFO(rax); 136254721Semaste UPDATE_GPR_INFO(rbx); 137254721Semaste UPDATE_GPR_INFO(rcx); 138254721Semaste UPDATE_GPR_INFO(rdx); 139254721Semaste UPDATE_GPR_INFO(rdi); 140254721Semaste UPDATE_GPR_INFO(rsi); 141254721Semaste UPDATE_GPR_INFO(rbp); 142254721Semaste UPDATE_GPR_INFO(rsp); 143254721Semaste UPDATE_GPR_INFO(r8); 144254721Semaste UPDATE_GPR_INFO(r9); 145254721Semaste UPDATE_GPR_INFO(r10); 146254721Semaste UPDATE_GPR_INFO(r11); 147254721Semaste UPDATE_GPR_INFO(r12); 148254721Semaste UPDATE_GPR_INFO(r13); 149254721Semaste UPDATE_GPR_INFO(r14); 150254721Semaste UPDATE_GPR_INFO(r15); 151254721Semaste UPDATE_GPR_INFO(rip); 152254721Semaste UPDATE_GPR_INFO(rflags); 153254721Semaste UPDATE_GPR_INFO(cs); 154254721Semaste UPDATE_GPR_INFO(fs); 155254721Semaste UPDATE_GPR_INFO(gs); 156254721Semaste UPDATE_GPR_INFO(ss); 157254721Semaste UPDATE_GPR_INFO(ds); 158254721Semaste UPDATE_GPR_INFO(es); 159254721Semaste 160254721Semaste UPDATE_I386_GPR_INFO(eax, rax); 161254721Semaste UPDATE_I386_GPR_INFO(ebx, rbx); 162254721Semaste UPDATE_I386_GPR_INFO(ecx, rcx); 163254721Semaste UPDATE_I386_GPR_INFO(edx, rdx); 164254721Semaste UPDATE_I386_GPR_INFO(edi, rdi); 165254721Semaste UPDATE_I386_GPR_INFO(esi, rsi); 166254721Semaste UPDATE_I386_GPR_INFO(ebp, rbp); 167254721Semaste UPDATE_I386_GPR_INFO(esp, rsp); 168254721Semaste UPDATE_I386_GPR_INFO(eip, rip); 169254721Semaste UPDATE_I386_GPR_INFO(eflags, rflags); 170254721Semaste 171254721Semaste UPDATE_DR_INFO(0); 172254721Semaste UPDATE_DR_INFO(1); 173254721Semaste UPDATE_DR_INFO(2); 174254721Semaste UPDATE_DR_INFO(3); 175254721Semaste UPDATE_DR_INFO(4); 176254721Semaste UPDATE_DR_INFO(5); 177254721Semaste UPDATE_DR_INFO(6); 178254721Semaste UPDATE_DR_INFO(7); 179254721Semaste} 180254721Semaste 181