blob: eb8f0d1b45a27e090b34e217632ed4dada591ba5 [file] [log] [blame]
// Copyright 2023 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 <signal.h>
#include <zircon/status.h>
#include "src/developer/debug/debug_agent/arch.h"
#include "src/developer/debug/shared/arch_x86.h"
// Our sysroot does not define this constant.
#ifndef TRAP_HWBKPT
#define TRAP_HWBKPT 4
#endif
namespace debug_agent {
namespace arch {
uint32_t GetHardwareBreakpointCount() {
// TODO(brettW) implement this.
return 4;
}
uint32_t GetHardwareWatchpointCount() {
// TODO(brettW) implement this.
return 4;
}
void SaveGeneralRegs(const PlatformGeneralRegisters& input,
std::vector<debug::RegisterValue>& out) {
using debug::RegisterID;
out.emplace_back(RegisterID::kX64_rax, static_cast<uint64_t>(input.rax));
out.emplace_back(RegisterID::kX64_rbx, static_cast<uint64_t>(input.rbx));
out.emplace_back(RegisterID::kX64_rcx, static_cast<uint64_t>(input.rcx));
out.emplace_back(RegisterID::kX64_rdx, static_cast<uint64_t>(input.rdx));
out.emplace_back(RegisterID::kX64_rsi, static_cast<uint64_t>(input.rsi));
out.emplace_back(RegisterID::kX64_rdi, static_cast<uint64_t>(input.rdi));
out.emplace_back(RegisterID::kX64_rbp, static_cast<uint64_t>(input.rbp));
out.emplace_back(RegisterID::kX64_rsp, static_cast<uint64_t>(input.rsp));
out.emplace_back(RegisterID::kX64_r8, static_cast<uint64_t>(input.r8));
out.emplace_back(RegisterID::kX64_r9, static_cast<uint64_t>(input.r9));
out.emplace_back(RegisterID::kX64_r10, static_cast<uint64_t>(input.r10));
out.emplace_back(RegisterID::kX64_r11, static_cast<uint64_t>(input.r11));
out.emplace_back(RegisterID::kX64_r12, static_cast<uint64_t>(input.r12));
out.emplace_back(RegisterID::kX64_r13, static_cast<uint64_t>(input.r13));
out.emplace_back(RegisterID::kX64_r14, static_cast<uint64_t>(input.r14));
out.emplace_back(RegisterID::kX64_r15, static_cast<uint64_t>(input.r15));
out.emplace_back(RegisterID::kX64_rip, static_cast<uint64_t>(input.rip));
out.emplace_back(RegisterID::kX64_rflags, static_cast<uint64_t>(input.eflags));
out.emplace_back(RegisterID::kX64_fsbase, static_cast<uint64_t>(input.fs_base));
out.emplace_back(RegisterID::kX64_gsbase, static_cast<uint64_t>(input.gs_base));
// The Linux user_regs_struct also contains "cs", "ds", "es", "fs", "gs", and "ss" which we don't
// have enums for. They should be added when we have them.
}
debug_ipc::ExceptionType DecodeExceptionType(int signal, int sig_code) {
// TODO(brettw) fill out different singal types. See bits/siginfo-consts.h
switch (signal) {
case SIGTRAP:
switch (sig_code) {
case SI_KERNEL:
return debug_ipc::ExceptionType::kSoftwareBreakpoint;
case TRAP_TRACE:
return debug_ipc::ExceptionType::kSingleStep;
case TRAP_BRKPT:
// Single-stepping a syscall.
// TODO(brettw) do we need something different here?
return debug_ipc::ExceptionType::kSingleStep;
case TRAP_HWBKPT:
return debug_ipc::ExceptionType::kHardwareBreakpoint;
}
return debug_ipc::ExceptionType::kGeneral;
default:
return debug_ipc::ExceptionType::kUnknown;
}
}
} // namespace arch
} // namespace debug_agent