Skip to main content

libdd_libunwind_sys/
libunwind_x86_64.rs

1// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4// Context is platform ucontext_t (from libc)
5pub type UnwContext = libc::ucontext_t;
6
7pub type UnwWord = u64;
8
9// Opaque cursor structure
10#[repr(C)]
11#[derive(Debug, Copy, Clone)]
12pub struct UnwCursor {
13    pub opaque: [UnwWord; 127],
14}
15
16// Opaque address space handle (unw_addr_space_t)
17pub type UnwAddrSpaceT = *mut libc::c_void;
18
19#[repr(C)]
20pub struct UnwAccessors;
21
22// This is a subset of the libunwind API.
23
24extern "C" {
25    #[link_name = "_ULx86_64_init_local2"]
26    pub fn unw_init_local2(cursor: *mut UnwCursor, context: *mut UnwContext, flag: i32) -> i32;
27    #[link_name = "_Ux86_64_getcontext"]
28    pub fn unw_getcontext(context: *mut UnwContext) -> i32;
29    #[link_name = "_ULx86_64_step"]
30    pub fn unw_step(cursor: *mut UnwCursor) -> i32;
31    #[link_name = "_ULx86_64_get_reg"]
32    pub fn unw_get_reg(cursor: *mut UnwCursor, reg: i32, valp: *mut UnwWord) -> i32;
33    #[link_name = "_ULx86_64_get_proc_name"]
34    pub fn unw_get_proc_name(
35        cursor: *mut UnwCursor,
36        name: *mut libc::c_char,
37        len: usize,
38        offset: *mut u64,
39    ) -> i32;
40    #[link_name = "unw_backtrace2"]
41    pub fn unw_backtrace2(
42        buffer: *mut *mut ::std::os::raw::c_void,
43        size: i32,
44        context: *mut UnwContext,
45        flag: i32,
46    ) -> i32;
47}
48
49// Remote unwinding API. Uses _Ux86_64_* symbols from libunwind-x86_64
50// because the _ULx86_64_* dont have remote support
51#[allow(improper_ctypes)]
52extern "C" {
53    #[link_name = "_Ux86_64_init_remote"]
54    pub fn unw_init_remote(
55        cursor: *mut UnwCursor,
56        addr_space: UnwAddrSpaceT,
57        arg: *mut libc::c_void,
58    ) -> i32;
59    #[link_name = "_Ux86_64_step"]
60    pub fn unw_step_remote(cursor: *mut UnwCursor) -> i32;
61    #[link_name = "_Ux86_64_get_reg"]
62    pub fn unw_get_reg_remote(cursor: *mut UnwCursor, reg: i32, valp: *mut UnwWord) -> i32;
63    #[link_name = "_Ux86_64_get_proc_name"]
64    pub fn unw_get_proc_name_remote(
65        cursor: *mut UnwCursor,
66        name: *mut libc::c_char,
67        len: usize,
68        offset: *mut UnwWord,
69    ) -> i32;
70    #[link_name = "_Ux86_64_create_addr_space"]
71    pub fn unw_create_addr_space(accessors: *mut UnwAccessors, byteorder: i32) -> UnwAddrSpaceT;
72    #[link_name = "_Ux86_64_destroy_addr_space"]
73    pub fn unw_destroy_addr_space(addr_space: UnwAddrSpaceT);
74    pub fn _UPT_create(pid: libc::pid_t) -> *mut libc::c_void;
75    pub fn _UPT_destroy(upt_info: *mut libc::c_void);
76    pub static _UPT_accessors: UnwAccessors;
77}
78
79// x86_64 register definitions for libunwind
80pub const UNW_REG_IP: i32 = 16; // Instruction Pointer
81pub const UNW_REG_SP: i32 = 17; // Stack Pointer
82pub const UNW_REG_FP: i32 = 15; // Frame Pointer
83pub const UNW_INIT_SIGNAL_FRAME: i32 = 1;