blob: ad717e3313089a1ae98438ebdc90381e06dccaff [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string.h>
#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/strings/string_printf.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/debug.h>
#include "garnet/lib/debugger_utils/util.h"
#include "registers.h"
#include "thread.h"
namespace inferior_control {
Registers::Registers(Thread* thread) : thread_(thread) {
FXL_DCHECK(thread);
FXL_DCHECK(thread->handle() != ZX_HANDLE_INVALID);
}
bool Registers::RefreshRegset(int regset) {
FXL_DCHECK(regset == 0);
return RefreshRegsetHelper(regset, &general_regs_, sizeof(general_regs_));
}
bool Registers::WriteRegset(int regset) {
FXL_DCHECK(regset == 0);
return WriteRegsetHelper(regset, &general_regs_, sizeof(general_regs_));
}
bool Registers::RefreshGeneralRegisters() {
return RefreshRegset(ZX_THREAD_STATE_GENERAL_REGS);
}
bool Registers::WriteGeneralRegisters() {
return WriteRegset(ZX_THREAD_STATE_GENERAL_REGS);
}
zx_thread_state_general_regs_t* Registers::GetGeneralRegisters() {
return &general_regs_;
}
bool Registers::RefreshRegsetHelper(int regset, void* buf, size_t buf_size) {
// We report all zeros for the registers if the thread was just created.
if (thread()->state() == Thread::State::kNew) {
memset(buf, 0, buf_size);
return true;
}
zx_status_t status =
zx_thread_read_state(thread()->handle(), regset, buf, buf_size);
if (status < 0) {
FXL_LOG(ERROR) << "Failed to read regset " << regset << ": "
<< debugger_utils::ZxErrorString(status);
return false;
}
FXL_VLOG(4) << "Regset " << regset << " refreshed";
return true;
}
bool Registers::WriteRegsetHelper(int regset, const void* buf,
size_t buf_size) {
zx_status_t status =
zx_thread_write_state(thread()->handle(), regset, buf, buf_size);
if (status < 0) {
FXL_LOG(ERROR) << "Failed to write regset " << regset << ": "
<< debugger_utils::ZxErrorString(status);
return false;
}
FXL_VLOG(4) << "Regset " << regset << " written";
return true;
}
} // namespace inferior_control