1dda28197Spatrick //===-- RegisterContextLinux_i386.cpp -------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===---------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "RegisterContextLinux_i386.h"
10061da546Spatrick #include "RegisterContextPOSIX_x86.h"
11061da546Spatrick
12061da546Spatrick using namespace lldb_private;
13061da546Spatrick using namespace lldb;
14061da546Spatrick
15061da546Spatrick struct GPR {
16061da546Spatrick uint32_t ebx;
17061da546Spatrick uint32_t ecx;
18061da546Spatrick uint32_t edx;
19061da546Spatrick uint32_t esi;
20061da546Spatrick uint32_t edi;
21061da546Spatrick uint32_t ebp;
22061da546Spatrick uint32_t eax;
23061da546Spatrick uint32_t ds;
24061da546Spatrick uint32_t es;
25061da546Spatrick uint32_t fs;
26061da546Spatrick uint32_t gs;
27061da546Spatrick uint32_t orig_eax;
28061da546Spatrick uint32_t eip;
29061da546Spatrick uint32_t cs;
30061da546Spatrick uint32_t eflags;
31061da546Spatrick uint32_t esp;
32061da546Spatrick uint32_t ss;
33061da546Spatrick };
34061da546Spatrick
35061da546Spatrick struct FPR_i386 {
36061da546Spatrick uint16_t fctrl; // FPU Control Word (fcw)
37061da546Spatrick uint16_t fstat; // FPU Status Word (fsw)
38061da546Spatrick uint16_t ftag; // FPU Tag Word (ftw)
39061da546Spatrick uint16_t fop; // Last Instruction Opcode (fop)
40061da546Spatrick union {
41061da546Spatrick struct {
42061da546Spatrick uint64_t fip; // Instruction Pointer
43061da546Spatrick uint64_t fdp; // Data Pointer
44061da546Spatrick } x86_64;
45061da546Spatrick struct {
46061da546Spatrick uint32_t fioff; // FPU IP Offset (fip)
47061da546Spatrick uint32_t fiseg; // FPU IP Selector (fcs)
48061da546Spatrick uint32_t fooff; // FPU Operand Pointer Offset (foo)
49061da546Spatrick uint32_t foseg; // FPU Operand Pointer Selector (fos)
50061da546Spatrick } i386_; // Added _ in the end to avoid error with gcc defining i386 in some
51061da546Spatrick // cases
52061da546Spatrick } ptr;
53061da546Spatrick uint32_t mxcsr; // MXCSR Register State
54061da546Spatrick uint32_t mxcsrmask; // MXCSR Mask
55061da546Spatrick MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
56061da546Spatrick XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes
57061da546Spatrick uint32_t padding[56];
58061da546Spatrick };
59061da546Spatrick
60061da546Spatrick struct UserArea {
61061da546Spatrick GPR regs; // General purpose registers.
62061da546Spatrick int32_t fpvalid; // True if FPU is being used.
63061da546Spatrick FPR_i386 i387; // FPU registers.
64061da546Spatrick uint32_t tsize; // Text segment size.
65061da546Spatrick uint32_t dsize; // Data segment size.
66061da546Spatrick uint32_t ssize; // Stack segment size.
67061da546Spatrick uint32_t start_code; // VM address of text.
68061da546Spatrick uint32_t start_stack; // VM address of stack bottom (top in rsp).
69061da546Spatrick int32_t signal; // Signal causing core dump.
70061da546Spatrick int32_t reserved; // Unused.
71061da546Spatrick uint32_t ar0; // Location of GPR's.
72061da546Spatrick uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this
73061da546Spatrick // has to be 32-bits even on 64-bit systems.
74061da546Spatrick uint32_t magic; // Identifier for core dumps.
75061da546Spatrick char u_comm[32]; // Command causing core dump.
76061da546Spatrick uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
77061da546Spatrick };
78061da546Spatrick
79061da546Spatrick #define DR_SIZE sizeof(((UserArea *)NULL)->u_debugreg[0])
80061da546Spatrick #define DR_0_OFFSET 0xFC
81061da546Spatrick #define DR_OFFSET(reg_index) (DR_0_OFFSET + (reg_index * 4))
82061da546Spatrick #define FPR_SIZE(reg) sizeof(((FPR_i386 *)NULL)->reg)
83061da546Spatrick
84061da546Spatrick // Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
85061da546Spatrick #define DECLARE_REGISTER_INFOS_I386_STRUCT
86061da546Spatrick #include "RegisterInfos_i386.h"
87061da546Spatrick #undef DECLARE_REGISTER_INFOS_I386_STRUCT
88061da546Spatrick
RegisterContextLinux_i386(const ArchSpec & target_arch)89061da546Spatrick RegisterContextLinux_i386::RegisterContextLinux_i386(
90061da546Spatrick const ArchSpec &target_arch)
91061da546Spatrick : RegisterInfoInterface(target_arch) {
92*f6aab3d8Srobert RegisterInfo orig_ax = {
93*f6aab3d8Srobert "orig_eax",
94061da546Spatrick nullptr,
95061da546Spatrick sizeof(((GPR *)nullptr)->orig_eax),
96061da546Spatrick (LLVM_EXTENSION offsetof(GPR, orig_eax)),
97061da546Spatrick eEncodingUint,
98061da546Spatrick eFormatHex,
99*f6aab3d8Srobert {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
100*f6aab3d8Srobert LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
101061da546Spatrick nullptr,
102061da546Spatrick nullptr,
103*f6aab3d8Srobert };
104061da546Spatrick d_register_infos.push_back(orig_ax);
105061da546Spatrick }
106061da546Spatrick
GetGPRSizeStatic()107*f6aab3d8Srobert size_t RegisterContextLinux_i386::GetGPRSizeStatic() { return sizeof(GPR); }
108061da546Spatrick
GetRegisterInfo() const109061da546Spatrick const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const {
110*f6aab3d8Srobert switch (GetTargetArchitecture().GetMachine()) {
111061da546Spatrick case llvm::Triple::x86:
112061da546Spatrick case llvm::Triple::x86_64:
113061da546Spatrick return g_register_infos_i386;
114061da546Spatrick default:
115061da546Spatrick assert(false && "Unhandled target architecture.");
116061da546Spatrick return nullptr;
117061da546Spatrick }
118061da546Spatrick }
119061da546Spatrick
GetRegisterCount() const120061da546Spatrick uint32_t RegisterContextLinux_i386::GetRegisterCount() const {
121061da546Spatrick return static_cast<uint32_t>(sizeof(g_register_infos_i386) /
122061da546Spatrick sizeof(g_register_infos_i386[0]));
123061da546Spatrick }
124061da546Spatrick
GetUserRegisterCount() const125061da546Spatrick uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const {
126061da546Spatrick return static_cast<uint32_t>(k_num_user_registers_i386);
127061da546Spatrick }
128061da546Spatrick
129061da546Spatrick const std::vector<lldb_private::RegisterInfo> *
GetDynamicRegisterInfoP() const130061da546Spatrick RegisterContextLinux_i386::GetDynamicRegisterInfoP() const {
131061da546Spatrick return &d_register_infos;
132061da546Spatrick }
133