rhdxmr-publish-test2 0.1.0

rhdxmr's publish test crate
// Copyright 2020 Authors of Red Sift
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Utilities to work with registers in KProbes and UProbes

use crate::bindings::*;
use cty::*;

#[derive(Copy, Clone)]
pub struct Registers {
    pub ctx: *mut pt_regs,
}

impl From<*mut c_void> for Registers {
    #[inline]
    fn from(ptr: *mut c_void) -> Registers {
        Registers {
            ctx: (ptr as *mut pt_regs),
        }
    }
}

/// Convenience functions wrapping the architecture native `struct pt_regs`
///
/// These methods are ports of the [`PT_REGS_*`](https://elixir.bootlin.com/linux/v5.0/source/tools/testing/selftests/bpf/bpf_helpers.h#L270) macros in the Linux kernel.
///
/// The only supported architectures by RedBPF are aarch64/arm64 and
/// x86_64, therefore we only return 64bit registers, as generated by
/// bindgen.
impl Registers {
    /// First parameter to the function
    #[inline]
    pub fn parm1(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).di
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[0]
        }
    }

    /// Second parameter to the function
    #[inline]
    pub fn parm2(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).si
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[1]
        }
    }

    /// Third parameter to the function
    #[inline]
    pub fn parm3(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).dx
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[2]
        }
    }

    /// Fourth parameter to the function
    #[inline]
    pub fn parm4(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).cx
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[3]
        }
    }

    /// Fifth parameter to the function
    #[inline]
    pub fn parm5(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).r8
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[4]
        }
    }

    /// Procedure link pointer (return to this IP)
    #[inline]
    pub fn ret(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).sp
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[30]
        }
    }

    /// Frame pointer
    #[inline]
    pub fn fp(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).bp
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[29]
        }
    }

    /// Return value
    #[inline]
    pub fn rc(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).ax
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.regs[0]
        }
    }

    /// Stack pointer
    #[inline]
    pub fn sp(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).sp
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.sp
        }
    }

    /// Instruction pointer
    #[inline]
    pub fn ip(&self) -> u64 {
        #[cfg(target_arch = "x86_64")]
        unsafe {
            (*self.ctx).ip
        }

        #[cfg(target_arch = "aarch64")]
        unsafe {
            (*self.ctx).__bindgen_anon_1.user_regs.pc
        }
    }
}