blob: a20a8b119a1d2c30851f50b39a6dc98f912c420f [file]
// Copyright 2026 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
// TODO(https://fxbug.dev/507423574): Remove these FFI entry points once all C++ callers of
// Backtrace are ported to Rust.
use super::{Backtrace, FrameType};
use libc::stdio::FILE;
/// FFI entry point for C++ `Backtrace::reset()`.
///
/// # Safety
///
/// `bt` must be a valid, aligned pointer to an initialized [`Backtrace`] with exclusive access for
/// the duration of this call (including a valid [`FrameType`] in `first_frame_type` and
/// `size <= Backtrace::MAX_SIZE`).
#[unsafe(no_mangle)]
unsafe extern "C" fn rust_backtrace_reset(bt: *mut Backtrace) {
// SAFETY: The caller guarantees `bt` is a valid, aligned pointer to an initialized `Backtrace`
// with exclusive access for the duration of this call.
unsafe { (*bt).reset() };
}
/// FFI entry point for C++ `Backtrace::push_back(vaddr_t)`.
///
/// # Safety
///
/// `bt` must be a valid, aligned pointer to an initialized [`Backtrace`] with exclusive access for
/// the duration of this call (including a valid [`FrameType`] in `first_frame_type` and
/// `size <= Backtrace::MAX_SIZE`).
#[unsafe(no_mangle)]
unsafe extern "C" fn rust_backtrace_push_back(bt: *mut Backtrace, addr: usize) {
// SAFETY: The caller guarantees `bt` is a valid, aligned pointer to an initialized `Backtrace`
// with exclusive access for the duration of this call.
unsafe { (*bt).push_back(addr) };
}
/// FFI entry point for C++ `Backtrace::set_first_frame_type(FrameType)`.
///
/// # Safety
///
/// `bt` must be a valid, aligned pointer to an initialized [`Backtrace`] with exclusive access for
/// the duration of this call (including a valid [`FrameType`] in `first_frame_type` and
/// `size <= Backtrace::MAX_SIZE`).
#[unsafe(no_mangle)]
unsafe extern "C" fn rust_backtrace_set_first_frame_type(bt: *mut Backtrace, ty: u32) {
let ty = match ty {
1 => FrameType::PreciseLocation,
_ => FrameType::ReturnAddress,
};
// SAFETY: The caller guarantees `bt` is a valid, aligned pointer to an initialized `Backtrace`
// with exclusive access for the duration of this call.
unsafe { (*bt).set_first_frame_type(ty) };
}
/// FFI entry point for C++ `Backtrace::Print(FILE*)`.
///
/// # Safety
///
/// `bt` must be a valid, aligned pointer to an initialized [`Backtrace`] with shared read access
/// for the duration of this call (including a valid [`FrameType`] in `first_frame_type` and
/// `size <= Backtrace::MAX_SIZE`), and the caller must uphold [`Backtrace::print_to_file`]'s
/// safety contract for `file`.
#[unsafe(no_mangle)]
unsafe extern "C" fn rust_backtrace_print(bt: *const Backtrace, file: *mut FILE) {
// SAFETY: The caller guarantees `bt` is a valid, aligned pointer to an initialized `Backtrace`
// with shared read access for the duration of this call, and upholds
// `Backtrace::print_to_file`'s safety contract for `file`.
unsafe { (*bt).print_to_file(file) };
}
/// FFI entry point for C++ `Backtrace::PrintWithoutVersion(FILE*)`.
///
/// # Safety
///
/// `bt` must be a valid, aligned pointer to an initialized [`Backtrace`] with shared read access
/// for the duration of this call (including a valid [`FrameType`] in `first_frame_type` and
/// `size <= Backtrace::MAX_SIZE`), and the caller must uphold
/// [`Backtrace::print_without_version`]'s safety contract for `file`.
#[unsafe(no_mangle)]
unsafe extern "C" fn rust_backtrace_print_without_version(bt: *const Backtrace, file: *mut FILE) {
// SAFETY: The caller guarantees `bt` is a valid, aligned pointer to an initialized `Backtrace`
// with shared read access for the duration of this call, and upholds
// `Backtrace::print_without_version`'s safety contract for `file`.
unsafe { (*bt).print_without_version(file) };
}