LLDB mainline
NativeRegisterContextLinux_x86.cpp
Go to the documentation of this file.
1//===-- NativeRegisterContextLinux_x86.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(__i386__) || defined(__x86_64__)
10
12
17#include "lldb/Host/HostInfo.h"
19#include "lldb/Utility/Log.h"
21#include "lldb/Utility/Status.h"
22
23#include <algorithm>
24#include <optional>
25
26// System includes - They have to be included after framework includes because
27// they define some macros which collide with variable names in other modules.
28#include <asm/ldt.h>
29#include <cpuid.h>
30#include <linux/elf.h>
31#include <sys/ptrace.h>
32
33#ifndef PTRACE_GET_THREAD_AREA
34#define PTRACE_GET_THREAD_AREA 25
35#endif
36
37// Newer toolchains define __get_cpuid_count in cpuid.h, but some
38// older-but-still-supported ones (e.g. gcc 5.4.0) don't, so we
39// define it locally here, following the definition in clang/lib/Headers.
40static inline int get_cpuid_count(unsigned int __leaf,
41 unsigned int __subleaf,
42 unsigned int *__eax, unsigned int *__ebx,
43 unsigned int *__ecx, unsigned int *__edx)
44{
45 unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, nullptr);
46
47 if (__max_leaf == 0 || __max_leaf < __leaf)
48 return 0;
49
50 __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
51 return 1;
52}
53
54using namespace lldb_private;
55using namespace lldb_private::process_linux;
56
57// Linux exposes the i386 thread pointer as a synthetic register between the
58// always-available FPU registers and the optional extended register sets.
59constexpr uint32_t k_i386_thread_pointer_index = k_first_avx_i386;
60
61// x86 32-bit general purpose registers.
62static const uint32_t g_gpr_regnums_i386[] = {
71 LLDB_INVALID_REGNUM // register sets need to end with this flag
72};
73static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
74 1 ==
76 "g_gpr_regnums_i386 has wrong number of register infos");
77
78// x86 32-bit floating point registers.
79static const uint32_t g_fpu_regnums_i386[] = {
89 LLDB_INVALID_REGNUM // register sets need to end with this flag
90};
91static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
92 1 ==
94 "g_fpu_regnums_i386 has wrong number of register infos");
95
96// x86 32-bit AVX registers.
97static const uint32_t g_avx_regnums_i386[] = {
100 LLDB_INVALID_REGNUM // register sets need to end with this flag
101};
102static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
103 1 ==
105 " g_avx_regnums_i386 has wrong number of register infos");
106
107// x64 32-bit MPX registers.
108static const uint32_t g_mpx_regnums_i386[] = {
111 LLDB_INVALID_REGNUM // register sets need to end with this flag
112};
113static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
114 1 ==
116 "g_mpx_regnums_x86_64 has wrong number of register infos");
117
118// x86 64-bit general purpose registers.
119static const uint32_t g_gpr_regnums_x86_64[] = {
129 x86_64_with_base::lldb_r8d, // Low 32 bits or r8
130 x86_64_with_base::lldb_r9d, // Low 32 bits or r9
131 x86_64_with_base::lldb_r10d, // Low 32 bits or r10
132 x86_64_with_base::lldb_r11d, // Low 32 bits or r11
133 x86_64_with_base::lldb_r12d, // Low 32 bits or r12
134 x86_64_with_base::lldb_r13d, // Low 32 bits or r13
135 x86_64_with_base::lldb_r14d, // Low 32 bits or r14
136 x86_64_with_base::lldb_r15d, // Low 32 bits or r15
139 x86_64_with_base::lldb_r8w, // Low 16 bits or r8
140 x86_64_with_base::lldb_r9w, // Low 16 bits or r9
141 x86_64_with_base::lldb_r10w, // Low 16 bits or r10
142 x86_64_with_base::lldb_r11w, // Low 16 bits or r11
143 x86_64_with_base::lldb_r12w, // Low 16 bits or r12
144 x86_64_with_base::lldb_r13w, // Low 16 bits or r13
145 x86_64_with_base::lldb_r14w, // Low 16 bits or r14
146 x86_64_with_base::lldb_r15w, // Low 16 bits or r15
150 x86_64_with_base::lldb_r8l, // Low 8 bits or r8
151 x86_64_with_base::lldb_r9l, // Low 8 bits or r9
152 x86_64_with_base::lldb_r10l, // Low 8 bits or r10
153 x86_64_with_base::lldb_r11l, // Low 8 bits or r11
154 x86_64_with_base::lldb_r12l, // Low 8 bits or r12
155 x86_64_with_base::lldb_r13l, // Low 8 bits or r13
156 x86_64_with_base::lldb_r14l, // Low 8 bits or r14
157 x86_64_with_base::lldb_r15l, // Low 8 bits or r15
158 LLDB_INVALID_REGNUM // register sets need to end with this flag
159};
160static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
161 1 ==
163 "g_gpr_regnums_x86_64 has wrong number of register infos");
164
165// x86 64-bit floating point registers.
166static const uint32_t g_fpu_regnums_x86_64[] = {
182 LLDB_INVALID_REGNUM // register sets need to end with this flag
183};
184static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
185 1 ==
187 "g_fpu_regnums_x86_64 has wrong number of register infos");
188
189// x86 64-bit AVX registers.
190static const uint32_t g_avx_regnums_x86_64[] = {
195 LLDB_INVALID_REGNUM // register sets need to end with this flag
196};
197static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
198 1 ==
200 "g_avx_regnums_x86_64 has wrong number of register infos");
201
202// x86 64-bit MPX registers.
203static const uint32_t g_mpx_regnums_x86_64[] = {
206 LLDB_INVALID_REGNUM // register sets need to end with this flag
207};
208static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
209 1 ==
211 "g_mpx_regnums_x86_64 has wrong number of register infos");
212
213// Number of register sets provided by this context.
214constexpr unsigned k_num_extended_register_sets = 2, k_num_register_sets = 4;
215
216// Register sets for x86 32-bit.
218 {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
220 {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
221 g_fpu_regnums_i386},
222 {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
224 { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
225 g_mpx_regnums_i386}};
226
227// Register sets for x86 64-bit.
229 {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers,
231 {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers,
232 g_fpu_regnums_x86_64},
233 {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers,
235 { "Memory Protection Extensions", "mpx", x86_64_with_base::k_num_mpx_registers,
236 g_mpx_regnums_x86_64}};
237
238#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
239
240// Required ptrace defines.
241
242// Support ptrace extensions even when compiled without required kernel support
243#ifndef NT_X86_XSTATE
244#define NT_X86_XSTATE 0x202
245#endif
246#ifndef NT_PRXFPREG
247#define NT_PRXFPREG 0x46e62b7f
248#endif
249
250// On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to
251// use NT_PRXFPREG.
252static inline unsigned int fxsr_regset(const ArchSpec &arch) {
253 return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
254}
255
256// Required MPX define.
257
258// Support MPX extensions also if compiled with compiler without MPX support.
259#ifndef bit_MPX
260#define bit_MPX 0x4000
261#endif
262
263// XCR0 extended register sets masks.
264#define mask_XSTATE_AVX (1ULL << 2)
265#define mask_XSTATE_BNDREGS (1ULL << 3)
266#define mask_XSTATE_BNDCFG (1ULL << 4)
267#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
268
269std::unique_ptr<NativeRegisterContextLinux>
271 const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
272 return std::unique_ptr<NativeRegisterContextLinux>(
273 new NativeRegisterContextLinux_x86(target_arch, native_thread));
274}
275
276llvm::Expected<ArchSpec>
278 return DetermineArchitectureViaGPR(
280}
281
282// NativeRegisterContextLinux_x86 members.
283
284static std::unique_ptr<RegisterContextLinux_x86>
285CreateRegisterInfoInterface(const ArchSpec &target_arch) {
286 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
287 // 32-bit hosts run with a RegisterContextLinux_i386 context.
288 return std::make_unique<RegisterContextLinux_i386>(target_arch);
289 } else {
290 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
291 "Register setting path assumes this is a 64-bit host");
292 // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
293 // x86_64 register context.
294 return std::make_unique<RegisterContextLinux_x86_64>(target_arch);
295 }
296}
297
298// Return the size of the XSTATE area supported on this cpu. It is necessary to
299// allocate the full size of the area even if we do not use/recognise all of it
300// because ptrace(PTRACE_SETREGSET, NT_X86_XSTATE) will refuse to write to it if
301// we do not pass it a buffer of sufficient size. The size is always at least
302// sizeof(FPR) so that the allocated buffer can be safely cast to FPR*.
303static std::size_t GetXSTATESize() {
304 unsigned int eax, ebx, ecx, edx;
305 // First check whether the XSTATE are is supported at all.
306 if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx) || !(ecx & bit_XSAVE))
307 return sizeof(FPR);
308
309 // Then fetch the maximum size of the area.
310 if (!get_cpuid_count(0x0d, 0, &eax, &ebx, &ecx, &edx))
311 return sizeof(FPR);
312 return std::max<std::size_t>(ecx, sizeof(FPR));
313}
314
315NativeRegisterContextLinux_x86::NativeRegisterContextLinux_x86(
316 const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
318 native_thread, CreateRegisterInfoInterface(target_arch).release()),
319 NativeRegisterContextLinux(native_thread),
320 m_xstate_type(XStateType::Invalid), m_ymm_set(), m_mpx_set(),
321 m_reg_info(), m_gpr_x86_64() {
322 // Set up data about ranges of valid registers.
323 switch (target_arch.GetMachine()) {
324 case llvm::Triple::x86: {
325 const RegisterInfoInterface &register_info = GetRegisterInfoInterface();
326 // Place the synthetic value after all existing user data so existing
327 // g-packet offsets remain unchanged.
328 uint32_t byte_offset = 0;
329 for (uint32_t i = 0; i < register_info.GetUserRegisterCount(); ++i) {
330 const RegisterInfo &info = register_info.GetRegisterInfo()[i];
331 byte_offset = std::max(byte_offset, info.byte_offset + info.byte_size);
332 }
333 m_i386_thread_pointer_info = {"gs_base",
334 nullptr,
335 sizeof(uint32_t),
336 byte_offset,
337 lldb::eEncodingUint,
338 lldb::eFormatHex,
339 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
340 LLDB_REGNUM_GENERIC_TP, LLDB_INVALID_REGNUM,
341 LLDB_INVALID_REGNUM},
342 nullptr,
343 nullptr,
344 nullptr};
345
346 m_reg_info.num_registers = k_num_registers_i386 + 1;
347 m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
348 m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
349 m_reg_info.num_avx_registers = k_num_avx_registers_i386;
350 m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
351 m_reg_info.last_gpr = k_last_gpr_i386;
352 m_reg_info.first_fpr = k_first_fpr_i386;
353 m_reg_info.last_fpr = k_last_fpr_i386;
354 m_reg_info.first_st = lldb_st0_i386;
355 m_reg_info.last_st = lldb_st7_i386;
356 m_reg_info.first_mm = lldb_mm0_i386;
357 m_reg_info.last_mm = lldb_mm7_i386;
358 m_reg_info.first_xmm = lldb_xmm0_i386;
359 m_reg_info.last_xmm = lldb_xmm7_i386;
360 m_reg_info.first_ymm = lldb_ymm0_i386;
361 m_reg_info.last_ymm = lldb_ymm7_i386;
362 m_reg_info.first_mpxr = lldb_bnd0_i386;
363 m_reg_info.last_mpxr = lldb_bnd3_i386;
364 m_reg_info.first_mpxc = lldb_bndcfgu_i386;
365 m_reg_info.last_mpxc = lldb_bndstatus_i386;
366 m_reg_info.first_dr = lldb_dr0_i386;
367 m_reg_info.last_dr = lldb_dr7_i386;
368 m_reg_info.gpr_flags = lldb_eflags_i386;
369 break;
370 }
371 case llvm::Triple::x86_64:
372 m_reg_info.num_registers = x86_64_with_base::k_num_registers;
373 m_reg_info.num_gpr_registers = x86_64_with_base::k_num_gpr_registers;
374 m_reg_info.num_fpr_registers = x86_64_with_base::k_num_fpr_registers;
375 m_reg_info.num_avx_registers = x86_64_with_base::k_num_avx_registers;
376 m_reg_info.num_mpx_registers = x86_64_with_base::k_num_mpx_registers;
377 m_reg_info.last_gpr = x86_64_with_base::k_last_gpr;
378 m_reg_info.first_fpr = x86_64_with_base::k_first_fpr;
379 m_reg_info.last_fpr = x86_64_with_base::k_last_fpr;
380 m_reg_info.first_st = x86_64_with_base::lldb_st0;
381 m_reg_info.last_st = x86_64_with_base::lldb_st7;
382 m_reg_info.first_mm = x86_64_with_base::lldb_mm0;
383 m_reg_info.last_mm = x86_64_with_base::lldb_mm7;
384 m_reg_info.first_xmm = x86_64_with_base::lldb_xmm0;
385 m_reg_info.last_xmm = x86_64_with_base::lldb_xmm15;
386 m_reg_info.first_ymm = x86_64_with_base::lldb_ymm0;
387 m_reg_info.last_ymm = x86_64_with_base::lldb_ymm15;
388 m_reg_info.first_mpxr = x86_64_with_base::lldb_bnd0;
389 m_reg_info.last_mpxr = x86_64_with_base::lldb_bnd3;
390 m_reg_info.first_mpxc = x86_64_with_base::lldb_bndcfgu;
391 m_reg_info.last_mpxc = x86_64_with_base::lldb_bndstatus;
392 m_reg_info.first_dr = x86_64_with_base::lldb_dr0;
393 m_reg_info.last_dr = x86_64_with_base::lldb_dr7;
394 m_reg_info.gpr_flags = x86_64_with_base::lldb_rflags;
395 break;
396 default:
397 assert(false && "Unhandled target architecture.");
398 break;
399 }
400
401 std::size_t xstate_size = GetXSTATESize();
402 m_xstate.reset(static_cast<FPR *>(std::malloc(xstate_size)));
403 m_iovec.iov_base = m_xstate.get();
404 m_iovec.iov_len = xstate_size;
405
406 // Clear out the FPR state.
407 ::memset(m_xstate.get(), 0, xstate_size);
408
409 // Store byte offset of fctrl (i.e. first register of FPR)
410 const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
411 m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
412}
413
414uint32_t NativeRegisterContextLinux_x86::GetRegisterCount() const {
416 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
417 llvm::Triple::x86)
418 ++count;
419 return count;
420}
421
422const RegisterInfo *
423NativeRegisterContextLinux_x86::GetRegisterInfoAtIndex(uint32_t reg) const {
424 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
425 llvm::Triple::x86) {
426 if (reg == k_i386_thread_pointer_index)
427 return &m_i386_thread_pointer_info;
428 // Translate the public index back to the unchanged underlying table.
429 if (reg > k_i386_thread_pointer_index)
430 --reg;
431 }
433}
434
435// CONSIDER after local and llgs debugging are merged, register set support can
436// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
437uint32_t NativeRegisterContextLinux_x86::GetRegisterSetCount() const {
438 uint32_t sets = 0;
439 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
440 if (IsRegisterSetAvailable(set_index))
441 ++sets;
442 }
443
444 return sets;
445}
446
447uint32_t NativeRegisterContextLinux_x86::GetUserRegisterCount() const {
448 uint32_t count = 0;
449 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
450 const RegisterSet *set = GetRegisterSet(set_index);
451 if (set)
452 count += set->num_registers;
453 }
454 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
455 llvm::Triple::x86)
456 ++count;
457 return count;
458}
459
460const RegisterSet *
461NativeRegisterContextLinux_x86::GetRegisterSet(uint32_t set_index) const {
462 if (!IsRegisterSetAvailable(set_index))
463 return nullptr;
464
465 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
466 case llvm::Triple::x86:
467 return &g_reg_sets_i386[set_index];
468 case llvm::Triple::x86_64:
469 return &g_reg_sets_x86_64[set_index];
470 default:
471 assert(false && "Unhandled target architecture.");
472 return nullptr;
473 }
474
475 return nullptr;
476}
477
478Status
479NativeRegisterContextLinux_x86::ReadRegister(const RegisterInfo *reg_info,
480 RegisterValue &reg_value) {
482
483 if (!reg_info) {
484 error = Status::FromErrorString("reg_info NULL");
485 return error;
486 }
487
488 if (IsThreadPointer(*reg_info))
489 return ReadThreadPointer(reg_value);
490
491 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
492 if (reg == LLDB_INVALID_REGNUM) {
493 // This is likely an internal register for lldb use only and should not be
494 // directly queried.
496 "register \"%s\" is an internal-only lldb "
497 "register, cannot read directly",
498 reg_info->name);
499 return error;
500 }
501
502 if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
503 error = ReadFPR();
504 if (error.Fail())
505 return error;
506 } else {
507 uint32_t full_reg = reg;
508 bool is_subreg = reg_info->invalidate_regs &&
509 (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
510
511 if (is_subreg) {
512 // Read the full aligned 64-bit register.
513 full_reg = reg_info->invalidate_regs[0];
514 }
515
516 error = ReadRegisterRaw(GetRegisterInfoIndex(full_reg), reg_value);
517
518 if (error.Success()) {
519 // If our read was not aligned (for ah,bh,ch,dh), shift our returned
520 // value one byte to the right.
521 if (is_subreg && (reg_info->byte_offset & 0x1))
522 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
523
524 // If our return byte size was greater than the return value reg size,
525 // then use the type specified by reg_info rather than the uint64_t
526 // default
527 if (reg_value.GetByteSize() > reg_info->byte_size)
528 reg_value.SetType(*reg_info);
529 }
530 return error;
531 }
532
533 if (reg_info->encoding == lldb::eEncodingVector) {
534 lldb::ByteOrder byte_order = GetByteOrder();
535
536 if (byte_order != lldb::eByteOrderInvalid) {
537 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
538 reg_value.SetBytes(
539 m_xstate->fxsave.stmm[reg - m_reg_info.first_st].bytes,
540 reg_info->byte_size, byte_order);
541 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
542 reg_value.SetBytes(
543 m_xstate->fxsave.stmm[reg - m_reg_info.first_mm].bytes,
544 reg_info->byte_size, byte_order);
545 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
546 reg_value.SetBytes(
547 m_xstate->fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
548 reg_info->byte_size, byte_order);
549 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
550 // Concatenate ymm using the register halves in xmm.bytes and
551 // ymmh.bytes
552 if (CopyXSTATEtoYMM(reg, byte_order))
553 reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
554 reg_info->byte_size, byte_order);
555 else {
556 error = Status::FromErrorString("failed to copy ymm register value");
557 return error;
558 }
559 }
560 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
561 if (CopyXSTATEtoMPX(reg))
562 reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
563 reg_info->byte_size, byte_order);
564 else {
565 error = Status::FromErrorString("failed to copy mpx register value");
566 return error;
567 }
568 }
569 if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
570 if (CopyXSTATEtoMPX(reg))
571 reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
572 reg_info->byte_size, byte_order);
573 else {
574 error = Status::FromErrorString("failed to copy mpx register value");
575 return error;
576 }
577 }
578
579 if (reg_value.GetType() != RegisterValue::eTypeBytes)
581 "write failed - type was expected to be RegisterValue::eTypeBytes");
582
583 return error;
584 }
585
586 error = Status::FromErrorString("byte order is invalid");
587 return error;
588 }
589
590 // Get pointer to m_xstate->fxsave variable and set the data from it.
591
592 // Byte offsets of all registers are calculated wrt 'UserArea' structure.
593 // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
594 // and stores them in 'm_fpr' (of type FPR structure). To extract values of
595 // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR
596 // structure.
597
598 // Since, FPR structure is also one of the member of UserArea structure.
599 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
600 // byte_offset(fctrl wrt UserArea)
601 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(FPR));
602 uint8_t *src = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
603 m_fctrl_offset_in_userarea;
604
605 if (src == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag)) {
607 m_xstate->fxsave.ftag, m_xstate->fxsave.fstat, m_xstate->fxsave.stmm));
608 return error;
609 }
610
611 switch (reg_info->byte_size) {
612 case 1:
613 reg_value.SetUInt8(*(uint8_t *)src);
614 break;
615 case 2:
616 reg_value.SetUInt16(*(uint16_t *)src);
617 break;
618 case 4:
619 reg_value.SetUInt32(*(uint32_t *)src);
620 break;
621 case 8:
622 reg_value.SetUInt64(*(uint64_t *)src);
623 break;
624 default:
625 assert(false && "Unhandled data size.");
626 error = Status::FromErrorStringWithFormat("unhandled byte size: %" PRIu32,
627 reg_info->byte_size);
628 break;
629 }
630
631 return error;
632}
633
634void NativeRegisterContextLinux_x86::UpdateXSTATEforWrite(
635 uint32_t reg_index) {
636 XSAVE_HDR::XFeature &xstate_bv = m_xstate->xsave.header.xstate_bv;
637 if (IsFPR(reg_index)) {
638 // IsFPR considers both %st and %xmm registers as floating point, but these
639 // map to two features. Set both flags, just in case.
641 } else if (IsAVX(reg_index)) {
642 // Lower bytes of some %ymm registers are shared with %xmm registers.
644 } else if (IsMPX(reg_index)) {
645 // MPX registers map to two XSAVE features.
647 }
648}
649
650Status NativeRegisterContextLinux_x86::WriteRegister(
651 const RegisterInfo *reg_info, const RegisterValue &reg_value) {
652 assert(reg_info && "reg_info is null");
653
654 if (IsThreadPointer(*reg_info))
655 return Status::FromErrorString("the i386 thread pointer is read-only");
656
657 const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
658 if (reg_index == LLDB_INVALID_REGNUM)
660 "no lldb regnum for %s",
661 reg_info && reg_info->name ? reg_info->name : "<unknown register>");
662
663 UpdateXSTATEforWrite(reg_index);
664
665 if (IsGPR(reg_index) || IsDR(reg_index))
666 return WriteRegisterRaw(GetRegisterInfoIndex(reg_index), reg_value);
667
668 if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
669 if (reg_info->encoding == lldb::eEncodingVector) {
670 if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
671 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
672 reg_value.GetBytes(), reg_value.GetByteSize());
673
674 if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
675 ::memcpy(m_xstate->fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
676 reg_value.GetBytes(), reg_value.GetByteSize());
677
678 if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
679 ::memcpy(m_xstate->fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
680 reg_value.GetBytes(), reg_value.GetByteSize());
681
682 if (reg_index >= m_reg_info.first_ymm &&
683 reg_index <= m_reg_info.last_ymm) {
684 // Store ymm register content, and split into the register halves in
685 // xmm.bytes and ymmh.bytes
686 ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
687 reg_value.GetBytes(), reg_value.GetByteSize());
688 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
689 return Status::FromErrorString("CopyYMMtoXSTATE() failed");
690 }
691
692 if (reg_index >= m_reg_info.first_mpxr &&
693 reg_index <= m_reg_info.last_mpxr) {
694 ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
695 reg_value.GetBytes(), reg_value.GetByteSize());
696 if (!CopyMPXtoXSTATE(reg_index))
697 return Status::FromErrorString("CopyMPXtoXSTATE() failed");
698 }
699
700 if (reg_index >= m_reg_info.first_mpxc &&
701 reg_index <= m_reg_info.last_mpxc) {
702 ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
703 reg_value.GetBytes(), reg_value.GetByteSize());
704 if (!CopyMPXtoXSTATE(reg_index))
705 return Status::FromErrorString("CopyMPXtoXSTATE() failed");
706 }
707 } else {
708 // Get pointer to m_xstate->fxsave variable and set the data to it.
709
710 // Byte offsets of all registers are calculated wrt 'UserArea' structure.
711 // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
712 // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
713 // registers should be written in m_fpr at byte offsets calculated wrt
714 // FPR structure.
715
716 // Since, FPR structure is also one of the member of UserArea structure.
717 // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
718 // byte_offset(fctrl wrt UserArea)
719 assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
720 sizeof(FPR));
721 uint8_t *dst = (uint8_t *)m_xstate.get() + reg_info->byte_offset -
722 m_fctrl_offset_in_userarea;
723
724 if (dst == reinterpret_cast<uint8_t *>(&m_xstate->fxsave.ftag))
725 m_xstate->fxsave.ftag = FullToAbridgedTagWord(reg_value.GetAsUInt16());
726 else {
727 switch (reg_info->byte_size) {
728 case 1:
729 *(uint8_t *)dst = reg_value.GetAsUInt8();
730 break;
731 case 2:
732 *(uint16_t *)dst = reg_value.GetAsUInt16();
733 break;
734 case 4:
735 *(uint32_t *)dst = reg_value.GetAsUInt32();
736 break;
737 case 8:
738 *(uint64_t *)dst = reg_value.GetAsUInt64();
739 break;
740 default:
741 assert(false && "Unhandled data size.");
743 "unhandled register data size %" PRIu32, reg_info->byte_size);
744 }
745 }
746 }
747
748 Status error = WriteFPR();
749 if (error.Fail())
750 return error;
751
752 if (IsAVX(reg_index)) {
753 if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
754 return Status::FromErrorString("CopyYMMtoXSTATE() failed");
755 }
756
757 if (IsMPX(reg_index)) {
758 if (!CopyMPXtoXSTATE(reg_index))
759 return Status::FromErrorString("CopyMPXtoXSTATE() failed");
760 }
761 return Status();
762 }
764 "failed - register wasn't recognized to be a GPR or an FPR, "
765 "write strategy unknown");
766}
767
768Status NativeRegisterContextLinux_x86::ReadAllRegisterValues(
771
772 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
773 error = ReadGPR();
774 if (error.Fail())
775 return error;
776
777 error = ReadFPR();
778 if (error.Fail())
779 return error;
780
781 uint8_t *dst = data_sp->GetBytes();
782 ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
783 dst += GetRegisterInfoInterface().GetGPRSize();
784 if (m_xstate_type == XStateType::FXSAVE)
785 ::memcpy(dst, &m_xstate->fxsave, sizeof(m_xstate->fxsave));
786 else if (m_xstate_type == XStateType::XSAVE) {
787 lldb::ByteOrder byte_order = GetByteOrder();
788
789 if (IsCPUFeatureAvailable(RegSet::avx)) {
790 // Assemble the YMM register content from the register halves.
791 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
792 ++reg) {
793 if (!CopyXSTATEtoYMM(reg, byte_order)) {
795 "NativeRegisterContextLinux_x86::%s "
796 "CopyXSTATEtoYMM() failed for reg num "
797 "%" PRIu32,
798 __FUNCTION__, reg);
799 return error;
800 }
801 }
802 }
803
804 if (IsCPUFeatureAvailable(RegSet::mpx)) {
805 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
806 ++reg) {
807 if (!CopyXSTATEtoMPX(reg)) {
809 "NativeRegisterContextLinux_x86::%s "
810 "CopyXSTATEtoMPX() failed for reg num "
811 "%" PRIu32,
812 __FUNCTION__, reg);
813 return error;
814 }
815 }
816 }
817 // Copy the extended register state including the assembled ymm registers.
818 ::memcpy(dst, m_xstate.get(), sizeof(FPR));
819 } else {
820 assert(false && "how do we save the floating point registers?");
822 "unsure how to save the floating point registers");
823 }
824 /** The following code is specific to Linux x86 based architectures,
825 * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
826 * -1 to solve the bug 23659, such a setting prevents the automatic
827 * decrement of the instruction pointer which was causing the SIGILL
828 * exception.
829 * **/
830
831 RegisterValue value((uint64_t)-1);
832 const RegisterInfo &info = GetRegisterInfo().GetOrigAxInfo();
833 return DoWriteRegisterValue(info.byte_offset, info.name, value);
834
835 return error;
836}
837
838Status NativeRegisterContextLinux_x86::WriteAllRegisterValues(
839 const lldb::DataBufferSP &data_sp) {
841
842 if (!data_sp) {
844 "NativeRegisterContextLinux_x86::%s invalid data_sp provided",
845 __FUNCTION__);
846 return error;
847 }
848
849 if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
851 "data_sp contained mismatched data size, expected {0}, actual {1}",
852 REG_CONTEXT_SIZE, data_sp->GetByteSize());
853 return error;
854 }
855
856 const uint8_t *src = data_sp->GetBytes();
857 if (src == nullptr) {
859 "NativeRegisterContextLinux_x86::%s "
860 "DataBuffer::GetBytes() returned a null "
861 "pointer",
862 __FUNCTION__);
863 return error;
864 }
865 ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
866
867 error = WriteGPR();
868 if (error.Fail())
869 return error;
870
871 src += GetRegisterInfoInterface().GetGPRSize();
872 if (m_xstate_type == XStateType::FXSAVE)
873 ::memcpy(&m_xstate->fxsave, src, sizeof(m_xstate->fxsave));
874 else if (m_xstate_type == XStateType::XSAVE)
875 ::memcpy(&m_xstate->xsave, src, sizeof(m_xstate->xsave));
876
877 error = WriteFPR();
878 if (error.Fail())
879 return error;
880
881 if (m_xstate_type == XStateType::XSAVE) {
882 lldb::ByteOrder byte_order = GetByteOrder();
883
884 if (IsCPUFeatureAvailable(RegSet::avx)) {
885 // Parse the YMM register content from the register halves.
886 for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
887 ++reg) {
888 if (!CopyYMMtoXSTATE(reg, byte_order)) {
890 "NativeRegisterContextLinux_x86::%s "
891 "CopyYMMtoXSTATE() failed for reg num "
892 "%" PRIu32,
893 __FUNCTION__, reg);
894 return error;
895 }
896 }
897 }
898
899 if (IsCPUFeatureAvailable(RegSet::mpx)) {
900 for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
901 ++reg) {
902 if (!CopyMPXtoXSTATE(reg)) {
904 "NativeRegisterContextLinux_x86::%s "
905 "CopyMPXtoXSTATE() failed for reg num "
906 "%" PRIu32,
907 __FUNCTION__, reg);
908 return error;
909 }
910 }
911 }
912 }
913
914 return error;
915}
916
917bool NativeRegisterContextLinux_x86::IsCPUFeatureAvailable(
918 RegSet feature_code) const {
919 if (m_xstate_type == XStateType::Invalid) {
920 if (const_cast<NativeRegisterContextLinux_x86 *>(this)->ReadFPR().Fail())
921 return false;
922 }
923 switch (feature_code) {
924 case RegSet::gpr:
925 case RegSet::fpu:
926 return true;
927 case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
928 // reading in the XCR0 area of XSAVE.
929 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
930 return true;
931 break;
932 case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
933 // reading in the XCR0 area of XSAVE.
934 if ((m_xstate->xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
935 return true;
936 break;
937 }
938 return false;
939}
940
941bool NativeRegisterContextLinux_x86::IsRegisterSetAvailable(
942 uint32_t set_index) const {
944
945 switch (static_cast<RegSet>(set_index)) {
946 case RegSet::gpr:
947 case RegSet::fpu:
948 return (set_index < num_sets);
949 case RegSet::avx:
950 return IsCPUFeatureAvailable(RegSet::avx);
951 case RegSet::mpx:
952 return IsCPUFeatureAvailable(RegSet::mpx);
953 }
954 return false;
955}
956
957bool NativeRegisterContextLinux_x86::IsGPR(uint32_t reg_index) const {
958 // GPRs come first.
959 return reg_index <= m_reg_info.last_gpr;
960}
961
962bool NativeRegisterContextLinux_x86::IsFPR(uint32_t reg_index) const {
963 return (m_reg_info.first_fpr <= reg_index &&
964 reg_index <= m_reg_info.last_fpr);
965}
966
967bool NativeRegisterContextLinux_x86::IsDR(uint32_t reg_index) const {
968 return (m_reg_info.first_dr <= reg_index &&
969 reg_index <= m_reg_info.last_dr);
970}
971
972Status NativeRegisterContextLinux_x86::WriteFPR() {
973 switch (m_xstate_type) {
974 case XStateType::FXSAVE:
975 return WriteRegisterSet(
976 &m_iovec, sizeof(m_xstate->fxsave),
977 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
978 case XStateType::XSAVE:
979 return WriteRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
980 default:
981 return Status::FromErrorString("Unrecognized FPR type.");
982 }
983}
984
985bool NativeRegisterContextLinux_x86::IsAVX(uint32_t reg_index) const {
986 if (!IsCPUFeatureAvailable(RegSet::avx))
987 return false;
988 return (m_reg_info.first_ymm <= reg_index &&
989 reg_index <= m_reg_info.last_ymm);
990}
991
992bool NativeRegisterContextLinux_x86::CopyXSTATEtoYMM(
993 uint32_t reg_index, lldb::ByteOrder byte_order) {
994 if (!IsAVX(reg_index))
995 return false;
996
997 if (byte_order == lldb::eByteOrderLittle) {
998 uint32_t reg_no = reg_index - m_reg_info.first_ymm;
999 m_ymm_set.ymm[reg_no] = XStateToYMM(
1000 m_xstate->fxsave.xmm[reg_no].bytes,
1001 m_xstate->xsave.ymmh[reg_no].bytes);
1002 return true;
1003 }
1004
1005 return false; // unsupported or invalid byte order
1006}
1007
1008bool NativeRegisterContextLinux_x86::CopyYMMtoXSTATE(
1009 uint32_t reg, lldb::ByteOrder byte_order) {
1010 if (!IsAVX(reg))
1011 return false;
1012
1013 if (byte_order == lldb::eByteOrderLittle) {
1014 uint32_t reg_no = reg - m_reg_info.first_ymm;
1015 YMMToXState(m_ymm_set.ymm[reg_no],
1016 m_xstate->fxsave.xmm[reg_no].bytes,
1017 m_xstate->xsave.ymmh[reg_no].bytes);
1018 return true;
1019 }
1020
1021 return false; // unsupported or invalid byte order
1022}
1023
1024void *NativeRegisterContextLinux_x86::GetFPRBuffer() {
1025 switch (m_xstate_type) {
1026 case XStateType::FXSAVE:
1027 return &m_xstate->fxsave;
1028 case XStateType::XSAVE:
1029 return &m_iovec;
1030 default:
1031 return nullptr;
1032 }
1033}
1034
1035size_t NativeRegisterContextLinux_x86::GetFPRSize() {
1036 switch (m_xstate_type) {
1037 case XStateType::FXSAVE:
1038 return sizeof(m_xstate->fxsave);
1039 case XStateType::XSAVE:
1040 return sizeof(m_iovec);
1041 default:
1042 return 0;
1043 }
1044}
1045
1046Status NativeRegisterContextLinux_x86::ReadFPR() {
1047 Status error;
1048
1049 // Probe XSAVE and if it is not supported fall back to FXSAVE.
1050 if (m_xstate_type != XStateType::FXSAVE) {
1051 error = ReadRegisterSet(&m_iovec, sizeof(m_xstate->xsave), NT_X86_XSTATE);
1052 if (!error.Fail()) {
1053 m_xstate_type = XStateType::XSAVE;
1054 return error;
1055 }
1056 }
1057 error = ReadRegisterSet(
1058 &m_iovec, sizeof(m_xstate->xsave),
1059 fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
1060 if (!error.Fail()) {
1061 m_xstate_type = XStateType::FXSAVE;
1062 return error;
1063 }
1064 return Status::FromErrorString("Unrecognized FPR type.");
1065}
1066
1067bool NativeRegisterContextLinux_x86::IsMPX(uint32_t reg_index) const {
1068 if (!IsCPUFeatureAvailable(RegSet::mpx))
1069 return false;
1070 return (m_reg_info.first_mpxr <= reg_index &&
1071 reg_index <= m_reg_info.last_mpxc);
1072}
1073
1074bool NativeRegisterContextLinux_x86::IsThreadPointer(
1075 const RegisterInfo &reg_info) const {
1076 return GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
1077 llvm::Triple::x86 &&
1079}
1080
1081Status
1082NativeRegisterContextLinux_x86::ReadThreadPointer(RegisterValue &reg_value) {
1083 RegisterValue selector;
1084 Status error = ReadRegisterRaw(lldb_gs_i386, selector);
1085 if (error.Fail())
1086 return error;
1087
1088 const uint32_t gs = selector.GetAsUInt32();
1089 // Selectors 0 through 3 refer to the null GDT descriptor with different
1090 // requested privilege levels.
1091 if (gs < 4) {
1092 reg_value.SetUInt32(0);
1093 return Status();
1094 }
1095 if (gs & 4)
1097 "cannot read the i386 thread pointer from an LDT selector");
1098
1099 const uintptr_t entry_number = gs >> 3;
1100 user_desc descriptor = {};
1102 PTRACE_GET_THREAD_AREA, m_thread.GetID(),
1103 reinterpret_cast<void *>(entry_number), &descriptor, sizeof(descriptor));
1104 if (error.Fail())
1105 return error;
1106
1107 reg_value.SetUInt32(descriptor.base_addr);
1108 return Status();
1109}
1110
1111uint32_t
1112NativeRegisterContextLinux_x86::GetRegisterInfoIndex(uint32_t lldb_reg) const {
1113 // Raw register helpers take register-info indices rather than LLDB numbers.
1114 if (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine() ==
1115 llvm::Triple::x86 &&
1116 lldb_reg >= k_i386_thread_pointer_index)
1117 return lldb_reg + 1;
1118 return lldb_reg;
1119}
1120
1121bool NativeRegisterContextLinux_x86::CopyXSTATEtoMPX(uint32_t reg) {
1122 if (!IsMPX(reg))
1123 return false;
1124
1125 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1126 ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
1127 m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1128 sizeof(MPXReg));
1129 } else {
1130 ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
1131 m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1132 sizeof(MPXCsr));
1133 }
1134 return true;
1135}
1136
1137bool NativeRegisterContextLinux_x86::CopyMPXtoXSTATE(uint32_t reg) {
1138 if (!IsMPX(reg))
1139 return false;
1140
1141 if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
1142 ::memcpy(m_xstate->xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
1143 m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
1144 } else {
1145 ::memcpy(m_xstate->xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
1146 m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
1147 }
1148 return true;
1149}
1150
1151uint32_t
1152NativeRegisterContextLinux_x86::GetPtraceOffset(uint32_t reg_index) {
1153 // If register is MPX, remove extra factor from gdb offset
1154 return GetRegisterInfoAtIndex(reg_index)->byte_offset -
1155 (IsMPX(reg_index) ? 128 : 0);
1156}
1157
1158std::optional<NativeRegisterContextLinux::SyscallData>
1159NativeRegisterContextLinux_x86::GetSyscallData() {
1160 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1161 case llvm::Triple::x86: {
1162 static const uint8_t Int80[] = {0xcd, 0x80};
1163 static const uint32_t Args[] = {lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386,
1166 return SyscallData{Int80, Args, lldb_eax_i386};
1167 }
1168 case llvm::Triple::x86_64: {
1169 static const uint8_t Syscall[] = {0x0f, 0x05};
1170 static const uint32_t Args[] = {
1173 return SyscallData{Syscall, Args, x86_64_with_base::lldb_rax};
1174 }
1175 default:
1176 llvm_unreachable("Unhandled architecture!");
1177 }
1178}
1179
1180std::optional<NativeRegisterContextLinux::MmapData>
1181NativeRegisterContextLinux_x86::GetMmapData() {
1182 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1183 case llvm::Triple::x86:
1184 return MmapData{192, 91};
1185 case llvm::Triple::x86_64:
1186 return MmapData{9, 11};
1187 default:
1188 llvm_unreachable("Unhandled architecture!");
1189 }
1190}
1191
1192const RegisterInfo *NativeRegisterContextLinux_x86::GetDR(int num) const {
1193 assert(num >= 0 && num <= 7);
1194 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
1195 case llvm::Triple::x86:
1196 return GetRegisterInfoAtIndex(GetRegisterInfoIndex(lldb_dr0_i386 + num));
1197 case llvm::Triple::x86_64:
1198 return GetRegisterInfoAtIndex(x86_64_with_base::lldb_dr0 + num);
1199 default:
1200 llvm_unreachable("Unhandled target architecture.");
1201 }
1202}
1203
1204#endif // defined(__i386__) || defined(__x86_64__)
static llvm::raw_ostream & error(Stream &strm)
#define REG_CONTEXT_SIZE
struct _FPR FPR
static const RegisterSet g_reg_sets_i386[]
static const uint32_t g_gpr_regnums_x86_64[]
const uint32_t g_gpr_regnums_i386[]
static const RegisterSet g_reg_sets_x86_64[]
const uint32_t g_avx_regnums_i386[]
static const uint32_t g_avx_regnums_x86_64[]
@ k_num_extended_register_sets
A subclass of DataBuffer that stores a data buffer on the heap.
const RegisterInfo * GetRegisterInfoAtIndex(uint32_t reg_index) const override
uint16_t GetAsUInt16(uint16_t fail_value=UINT16_MAX, bool *success_ptr=nullptr) const
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
uint8_t GetAsUInt8(uint8_t fail_value=UINT8_MAX, bool *success_ptr=nullptr) const
void SetUInt16(uint16_t uint)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
void SetUInt8(uint8_t uint)
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
const void * GetBytes() const
RegisterValue::Type GetType() const
void SetType(RegisterValue::Type type)
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
}
static std::unique_ptr< NativeRegisterContextLinux > CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch, NativeThreadLinux &native_thread)
static llvm::Expected< ArchSpec > DetermineArchitecture(lldb::tid_t tid)
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_TP
A class that represents a running process on the host machine.
void YMMToXState(const YMMReg &input, void *xmm_bytes, void *ymmh_bytes)
uint16_t AbridgedToFullTagWord(uint8_t abridged_tw, uint16_t sw, llvm::ArrayRef< MMSReg > st_regs)
YMMReg XStateToYMM(const void *xmm_bytes, const void *ymmh_bytes)
uint8_t FullToAbridgedTagWord(uint16_t tw)
@ eEncodingVector
vector registers
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t tid_t
Definition lldb-types.h:85
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
lldb::Encoding encoding
Encoding of the register bits.
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
uint32_t * invalidate_regs
List of registers (terminated with LLDB_INVALID_REGNUM).
Registers are grouped into register sets.
size_t num_registers
The number of registers in REGISTERS array below.