blob: 754c4801685f1a52ae8abd71002eec643acad421 [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 <src/lib/fxl/logging.h>
#include <zircon/syscalls/debug.h>
#include "garnet/lib/debugger_utils/util.h"
#include "garnet/lib/inferior_control/thread.h"
#include "registers.h"
namespace debugserver {
constexpr int kFpRegisterNumber = 6; // rbp
constexpr int kSpRegisterNumber = 7; // rsp
constexpr int kPcRegisterNumber = 16; // rip
constexpr int kNumGeneralRegisters = 18;
int GetFPRegisterNumber() { return kFpRegisterNumber; }
int GetSPRegisterNumber() { return kSpRegisterNumber; }
int GetPCRegisterNumber() { return kPcRegisterNumber; }
std::string GetUninitializedGeneralRegistersAsString() {
return std::string(sizeof(zx_thread_state_general_regs_t) * 2, '0');
}
std::string GetRegsetAsString(Thread* thread, int regset) {
FXL_DCHECK(regset == 0);
if (!thread->registers()->RefreshGeneralRegisters()) {
FXL_LOG(ERROR) << "Unable to refresh general registers";
return GetUninitializedGeneralRegistersAsString();
}
const zx_thread_state_general_regs_t* gregs =
thread->registers()->GetGeneralRegisters();
const uint8_t* greg_bytes = reinterpret_cast<const uint8_t*>(gregs);
return debugger_utils::EncodeByteArrayString(greg_bytes, sizeof(*gregs));
}
bool SetRegsetFromString(Thread* thread, int regset,
const fxl::StringView& value) {
FXL_DCHECK(regset == 0);
auto bytes = debugger_utils::DecodeByteArrayString(value);
if (bytes.size() != sizeof(zx_thread_state_general_regs_t)) {
FXL_LOG(ERROR) << "|value| doesn't match regset " << regset << " size of "
<< bytes.size() << ": " << value;
return false;
}
return SetRegsetHelper(thread, regset, bytes.data(), bytes.size());
}
std::string GetRegisterAsString(Thread* thread, int regno) {
if (regno < 0 || regno >= kNumGeneralRegisters) {
FXL_LOG(ERROR) << "Bad register number: " << regno;
return "";
}
if (!thread->registers()->RefreshGeneralRegisters()) {
FXL_LOG(ERROR) << "Unable to refresh general registers";
return std::string(sizeof(uint64_t) * 2, '0');
}
const zx_thread_state_general_regs_t* gregs =
thread->registers()->GetGeneralRegisters();
const uint8_t* greg_bytes = reinterpret_cast<const uint8_t*>(gregs);
greg_bytes += regno * sizeof(uint64_t);
return debugger_utils::EncodeByteArrayString(greg_bytes, sizeof(uint64_t));
}
} // namespace debugserver