1 //===-- RegisterContextFreeBSD_x86_64.cpp ----------------------*- C++ -*-===//
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
7 //===---------------------------------------------------------------------===//
9 #include "RegisterContextFreeBSD_x86_64.h"
10 #include "RegisterContextFreeBSD_i386.h"
11 #include "RegisterContextPOSIX_x86.h"
14 using namespace lldb_private;
17 // http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h
48 uint64_t dr[16]; /* debug registers */
49 /* Index 0-3: debug address registers */
50 /* Index 4-5: reserved */
51 /* Index 6: debug status */
52 /* Index 7: debug control */
53 /* Index 8-15: reserved */
62 #define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index]))
64 // Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64
66 #define DECLARE_REGISTER_INFOS_X86_64_STRUCT
67 #include "RegisterInfos_x86_64.h"
68 #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
70 static std::vector<lldb_private::RegisterInfo> &GetSharedRegisterInfoVector() {
71 static std::vector<lldb_private::RegisterInfo> register_infos;
72 return register_infos;
75 static const RegisterInfo *
76 GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
77 static std::vector<lldb_private::RegisterInfo> g_register_infos(
78 GetSharedRegisterInfoVector());
80 // Allocate RegisterInfo only once
81 if (g_register_infos.empty()) {
82 // Copy the register information from base class
83 std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface(
84 new RegisterContextFreeBSD_i386(arch));
85 const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
86 g_register_infos.insert(g_register_infos.end(), &base_info[0],
87 &base_info[k_num_registers_i386]);
89 // Include RegisterInfos_x86_64 to update the g_register_infos structure
90 // with x86_64 offsets.
91 #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
92 #include "RegisterInfos_x86_64.h"
93 #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
96 return &g_register_infos[0];
99 static const RegisterInfo *
100 PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
101 switch (target_arch.GetMachine()) {
102 case llvm::Triple::x86:
103 return GetRegisterInfo_i386(target_arch);
104 case llvm::Triple::x86_64:
105 return g_register_infos_x86_64;
107 assert(false && "Unhandled target architecture.");
113 PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
114 switch (target_arch.GetMachine()) {
115 case llvm::Triple::x86:
116 // This vector should have already been filled.
117 assert(!GetSharedRegisterInfoVector().empty() &&
118 "i386 register info vector not filled.");
119 return static_cast<uint32_t>(GetSharedRegisterInfoVector().size());
120 case llvm::Triple::x86_64:
121 return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
122 sizeof(g_register_infos_x86_64[0]));
124 assert(false && "Unhandled target architecture.");
129 RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(
130 const ArchSpec &target_arch)
131 : lldb_private::RegisterInfoInterface(target_arch),
132 m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),
133 m_register_count(PrivateGetRegisterCount(target_arch)) {}
135 size_t RegisterContextFreeBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }
137 const RegisterInfo *RegisterContextFreeBSD_x86_64::GetRegisterInfo() const {
138 return m_register_info_p;
141 uint32_t RegisterContextFreeBSD_x86_64::GetRegisterCount() const {
142 return m_register_count;