1//===-- RegisterContextLinuxCore_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#include "RegisterContextLinuxCore_x86_64.h"
10#include "lldb/Target/Thread.h"
11#include "lldb/Utility/DataExtractor.h"
12#include "lldb/Utility/RegisterValue.h"
13
14using namespace lldb_private;
15
16const uint32_t g_gpr_regnums_i386[] = {
17    lldb_eax_i386,       lldb_ebx_i386,    lldb_ecx_i386, lldb_edx_i386,
18    lldb_edi_i386,       lldb_esi_i386,    lldb_ebp_i386, lldb_esp_i386,
19    lldb_eip_i386,       lldb_eflags_i386, lldb_cs_i386,  lldb_fs_i386,
20    lldb_gs_i386,        lldb_ss_i386,     lldb_ds_i386,  lldb_es_i386,
21    lldb_ax_i386,        lldb_bx_i386,     lldb_cx_i386,  lldb_dx_i386,
22    lldb_di_i386,        lldb_si_i386,     lldb_bp_i386,  lldb_sp_i386,
23    lldb_ah_i386,        lldb_bh_i386,     lldb_ch_i386,  lldb_dh_i386,
24    lldb_al_i386,        lldb_bl_i386,     lldb_cl_i386,  lldb_dl_i386,
25    LLDB_INVALID_REGNUM, // Register sets must be terminated with
26                         // LLDB_INVALID_REGNUM.
27};
28static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
29                      1 ==
30                  k_num_gpr_registers_i386,
31              "g_gpr_regnums_i386 has wrong number of register infos");
32
33const uint32_t g_lldb_regnums_i386[] = {
34    lldb_fctrl_i386,    lldb_fstat_i386,     lldb_ftag_i386,  lldb_fop_i386,
35    lldb_fiseg_i386,    lldb_fioff_i386,     lldb_foseg_i386, lldb_fooff_i386,
36    lldb_mxcsr_i386,    lldb_mxcsrmask_i386, lldb_st0_i386,   lldb_st1_i386,
37    lldb_st2_i386,      lldb_st3_i386,       lldb_st4_i386,   lldb_st5_i386,
38    lldb_st6_i386,      lldb_st7_i386,       lldb_mm0_i386,   lldb_mm1_i386,
39    lldb_mm2_i386,      lldb_mm3_i386,       lldb_mm4_i386,   lldb_mm5_i386,
40    lldb_mm6_i386,      lldb_mm7_i386,       lldb_xmm0_i386,  lldb_xmm1_i386,
41    lldb_xmm2_i386,     lldb_xmm3_i386,      lldb_xmm4_i386,  lldb_xmm5_i386,
42    lldb_xmm6_i386,     lldb_xmm7_i386,
43    LLDB_INVALID_REGNUM // Register sets must be terminated with
44                        // LLDB_INVALID_REGNUM.
45};
46static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) -
47                      1 ==
48                  k_num_fpr_registers_i386,
49              "g_lldb_regnums_i386 has wrong number of register infos");
50
51const uint32_t g_avx_regnums_i386[] = {
52    lldb_ymm0_i386,     lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
53    lldb_ymm4_i386,     lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
54    LLDB_INVALID_REGNUM // Register sets must be terminated with
55                        // LLDB_INVALID_REGNUM.
56};
57static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
58                      1 ==
59                  k_num_avx_registers_i386,
60              " g_avx_regnums_i386 has wrong number of register infos");
61
62static const uint32_t g_gpr_regnums_x86_64[] = {
63    x86_64_with_base::lldb_rax,
64    x86_64_with_base::lldb_rbx,
65    x86_64_with_base::lldb_rcx,
66    x86_64_with_base::lldb_rdx,
67    x86_64_with_base::lldb_rdi,
68    x86_64_with_base::lldb_rsi,
69    x86_64_with_base::lldb_rbp,
70    x86_64_with_base::lldb_rsp,
71    x86_64_with_base::lldb_r8,
72    x86_64_with_base::lldb_r9,
73    x86_64_with_base::lldb_r10,
74    x86_64_with_base::lldb_r11,
75    x86_64_with_base::lldb_r12,
76    x86_64_with_base::lldb_r13,
77    x86_64_with_base::lldb_r14,
78    x86_64_with_base::lldb_r15,
79    x86_64_with_base::lldb_rip,
80    x86_64_with_base::lldb_rflags,
81    x86_64_with_base::lldb_cs,
82    x86_64_with_base::lldb_fs,
83    x86_64_with_base::lldb_gs,
84    x86_64_with_base::lldb_ss,
85    x86_64_with_base::lldb_fs_base,
86    x86_64_with_base::lldb_gs_base,
87    x86_64_with_base::lldb_ds,
88    x86_64_with_base::lldb_es,
89    x86_64_with_base::lldb_eax,
90    x86_64_with_base::lldb_ebx,
91    x86_64_with_base::lldb_ecx,
92    x86_64_with_base::lldb_edx,
93    x86_64_with_base::lldb_edi,
94    x86_64_with_base::lldb_esi,
95    x86_64_with_base::lldb_ebp,
96    x86_64_with_base::lldb_esp,
97    x86_64_with_base::lldb_r8d,  // Low 32 bits or r8
98    x86_64_with_base::lldb_r9d,  // Low 32 bits or r9
99    x86_64_with_base::lldb_r10d, // Low 32 bits or r10
100    x86_64_with_base::lldb_r11d, // Low 32 bits or r11
101    x86_64_with_base::lldb_r12d, // Low 32 bits or r12
102    x86_64_with_base::lldb_r13d, // Low 32 bits or r13
103    x86_64_with_base::lldb_r14d, // Low 32 bits or r14
104    x86_64_with_base::lldb_r15d, // Low 32 bits or r15
105    x86_64_with_base::lldb_ax,
106    x86_64_with_base::lldb_bx,
107    x86_64_with_base::lldb_cx,
108    x86_64_with_base::lldb_dx,
109    x86_64_with_base::lldb_di,
110    x86_64_with_base::lldb_si,
111    x86_64_with_base::lldb_bp,
112    x86_64_with_base::lldb_sp,
113    x86_64_with_base::lldb_r8w,  // Low 16 bits or r8
114    x86_64_with_base::lldb_r9w,  // Low 16 bits or r9
115    x86_64_with_base::lldb_r10w, // Low 16 bits or r10
116    x86_64_with_base::lldb_r11w, // Low 16 bits or r11
117    x86_64_with_base::lldb_r12w, // Low 16 bits or r12
118    x86_64_with_base::lldb_r13w, // Low 16 bits or r13
119    x86_64_with_base::lldb_r14w, // Low 16 bits or r14
120    x86_64_with_base::lldb_r15w, // Low 16 bits or r15
121    x86_64_with_base::lldb_ah,
122    x86_64_with_base::lldb_bh,
123    x86_64_with_base::lldb_ch,
124    x86_64_with_base::lldb_dh,
125    x86_64_with_base::lldb_al,
126    x86_64_with_base::lldb_bl,
127    x86_64_with_base::lldb_cl,
128    x86_64_with_base::lldb_dl,
129    x86_64_with_base::lldb_dil,
130    x86_64_with_base::lldb_sil,
131    x86_64_with_base::lldb_bpl,
132    x86_64_with_base::lldb_spl,
133    x86_64_with_base::lldb_r8l,  // Low 8 bits or r8
134    x86_64_with_base::lldb_r9l,  // Low 8 bits or r9
135    x86_64_with_base::lldb_r10l, // Low 8 bits or r10
136    x86_64_with_base::lldb_r11l, // Low 8 bits or r11
137    x86_64_with_base::lldb_r12l, // Low 8 bits or r12
138    x86_64_with_base::lldb_r13l, // Low 8 bits or r13
139    x86_64_with_base::lldb_r14l, // Low 8 bits or r14
140    x86_64_with_base::lldb_r15l, // Low 8 bits or r15
141    LLDB_INVALID_REGNUM          // Register sets must be terminated with
142                                 // LLDB_INVALID_REGNUM.
143};
144static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
145                      1 ==
146                  x86_64_with_base::k_num_gpr_registers,
147              "g_gpr_regnums_x86_64 has wrong number of register infos");
148
149static const uint32_t g_lldb_regnums_x86_64[] = {
150    x86_64_with_base::lldb_fctrl, x86_64_with_base::lldb_fstat,
151    x86_64_with_base::lldb_ftag,  x86_64_with_base::lldb_fop,
152    x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff,
153    x86_64_with_base::lldb_fip,   x86_64_with_base::lldb_foseg,
154    x86_64_with_base::lldb_fooff, x86_64_with_base::lldb_fdp,
155    x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask,
156    x86_64_with_base::lldb_st0,   x86_64_with_base::lldb_st1,
157    x86_64_with_base::lldb_st2,   x86_64_with_base::lldb_st3,
158    x86_64_with_base::lldb_st4,   x86_64_with_base::lldb_st5,
159    x86_64_with_base::lldb_st6,   x86_64_with_base::lldb_st7,
160    x86_64_with_base::lldb_mm0,   x86_64_with_base::lldb_mm1,
161    x86_64_with_base::lldb_mm2,   x86_64_with_base::lldb_mm3,
162    x86_64_with_base::lldb_mm4,   x86_64_with_base::lldb_mm5,
163    x86_64_with_base::lldb_mm6,   x86_64_with_base::lldb_mm7,
164    x86_64_with_base::lldb_xmm0,  x86_64_with_base::lldb_xmm1,
165    x86_64_with_base::lldb_xmm2,  x86_64_with_base::lldb_xmm3,
166    x86_64_with_base::lldb_xmm4,  x86_64_with_base::lldb_xmm5,
167    x86_64_with_base::lldb_xmm6,  x86_64_with_base::lldb_xmm7,
168    x86_64_with_base::lldb_xmm8,  x86_64_with_base::lldb_xmm9,
169    x86_64_with_base::lldb_xmm10, x86_64_with_base::lldb_xmm11,
170    x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13,
171    x86_64_with_base::lldb_xmm14, x86_64_with_base::lldb_xmm15,
172    LLDB_INVALID_REGNUM // Register sets must be terminated with
173                        // LLDB_INVALID_REGNUM.
174};
175static_assert(
176    (sizeof(g_lldb_regnums_x86_64) / sizeof(g_lldb_regnums_x86_64[0])) - 1 ==
177        x86_64_with_base::k_num_fpr_registers,
178    "g_lldb_regnums_x86_64 has wrong number of register infos");
179
180static const uint32_t g_avx_regnums_x86_64[] = {
181    x86_64_with_base::lldb_ymm0,  x86_64_with_base::lldb_ymm1,
182    x86_64_with_base::lldb_ymm2,  x86_64_with_base::lldb_ymm3,
183    x86_64_with_base::lldb_ymm4,  x86_64_with_base::lldb_ymm5,
184    x86_64_with_base::lldb_ymm6,  x86_64_with_base::lldb_ymm7,
185    x86_64_with_base::lldb_ymm8,  x86_64_with_base::lldb_ymm9,
186    x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11,
187    x86_64_with_base::lldb_ymm12, x86_64_with_base::lldb_ymm13,
188    x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15,
189    LLDB_INVALID_REGNUM // Register sets must be terminated with
190                        // LLDB_INVALID_REGNUM.
191};
192static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
193                      1 ==
194                  x86_64_with_base::k_num_avx_registers,
195              "g_avx_regnums_x86_64 has wrong number of register infos");
196
197static const RegisterSet g_reg_sets_i386[] = {
198    {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
199     g_gpr_regnums_i386},
200    {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
201     g_lldb_regnums_i386},
202    {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
203     g_avx_regnums_i386}};
204
205static const RegisterSet g_reg_sets_x86_64[] = {
206    {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers,
207     g_gpr_regnums_x86_64},
208    {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers,
209     g_lldb_regnums_x86_64},
210    {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers,
211     g_avx_regnums_x86_64}};
212
213RegisterContextLinuxCore_x86_64::RegisterContextLinuxCore_x86_64(
214    Thread &thread, RegisterInfoInterface *register_info,
215    const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
216    : RegisterContextCorePOSIX_x86_64(thread, register_info, gpregset, notes) {}
217
218const RegisterSet *RegisterContextLinuxCore_x86_64::GetRegisterSet(size_t set) {
219  if (IsRegisterSetAvailable(set)) {
220    switch (m_register_info_up->GetTargetArchitecture().GetMachine()) {
221    case llvm::Triple::x86:
222      return &g_reg_sets_i386[set];
223    case llvm::Triple::x86_64:
224      return &g_reg_sets_x86_64[set];
225    default:
226      assert(false && "Unhandled target architecture.");
227      return nullptr;
228    }
229  }
230  return nullptr;
231}
232
233RegInfo &RegisterContextLinuxCore_x86_64::GetRegInfo() {
234  return GetRegInfoShared(
235      m_register_info_up->GetTargetArchitecture().GetMachine(),
236      /*with_base=*/true);
237}
238