1//===-- RegisterContextOpenBSDKernel_x86_64.cpp ---------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#if defined(__OpenBSD__) 10#include <sys/types.h> 11#include <sys/time.h> 12#define _KERNEL 13#include <machine/cpu.h> 14#undef _KERNEL 15#include <machine/pcb.h> 16#include <frame.h> 17#endif 18 19#include "RegisterContextOpenBSDKernel_x86_64.h" 20 21#include "lldb/Target/Process.h" 22#include "lldb/Target/Thread.h" 23#include "lldb/Utility/RegisterValue.h" 24#include "llvm/Support/Endian.h" 25 26using namespace lldb; 27using namespace lldb_private; 28 29RegisterContextOpenBSDKernel_x86_64::RegisterContextOpenBSDKernel_x86_64( 30 Thread &thread, RegisterInfoInterface *register_info, 31 lldb::addr_t pcb) 32 : RegisterContextPOSIX_x86(thread, 0, register_info), 33 m_pcb_addr(pcb) { 34} 35 36bool RegisterContextOpenBSDKernel_x86_64::ReadGPR() { return true; } 37 38bool RegisterContextOpenBSDKernel_x86_64::ReadFPR() { return true; } 39 40bool RegisterContextOpenBSDKernel_x86_64::WriteGPR() { 41 assert(0); 42 return false; 43} 44 45bool RegisterContextOpenBSDKernel_x86_64::WriteFPR() { 46 assert(0); 47 return false; 48} 49 50bool RegisterContextOpenBSDKernel_x86_64::ReadRegister( 51 const RegisterInfo *reg_info, RegisterValue &value) { 52 Status error; 53 54 if (m_pcb_addr == LLDB_INVALID_ADDRESS) 55 return false; 56 57#ifdef __amd64__ 58 struct pcb pcb; 59 size_t rd = m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), 60 error); 61 if (rd != sizeof(pcb)) 62 return false; 63 64 /* 65 Usually pcb is written in `cpu_switchto` function. This function writes 66 registers as same as the structure of `swichframe` in the stack. 67 We read the frame if it is. 68 */ 69 struct switchframe sf; 70 rd = m_thread.GetProcess()->ReadMemory(pcb.pcb_rsp, &sf, sizeof(sf), error); 71 if (rd != sizeof(sf)) 72 return false; 73 74 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 75 if (pcb.pcb_rbp == (u_int64_t)sf.sf_rbp) { 76#define SFREG(x) \ 77 case lldb_##x##_x86_64: \ 78 value = (u_int64_t)sf.sf_##x; \ 79 return true; 80#define PCBREG(x) \ 81 case lldb_##x##_x86_64: \ 82 value = pcb.pcb_##x; \ 83 return true; 84 switch (reg) { 85 SFREG(r15); 86 SFREG(r14); 87 SFREG(r13); 88 SFREG(r12); 89 SFREG(rbp); 90 SFREG(rbx); 91 SFREG(rip); 92 PCBREG(rsp); 93 } 94 } else { 95 switch (reg) { 96 PCBREG(rbp); 97 PCBREG(rsp); 98 case lldb_rip_x86_64: 99 value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_rbp + 8, 100 error); 101 return true; 102 } 103 } 104#endif 105 return false; 106} 107 108bool RegisterContextOpenBSDKernel_x86_64::WriteRegister( 109 const RegisterInfo *reg_info, const RegisterValue &value) { 110 return false; 111} 112