blob: e28a4a27b37601fb2941c0f62f8c30b949945063 [file] [log] [blame]
// Copyright 2019 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 <lib/backtrace-request/backtrace-request-utils.h>
#include <zircon/syscalls.h>
#include <lib/backtrace-request/backtrace-request.h>
namespace {
bool have_swbreak_magic(const zx_thread_state_general_regs_t* regs) {
#if defined(__x86_64__)
return regs->rax == BACKTRACE_REQUEST_MAGIC;
#elif defined(__aarch64__)
return regs->r[0] == BACKTRACE_REQUEST_MAGIC;
#else
return false;
#endif
}
} // namespace
// TODO: consider disabling this feature for non-development builds.
bool is_backtrace_request(zx_excp_type_t excp_type, const zx_thread_state_general_regs_t* regs) {
return excp_type == ZX_EXCP_SW_BREAKPOINT && regs != nullptr && have_swbreak_magic(regs);
}
zx_status_t cleanup_backtrace_request(zx_handle_t thread, zx_thread_state_general_regs_t* regs) {
#if defined(__x86_64__)
// On x86, the pc is left at one past the s/w break insn,
// so there's nothing more we need to do.
return ZX_OK;
#elif defined(__aarch64__)
// Skip past the brk instruction.
regs->pc += 4;
return zx_thread_write_state(thread, ZX_THREAD_STATE_GENERAL_REGS, regs, sizeof(*regs));
#else
return ZX_ERR_NOT_SUPPORTED;
#endif
}