blob: 14151258d18bd4d33a2c44fea08be296e4502b08 [file] [log] [blame]
// Copyright 2018 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.
#ifndef SRC_DEVELOPER_DEBUG_DEBUG_AGENT_ARCH_H_
#define SRC_DEVELOPER_DEBUG_DEBUG_AGENT_ARCH_H_
#include <lib/zx/process.h>
#include <lib/zx/thread.h>
#include <zircon/syscalls/debug.h>
#include <zircon/syscalls/exception.h>
#include "src/developer/debug/debug_agent/arch_helpers.h"
#include "src/developer/debug/debug_agent/arch_types.h"
#include "src/developer/debug/ipc/protocol.h"
namespace debug_agent {
class DebuggedThread;
class DebugRegisters;
class ThreadHandle;
namespace arch {
extern const BreakInstructionType kBreakInstruction;
// Class in charge of abstracting the low-level functionalities of the platform.
//
// TODO(brettw) TRhis object is not currently used for any abstractions so we should be able to make
// all functions standalone in the arch namespace.
class ArchProvider {
public:
ArchProvider() = default;
virtual ~ArchProvider() = default;
::debug_ipc::Arch GetArch();
uint32_t hw_breakpoint_count() const { return hw_breakpoint_count_; }
void set_hw_breakpoint_count(uint32_t count) { hw_breakpoint_count_ = count; }
uint32_t watchpoint_count() const { return watchpoint_count_; }
void set_watchpoint_count(uint32_t count) { watchpoint_count_ = count; }
// General Exceptions ----------------------------------------------------------------------------
// Converts an architecture-specific exception record to a cross-platform one.
static debug_ipc::ExceptionRecord FillExceptionRecord(const zx_exception_report_t& in);
// Software Exceptions ---------------------------------------------------------------------------
// Returns the address of the breakpoint instruction given the address of
// a software breakpoint exception.
virtual uint64_t BreakpointInstructionForSoftwareExceptionAddress(uint64_t exception_addr);
// Returns the instruction following the one causing the given software
// exception.
uint64_t NextInstructionForSoftwareExceptionAddress(uint64_t exception_addr);
uint64_t NextInstructionForWatchpointHit(uint64_t exception_addr);
// Address of the instruction that caused the watchpoint exception. Also returns the slot (which
// register triggered it).
//
// Returns {0, -1} on error or not found.
virtual std::pair<debug_ipc::AddressRange, int> InstructionForWatchpointHit(
const DebugRegisters& regs) const;
// Returns true if there is a breakpoint instruction at the given address.
// This doesn't just check equality of kBreakInstruction which is guaranteed
// to be used for our breakpoints, but also checks other encodings that may
// have been written into the program.
virtual bool IsBreakpointInstruction(zx::process& process, uint64_t address);
// Converts the given register structure to a vector of debug_ipc registers.
static void SaveGeneralRegs(const zx_thread_state_general_regs& input,
std::vector<debug_ipc::Register>* out);
// The registers in the given category are appended to the given output vector.
virtual zx_status_t ReadRegisters(const debug_ipc::RegisterCategory& cat, const zx::thread&,
std::vector<debug_ipc::Register>* out);
// The registers must all be in the same category.
virtual zx_status_t WriteRegisters(const debug_ipc::RegisterCategory&,
const std::vector<debug_ipc::Register>& registers,
zx::thread*);
// Hardware Exceptions ---------------------------------------------------------------------------
// Returns the address of the instruction that hit the exception from the
// address reported by the exception.
uint64_t BreakpointInstructionForHardwareExceptionAddress(uint64_t exception_addr);
// Currently HW notifications can mean both a single step or a hardware debug
// register exception. We need platform-specific queries to figure which one
// is it.
virtual debug_ipc::ExceptionType DecodeExceptionType(const DebuggedThread&,
uint32_t exception_type);
protected:
uint32_t hw_breakpoint_count_ = 0;
uint32_t watchpoint_count_ = 0;
};
} // namespace arch
} // namespace debug_agent
#endif // SRC_DEVELOPER_DEBUG_DEBUG_AGENT_ARCH_H_