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 26 using namespace lldb; 27 using namespace lldb_private; 28 29 RegisterContextOpenBSDKernel_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 36 bool RegisterContextOpenBSDKernel_x86_64::ReadGPR() { return true; } 37 38 bool RegisterContextOpenBSDKernel_x86_64::ReadFPR() { return true; } 39 40 bool RegisterContextOpenBSDKernel_x86_64::WriteGPR() { 41 assert(0); 42 return false; 43 } 44 45 bool RegisterContextOpenBSDKernel_x86_64::WriteFPR() { 46 assert(0); 47 return false; 48 } 49 50 bool 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 108 bool RegisterContextOpenBSDKernel_x86_64::WriteRegister( 109 const RegisterInfo *reg_info, const RegisterValue &value) { 110 return false; 111 } 112