use crate::cpp::StdVector;
pub use crate::manual_bindings::ReOxideInterface;
use crate::manual_bindings::ghidra_throw;
use std::{ffi::c_char, panic::PanicHookInfo};
#[repr(C)]
pub struct Context {
pub arch: *mut Architecture,
pub stackspace: *mut AddrSpace,
pub reoxide: *mut ReOxideInterface,
}
#[repr(C)]
pub struct ExtraArgs {
pub group_name: *const c_char,
pub extra_arg: u64,
}
opaque!(OpaquePlugin);
opaque!(OpaqueAction);
opaque!(OpaqueRule);
#[repr(C)]
pub struct ActionDefinition {
pub name: *const c_char,
pub constructor: extern "C-unwind" fn(
*const Context,
*mut OpaquePlugin,
*const ExtraArgs,
) -> *mut OpaqueAction,
pub destructor: extern "C-unwind" fn(*mut OpaqueAction),
pub apply: extern "C-unwind" fn(*mut OpaqueAction, *mut Funcdata) -> i32,
}
#[repr(C)]
pub struct RuleDefinition {
pub name: *const c_char,
pub constructor: extern "C-unwind" fn(
*const Context,
*mut OpaquePlugin,
*const ExtraArgs,
) -> *mut OpaqueRule,
pub destructor: extern "C-unwind" fn(*mut OpaqueRule),
pub oplist: extern "C-unwind" fn(*const OpaqueRule, *mut StdVector<OpCode>),
pub apply: extern "C-unwind" fn(*mut OpaqueRule, *mut PcodeOp, *mut Funcdata) -> i32,
}
#[repr(C)]
pub struct DefinitionTable<T: ?Sized> {
pub table: T,
}
unsafe impl<T: ?Sized> Sync for DefinitionTable<T> {}
pub struct CreationContext<'context, 'name, T> {
pub arch: &'context mut Architecture,
pub stack_space: &'context mut AddrSpace,
pub reoxide: &'context mut ReOxideInterface,
pub plugin: &'context mut T,
pub group_name: &'name str,
pub extra_args: u64,
}
#[repr(i32)]
pub enum ApplyResult {
Applied = 1,
NotApplied = 0,
}
pub trait Rule<'a> {
type PluginContext;
fn new(context: CreationContext<'a, '_, Self::PluginContext>) -> Self;
fn op_list(&self) -> Vec<OpCode>;
fn apply(&mut self, op: &mut PcodeOp, data: &mut Funcdata) -> ApplyResult;
}
pub trait Action<'a> {
type PluginContext;
fn new(context: CreationContext<'a, '_, Self::PluginContext>) -> Self;
fn apply(&mut self, data: &mut Funcdata) -> ApplyResult;
}
pub fn panic_hook(info: &PanicHookInfo) {
let mut msg = String::new();
if let Some(s) = info.payload().downcast_ref::<&str>() {
msg.push_str(s);
} else if let Some(s) = info.payload().downcast_ref::<String>() {
msg.push_str(s);
}
msg.push('\n');
if let Some(l) = info.location() {
msg.push_str(&format!("In file {}, line {}\n", l.file(), l.line()));
}
let bt = std::backtrace::Backtrace::force_capture();
msg.push_str(&format!("Backtrace:\n\n{}", bt));
ghidra_throw(&msg);
}
pub use crate::generated::*;
pub use reoxide_proc::{action, plugin, rule};