Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
96380 views
//===-- RegisterContextDarwin_i386.cpp ------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Utility/DataBufferHeap.h"9#include "lldb/Utility/DataExtractor.h"10#include "lldb/Utility/Endian.h"11#include "lldb/Utility/Log.h"12#include "lldb/Utility/RegisterValue.h"13#include "lldb/Utility/Scalar.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/Support/Compiler.h"1617#include <cstddef>1819#include <memory>2021#include "RegisterContextDarwin_i386.h"2223using namespace lldb;24using namespace lldb_private;2526enum {27gpr_eax = 0,28gpr_ebx,29gpr_ecx,30gpr_edx,31gpr_edi,32gpr_esi,33gpr_ebp,34gpr_esp,35gpr_ss,36gpr_eflags,37gpr_eip,38gpr_cs,39gpr_ds,40gpr_es,41gpr_fs,42gpr_gs,4344fpu_fcw,45fpu_fsw,46fpu_ftw,47fpu_fop,48fpu_ip,49fpu_cs,50fpu_dp,51fpu_ds,52fpu_mxcsr,53fpu_mxcsrmask,54fpu_stmm0,55fpu_stmm1,56fpu_stmm2,57fpu_stmm3,58fpu_stmm4,59fpu_stmm5,60fpu_stmm6,61fpu_stmm7,62fpu_xmm0,63fpu_xmm1,64fpu_xmm2,65fpu_xmm3,66fpu_xmm4,67fpu_xmm5,68fpu_xmm6,69fpu_xmm7,7071exc_trapno,72exc_err,73exc_faultvaddr,7475k_num_registers,7677// Aliases78fpu_fctrl = fpu_fcw,79fpu_fstat = fpu_fsw,80fpu_ftag = fpu_ftw,81fpu_fiseg = fpu_cs,82fpu_fioff = fpu_ip,83fpu_foseg = fpu_ds,84fpu_fooff = fpu_dp85};8687enum {88ehframe_eax = 0,89ehframe_ecx,90ehframe_edx,91ehframe_ebx,92ehframe_ebp,93ehframe_esp,94ehframe_esi,95ehframe_edi,96ehframe_eip,97ehframe_eflags98};99100enum {101dwarf_eax = 0,102dwarf_ecx,103dwarf_edx,104dwarf_ebx,105dwarf_esp,106dwarf_ebp,107dwarf_esi,108dwarf_edi,109dwarf_eip,110dwarf_eflags,111dwarf_stmm0 = 11,112dwarf_stmm1,113dwarf_stmm2,114dwarf_stmm3,115dwarf_stmm4,116dwarf_stmm5,117dwarf_stmm6,118dwarf_stmm7,119dwarf_xmm0 = 21,120dwarf_xmm1,121dwarf_xmm2,122dwarf_xmm3,123dwarf_xmm4,124dwarf_xmm5,125dwarf_xmm6,126dwarf_xmm7127};128129#define GPR_OFFSET(reg) \130(LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::GPR, reg))131#define FPU_OFFSET(reg) \132(LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::FPU, reg) + \133sizeof(RegisterContextDarwin_i386::GPR))134#define EXC_OFFSET(reg) \135(LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::EXC, reg) + \136sizeof(RegisterContextDarwin_i386::GPR) + \137sizeof(RegisterContextDarwin_i386::FPU))138139// These macros will auto define the register name, alt name, register size,140// register offset, encoding, format and native register. This ensures that the141// register state structures are defined correctly and have the correct sizes142// and offsets.143#define DEFINE_GPR(reg, alt) \144#reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg), \145GPR_OFFSET(reg), eEncodingUint, eFormatHex146#define DEFINE_FPU_UINT(reg) \147#reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg), \148FPU_OFFSET(reg), eEncodingUint, eFormatHex149#define DEFINE_FPU_VECT(reg, i) \150#reg #i, NULL, \151sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg[i].bytes), \152FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \153{LLDB_INVALID_REGNUM, dwarf_##reg##i, \154LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \155fpu_##reg##i }, \156nullptr, nullptr, nullptr,157158#define DEFINE_EXC(reg) \159#reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \160EXC_OFFSET(reg), eEncodingUint, eFormatHex161#define REG_CONTEXT_SIZE \162(sizeof(RegisterContextDarwin_i386::GPR) + \163sizeof(RegisterContextDarwin_i386::FPU) + \164sizeof(RegisterContextDarwin_i386::EXC))165166static RegisterInfo g_register_infos[] = {167// Macro auto defines most stuff eh_frame DWARF168// GENERIC PROCESS PLUGIN LLDB169// =============================== =======================170// =================== ========================= ==================171// =================172{DEFINE_GPR(eax, nullptr),173{ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,174gpr_eax},175nullptr,176nullptr,177nullptr,178},179{DEFINE_GPR(ebx, nullptr),180{ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,181gpr_ebx},182nullptr,183nullptr,184nullptr,185},186{DEFINE_GPR(ecx, nullptr),187{ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,188gpr_ecx},189nullptr,190nullptr,191nullptr,192},193{DEFINE_GPR(edx, nullptr),194{ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,195gpr_edx},196nullptr,197nullptr,198nullptr,199},200{DEFINE_GPR(edi, nullptr),201{ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,202gpr_edi},203nullptr,204nullptr,205nullptr,206},207{DEFINE_GPR(esi, nullptr),208{ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,209gpr_esi},210nullptr,211nullptr,212nullptr,213},214{DEFINE_GPR(ebp, "fp"),215{ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,216gpr_ebp},217nullptr,218nullptr,219nullptr,220},221{DEFINE_GPR(esp, "sp"),222{ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,223gpr_esp},224nullptr,225nullptr,226nullptr,227},228{DEFINE_GPR(ss, nullptr),229{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,230LLDB_INVALID_REGNUM, gpr_ss},231nullptr,232nullptr,233nullptr,234},235{DEFINE_GPR(eflags, "flags"),236{ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS,237LLDB_INVALID_REGNUM, gpr_eflags},238nullptr,239nullptr,240nullptr,241},242{DEFINE_GPR(eip, "pc"),243{ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,244gpr_eip},245nullptr,246nullptr,247nullptr,248},249{DEFINE_GPR(cs, nullptr),250{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,251LLDB_INVALID_REGNUM, gpr_cs},252nullptr,253nullptr,254nullptr,255},256{DEFINE_GPR(ds, nullptr),257{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,258LLDB_INVALID_REGNUM, gpr_ds},259nullptr,260nullptr,261nullptr,262},263{DEFINE_GPR(es, nullptr),264{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,265LLDB_INVALID_REGNUM, gpr_es},266nullptr,267nullptr,268nullptr,269},270{DEFINE_GPR(fs, nullptr),271{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,272LLDB_INVALID_REGNUM, gpr_fs},273nullptr,274nullptr,275nullptr,276},277{DEFINE_GPR(gs, nullptr),278{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,279LLDB_INVALID_REGNUM, gpr_gs},280nullptr,281nullptr,282nullptr,283},284285{DEFINE_FPU_UINT(fcw),286{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,287LLDB_INVALID_REGNUM, fpu_fcw},288nullptr,289nullptr,290nullptr,291},292{DEFINE_FPU_UINT(fsw),293{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,294LLDB_INVALID_REGNUM, fpu_fsw},295nullptr,296nullptr,297nullptr,298},299{DEFINE_FPU_UINT(ftw),300{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,301LLDB_INVALID_REGNUM, fpu_ftw},302nullptr,303nullptr,304nullptr,305},306{DEFINE_FPU_UINT(fop),307{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,308LLDB_INVALID_REGNUM, fpu_fop},309nullptr,310nullptr,311nullptr,312},313{DEFINE_FPU_UINT(ip),314{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,315LLDB_INVALID_REGNUM, fpu_ip},316nullptr,317nullptr,318nullptr,319},320{DEFINE_FPU_UINT(cs),321{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,322LLDB_INVALID_REGNUM, fpu_cs},323nullptr,324nullptr,325nullptr,326},327{DEFINE_FPU_UINT(dp),328{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,329LLDB_INVALID_REGNUM, fpu_dp},330nullptr,331nullptr,332nullptr,333},334{DEFINE_FPU_UINT(ds),335{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,336LLDB_INVALID_REGNUM, fpu_ds},337nullptr,338nullptr,339nullptr,340},341{DEFINE_FPU_UINT(mxcsr),342{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,343LLDB_INVALID_REGNUM, fpu_mxcsr},344nullptr,345nullptr,346nullptr,347},348{DEFINE_FPU_UINT(mxcsrmask),349{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,350LLDB_INVALID_REGNUM, fpu_mxcsrmask},351nullptr,352nullptr,353nullptr,354},355{DEFINE_FPU_VECT(stmm, 0)},356{DEFINE_FPU_VECT(stmm, 1)},357{DEFINE_FPU_VECT(stmm, 2)},358{DEFINE_FPU_VECT(stmm, 3)},359{DEFINE_FPU_VECT(stmm, 4)},360{DEFINE_FPU_VECT(stmm, 5)},361{DEFINE_FPU_VECT(stmm, 6)},362{DEFINE_FPU_VECT(stmm, 7)},363{DEFINE_FPU_VECT(xmm, 0)},364{DEFINE_FPU_VECT(xmm, 1)},365{DEFINE_FPU_VECT(xmm, 2)},366{DEFINE_FPU_VECT(xmm, 3)},367{DEFINE_FPU_VECT(xmm, 4)},368{DEFINE_FPU_VECT(xmm, 5)},369{DEFINE_FPU_VECT(xmm, 6)},370{DEFINE_FPU_VECT(xmm, 7)},371372{DEFINE_EXC(trapno),373{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,374LLDB_INVALID_REGNUM, exc_trapno},375nullptr,376nullptr,377nullptr,378},379{DEFINE_EXC(err),380{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,381LLDB_INVALID_REGNUM, exc_err},382nullptr,383nullptr,384nullptr,385},386{DEFINE_EXC(faultvaddr),387{LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,388LLDB_INVALID_REGNUM, exc_faultvaddr},389nullptr,390nullptr,391nullptr,392}};393394static size_t k_num_register_infos = std::size(g_register_infos);395396RegisterContextDarwin_i386::RegisterContextDarwin_i386(397Thread &thread, uint32_t concrete_frame_idx)398: RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {399uint32_t i;400for (i = 0; i < kNumErrors; i++) {401gpr_errs[i] = -1;402fpu_errs[i] = -1;403exc_errs[i] = -1;404}405}406407RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default;408409void RegisterContextDarwin_i386::InvalidateAllRegisters() {410InvalidateAllRegisterStates();411}412413size_t RegisterContextDarwin_i386::GetRegisterCount() {414assert(k_num_register_infos == k_num_registers);415return k_num_registers;416}417418const RegisterInfo *419RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) {420assert(k_num_register_infos == k_num_registers);421if (reg < k_num_registers)422return &g_register_infos[reg];423return nullptr;424}425426size_t RegisterContextDarwin_i386::GetRegisterInfosCount() {427return k_num_register_infos;428}429430const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() {431return g_register_infos;432}433434// General purpose registers435static uint32_t g_gpr_regnums[] = {436gpr_eax, gpr_ebx, gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp,437gpr_ss, gpr_eflags, gpr_eip, gpr_cs, gpr_ds, gpr_es, gpr_fs, gpr_gs};438439// Floating point registers440static uint32_t g_fpu_regnums[] = {441fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,442fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,443fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,444fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,445fpu_xmm6, fpu_xmm7};446447// Exception registers448449static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};450451// Number of registers in each register set452const size_t k_num_gpr_registers = std::size(g_gpr_regnums);453const size_t k_num_fpu_registers = std::size(g_fpu_regnums);454const size_t k_num_exc_registers = std::size(g_exc_regnums);455456// Register set definitions. The first definitions at register set index of457// zero is for all registers, followed by other registers sets. The register458// information for the all register set need not be filled in.459static const RegisterSet g_reg_sets[] = {460{461"General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,462},463{"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},464{"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};465466const size_t k_num_regsets = std::size(g_reg_sets);467468size_t RegisterContextDarwin_i386::GetRegisterSetCount() {469return k_num_regsets;470}471472const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) {473if (reg_set < k_num_regsets)474return &g_reg_sets[reg_set];475return nullptr;476}477478// Register information definitions for 32 bit i386.479int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {480if (reg_num < fpu_fcw)481return GPRRegSet;482else if (reg_num < exc_trapno)483return FPURegSet;484else if (reg_num < k_num_registers)485return EXCRegSet;486return -1;487}488489void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {490if (log) {491if (title)492LLDB_LOGF(log, "%s", title);493for (uint32_t i = 0; i < k_num_gpr_registers; i++) {494uint32_t reg = gpr_eax + i;495LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name,496(&gpr.eax)[reg]);497}498}499}500501int RegisterContextDarwin_i386::ReadGPR(bool force) {502int set = GPRRegSet;503if (force || !RegisterSetIsCached(set)) {504SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));505}506return GetError(set, Read);507}508509int RegisterContextDarwin_i386::ReadFPU(bool force) {510int set = FPURegSet;511if (force || !RegisterSetIsCached(set)) {512SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));513}514return GetError(set, Read);515}516517int RegisterContextDarwin_i386::ReadEXC(bool force) {518int set = EXCRegSet;519if (force || !RegisterSetIsCached(set)) {520SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));521}522return GetError(set, Read);523}524525int RegisterContextDarwin_i386::WriteGPR() {526int set = GPRRegSet;527if (!RegisterSetIsCached(set)) {528SetError(set, Write, -1);529return -1;530}531SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));532SetError(set, Read, -1);533return GetError(set, Write);534}535536int RegisterContextDarwin_i386::WriteFPU() {537int set = FPURegSet;538if (!RegisterSetIsCached(set)) {539SetError(set, Write, -1);540return -1;541}542SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));543SetError(set, Read, -1);544return GetError(set, Write);545}546547int RegisterContextDarwin_i386::WriteEXC() {548int set = EXCRegSet;549if (!RegisterSetIsCached(set)) {550SetError(set, Write, -1);551return -1;552}553SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));554SetError(set, Read, -1);555return GetError(set, Write);556}557558int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) {559switch (set) {560case GPRRegSet:561return ReadGPR(force);562case FPURegSet:563return ReadFPU(force);564case EXCRegSet:565return ReadEXC(force);566default:567break;568}569return -1;570}571572int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) {573// Make sure we have a valid context to set.574if (RegisterSetIsCached(set)) {575switch (set) {576case GPRRegSet:577return WriteGPR();578case FPURegSet:579return WriteFPU();580case EXCRegSet:581return WriteEXC();582default:583break;584}585}586return -1;587}588589bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,590RegisterValue &value) {591const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];592int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg);593594if (set == -1)595return false;596597if (ReadRegisterSet(set, false) != 0)598return false;599600switch (reg) {601case gpr_eax:602case gpr_ebx:603case gpr_ecx:604case gpr_edx:605case gpr_edi:606case gpr_esi:607case gpr_ebp:608case gpr_esp:609case gpr_ss:610case gpr_eflags:611case gpr_eip:612case gpr_cs:613case gpr_ds:614case gpr_es:615case gpr_fs:616case gpr_gs:617value = (&gpr.eax)[reg - gpr_eax];618break;619620case fpu_fcw:621value = fpu.fcw;622break;623624case fpu_fsw:625value = fpu.fsw;626break;627628case fpu_ftw:629value = fpu.ftw;630break;631632case fpu_fop:633value = fpu.fop;634break;635636case fpu_ip:637value = fpu.ip;638break;639640case fpu_cs:641value = fpu.cs;642break;643644case fpu_dp:645value = fpu.dp;646break;647648case fpu_ds:649value = fpu.ds;650break;651652case fpu_mxcsr:653value = fpu.mxcsr;654break;655656case fpu_mxcsrmask:657value = fpu.mxcsrmask;658break;659660case fpu_stmm0:661case fpu_stmm1:662case fpu_stmm2:663case fpu_stmm3:664case fpu_stmm4:665case fpu_stmm5:666case fpu_stmm6:667case fpu_stmm7:668// These values don't fit into scalar types,669// RegisterContext::ReadRegisterBytes() must be used for these registers670//::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes,671//10);672return false;673674case fpu_xmm0:675case fpu_xmm1:676case fpu_xmm2:677case fpu_xmm3:678case fpu_xmm4:679case fpu_xmm5:680case fpu_xmm6:681case fpu_xmm7:682// These values don't fit into scalar types,683// RegisterContext::ReadRegisterBytes() must be used for these registers684//::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes,685//16);686return false;687688case exc_trapno:689value = exc.trapno;690break;691692case exc_err:693value = exc.err;694break;695696case exc_faultvaddr:697value = exc.faultvaddr;698break;699700default:701return false;702}703return true;704}705706bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,707const RegisterValue &value) {708const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];709int set = GetSetForNativeRegNum(reg);710711if (set == -1)712return false;713714if (ReadRegisterSet(set, false) != 0)715return false;716717switch (reg) {718case gpr_eax:719case gpr_ebx:720case gpr_ecx:721case gpr_edx:722case gpr_edi:723case gpr_esi:724case gpr_ebp:725case gpr_esp:726case gpr_ss:727case gpr_eflags:728case gpr_eip:729case gpr_cs:730case gpr_ds:731case gpr_es:732case gpr_fs:733case gpr_gs:734(&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();735break;736737case fpu_fcw:738fpu.fcw = value.GetAsUInt16();739break;740741case fpu_fsw:742fpu.fsw = value.GetAsUInt16();743break;744745case fpu_ftw:746fpu.ftw = value.GetAsUInt8();747break;748749case fpu_fop:750fpu.fop = value.GetAsUInt16();751break;752753case fpu_ip:754fpu.ip = value.GetAsUInt32();755break;756757case fpu_cs:758fpu.cs = value.GetAsUInt16();759break;760761case fpu_dp:762fpu.dp = value.GetAsUInt32();763break;764765case fpu_ds:766fpu.ds = value.GetAsUInt16();767break;768769case fpu_mxcsr:770fpu.mxcsr = value.GetAsUInt32();771break;772773case fpu_mxcsrmask:774fpu.mxcsrmask = value.GetAsUInt32();775break;776777case fpu_stmm0:778case fpu_stmm1:779case fpu_stmm2:780case fpu_stmm3:781case fpu_stmm4:782case fpu_stmm5:783case fpu_stmm6:784case fpu_stmm7:785// These values don't fit into scalar types,786// RegisterContext::ReadRegisterBytes() must be used for these registers787::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),788value.GetByteSize());789return false;790791case fpu_xmm0:792case fpu_xmm1:793case fpu_xmm2:794case fpu_xmm3:795case fpu_xmm4:796case fpu_xmm5:797case fpu_xmm6:798case fpu_xmm7:799// These values don't fit into scalar types,800// RegisterContext::ReadRegisterBytes() must be used for these registers801::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),802value.GetByteSize());803return false;804805case exc_trapno:806exc.trapno = value.GetAsUInt32();807break;808809case exc_err:810exc.err = value.GetAsUInt32();811break;812813case exc_faultvaddr:814exc.faultvaddr = value.GetAsUInt32();815break;816817default:818return false;819}820return WriteRegisterSet(set) == 0;821}822823bool RegisterContextDarwin_i386::ReadAllRegisterValues(824lldb::WritableDataBufferSP &data_sp) {825data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);826if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {827uint8_t *dst = data_sp->GetBytes();828::memcpy(dst, &gpr, sizeof(gpr));829dst += sizeof(gpr);830831::memcpy(dst, &fpu, sizeof(fpu));832dst += sizeof(gpr);833834::memcpy(dst, &exc, sizeof(exc));835return true;836}837return false;838}839840bool RegisterContextDarwin_i386::WriteAllRegisterValues(841const lldb::DataBufferSP &data_sp) {842if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {843const uint8_t *src = data_sp->GetBytes();844::memcpy(&gpr, src, sizeof(gpr));845src += sizeof(gpr);846847::memcpy(&fpu, src, sizeof(fpu));848src += sizeof(gpr);849850::memcpy(&exc, src, sizeof(exc));851uint32_t success_count = 0;852if (WriteGPR() == 0)853++success_count;854if (WriteFPU() == 0)855++success_count;856if (WriteEXC() == 0)857++success_count;858return success_count == 3;859}860return false;861}862863uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber(864lldb::RegisterKind kind, uint32_t reg) {865if (kind == eRegisterKindGeneric) {866switch (reg) {867case LLDB_REGNUM_GENERIC_PC:868return gpr_eip;869case LLDB_REGNUM_GENERIC_SP:870return gpr_esp;871case LLDB_REGNUM_GENERIC_FP:872return gpr_ebp;873case LLDB_REGNUM_GENERIC_FLAGS:874return gpr_eflags;875case LLDB_REGNUM_GENERIC_RA:876default:877break;878}879} else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {880switch (reg) {881case dwarf_eax:882return gpr_eax;883case dwarf_ecx:884return gpr_ecx;885case dwarf_edx:886return gpr_edx;887case dwarf_ebx:888return gpr_ebx;889case dwarf_esp:890return gpr_esp;891case dwarf_ebp:892return gpr_ebp;893case dwarf_esi:894return gpr_esi;895case dwarf_edi:896return gpr_edi;897case dwarf_eip:898return gpr_eip;899case dwarf_eflags:900return gpr_eflags;901case dwarf_stmm0:902return fpu_stmm0;903case dwarf_stmm1:904return fpu_stmm1;905case dwarf_stmm2:906return fpu_stmm2;907case dwarf_stmm3:908return fpu_stmm3;909case dwarf_stmm4:910return fpu_stmm4;911case dwarf_stmm5:912return fpu_stmm5;913case dwarf_stmm6:914return fpu_stmm6;915case dwarf_stmm7:916return fpu_stmm7;917case dwarf_xmm0:918return fpu_xmm0;919case dwarf_xmm1:920return fpu_xmm1;921case dwarf_xmm2:922return fpu_xmm2;923case dwarf_xmm3:924return fpu_xmm3;925case dwarf_xmm4:926return fpu_xmm4;927case dwarf_xmm5:928return fpu_xmm5;929case dwarf_xmm6:930return fpu_xmm6;931case dwarf_xmm7:932return fpu_xmm7;933default:934break;935}936} else if (kind == eRegisterKindLLDB) {937return reg;938}939return LLDB_INVALID_REGNUM;940}941942bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) {943if (ReadGPR(false) != 0)944return false;945946const uint32_t trace_bit = 0x100u;947if (enable) {948// If the trace bit is already set, there is nothing to do949if (gpr.eflags & trace_bit)950return true;951else952gpr.eflags |= trace_bit;953} else {954// If the trace bit is already cleared, there is nothing to do955if (gpr.eflags & trace_bit)956gpr.eflags &= ~trace_bit;957else958return true;959}960961return WriteGPR() == 0;962}963964965