179 lines · cpp
1//===-- RegisterContextNetBSD_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-exception6//7//===----------------------------------------------------------------------===//8 9#include "RegisterContextNetBSD_x86_64.h"10#include "RegisterContextNetBSD_i386.h"11#include "RegisterContextPOSIX_x86.h"12#include "llvm/Support/Compiler.h"13#include "llvm/TargetParser/Triple.h"14#include <cassert>15#include <cstddef>16 17using namespace lldb_private;18using namespace lldb;19 20// src/sys/arch/amd64/include/frame_regs.h21typedef struct _GPR {22 uint64_t rdi; /* 0 */23 uint64_t rsi; /* 1 */24 uint64_t rdx; /* 2 */25 uint64_t rcx; /* 3 */26 uint64_t r8; /* 4 */27 uint64_t r9; /* 5 */28 uint64_t r10; /* 6 */29 uint64_t r11; /* 7 */30 uint64_t r12; /* 8 */31 uint64_t r13; /* 9 */32 uint64_t r14; /* 10 */33 uint64_t r15; /* 11 */34 uint64_t rbp; /* 12 */35 uint64_t rbx; /* 13 */36 uint64_t rax; /* 14 */37 uint64_t gs; /* 15 */38 uint64_t fs; /* 16 */39 uint64_t es; /* 17 */40 uint64_t ds; /* 18 */41 uint64_t trapno; /* 19 */42 uint64_t err; /* 20 */43 uint64_t rip; /* 21 */44 uint64_t cs; /* 22 */45 uint64_t rflags; /* 23 */46 uint64_t rsp; /* 24 */47 uint64_t ss; /* 25 */48} GPR;49 50struct DBG {51 uint64_t dr[16]; /* debug registers */52 /* Index 0-3: debug address registers */53 /* Index 4-5: reserved */54 /* Index 6: debug status */55 /* Index 7: debug control */56 /* Index 8-15: reserved */57};58 59/*60 * src/sys/arch/amd64/include/mcontext.h61 *62 * typedef struct {63 * __gregset_t __gregs;64 * __greg_t _mc_tlsbase;65 * __fpregset_t __fpregs;66 * } mcontext_t;67 */68 69struct UserArea {70 GPR gpr;71 uint64_t mc_tlsbase;72 FPR fpr;73 DBG dbg;74};75 76#define DR_OFFSET(reg_index) \77 (LLVM_EXTENSION offsetof(UserArea, dbg) + \78 LLVM_EXTENSION offsetof(DBG, dr[reg_index]))79 80 81// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_6482// structure.83#define DECLARE_REGISTER_INFOS_X86_64_STRUCT84#include "RegisterInfos_x86_64.h"85#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT86 87static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() {88 static std::vector<lldb_private::RegisterInfo> g_register_infos;89 return g_register_infos;90}91 92static const RegisterInfo *93GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {94 std::vector<lldb_private::RegisterInfo> &g_register_infos =95 GetPrivateRegisterInfoVector();96 97 // Allocate RegisterInfo only once98 if (g_register_infos.empty()) {99 // Copy the register information from base class100 std::unique_ptr<RegisterContextNetBSD_i386> reg_interface(101 new RegisterContextNetBSD_i386(arch));102 const RegisterInfo *base_info = reg_interface->GetRegisterInfo();103 g_register_infos.insert(g_register_infos.end(), &base_info[0],104 &base_info[k_num_registers_i386]);105 106// Include RegisterInfos_x86_64 to update the g_register_infos structure107// with x86_64 offsets.108#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS109#include "RegisterInfos_x86_64.h"110#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS111 }112 113 return &g_register_infos[0];114}115 116static const RegisterInfo *117PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {118 switch (target_arch.GetMachine()) {119 case llvm::Triple::x86:120 return GetRegisterInfo_i386(target_arch);121 case llvm::Triple::x86_64:122 return g_register_infos_x86_64;123 default:124 assert(false && "Unhandled target architecture.");125 return nullptr;126 }127}128 129static uint32_t130PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {131 switch (target_arch.GetMachine()) {132 case llvm::Triple::x86: {133 assert(!GetPrivateRegisterInfoVector().empty() &&134 "i386 register info not yet filled.");135 return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size());136 }137 case llvm::Triple::x86_64:138 return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /139 sizeof(g_register_infos_x86_64[0]));140 default:141 assert(false && "Unhandled target architecture.");142 return 0;143 }144}145 146static uint32_t147PrivateGetUserRegisterCount(const lldb_private::ArchSpec &target_arch) {148 switch (target_arch.GetMachine()) {149 case llvm::Triple::x86:150 return static_cast<uint32_t>(k_num_user_registers_i386);151 case llvm::Triple::x86_64:152 return static_cast<uint32_t>(k_num_user_registers_x86_64);153 default:154 assert(false && "Unhandled target architecture.");155 return 0;156 }157}158 159RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(160 const ArchSpec &target_arch)161 : lldb_private::RegisterInfoInterface(target_arch),162 m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),163 m_register_count(PrivateGetRegisterCount(target_arch)),164 m_user_register_count(PrivateGetUserRegisterCount(target_arch)) {}165 166size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }167 168const RegisterInfo *RegisterContextNetBSD_x86_64::GetRegisterInfo() const {169 return m_register_info_p;170}171 172uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const {173 return m_register_count;174}175 176uint32_t RegisterContextNetBSD_x86_64::GetUserRegisterCount() const {177 return m_user_register_count;178}179