ErrorCode PTrace::writeCPUState(ProcessThreadId const &ptid, ProcessInfo const &pinfo, Architecture::CPUState const &state) { pid_t pid; if (!ptid.valid()) return kErrorInvalidArgument; if (!(ptid.tid <= kAnyThreadId)) { pid = ptid.tid; } else { pid = ptid.pid; } // // Initialize the CPU state, just in case. // initCPUState(pid); if (pinfo.pointerSize == sizeof(uint32_t) && !state.is32) return kErrorInvalidArgument; else if (pinfo.pointerSize != sizeof(uint32_t) && state.is32) return kErrorInvalidArgument; // // Write GPRs // user_regs_struct gprs; if (state.is32) { state32_to_user(gprs, state.state32); } else { state64_to_user(gprs, state.state64); } if (wrapPtrace(PTRACE_SETREGS, pid, nullptr, &gprs) < 0) return Platform::TranslateError(); // // Write X87 and SSE state // user_fpregs_struct fprs; if (state.is32) { state32_to_user(fprs, state.state32); } else { state64_to_user(fprs, state.state64); } wrapPtrace(PTRACE_SETFPREGS, pid, nullptr, &fprs); return kSuccess; }
ErrorCode Thread::writeCPUState(Architecture::CPUState const &state) { CONTEXT context; std::memset(&context, 0, sizeof(context)); // TODO(sas): Handle floats, SSE, AVX and debug registers. context.ContextFlags = CONTEXT_INTEGER | // GP registers. CONTEXT_CONTROL | // Some more GP + cs/ss. CONTEXT_SEGMENTS; // Data segment selectors. state32_to_user(context, state); BOOL result = SetThreadContext(_handle, &context); if (!result) { return Platform::TranslateError(); } return kSuccess; }