Skip to content

Commit d9056a9

Browse files
committed
Added getRegisterArgumentClasses, getRegisterArgumentClassLists, getRegisterArgumentLists, getRegisterArgumentListRegs, and getRegisterArgumentListKind.
1 parent b157aa0 commit d9056a9

File tree

2 files changed

+213
-0
lines changed

2 files changed

+213
-0
lines changed

binaryninjacore.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,6 +2648,12 @@ extern "C"
26482648
bool (*projectIsValid)(void* ctxt, BNProject* view);
26492649
} BNPluginCommand;
26502650

2651+
enum BNRegisterListKind
2652+
{
2653+
REGISTER_LIST_KIND_INTEGER_SEMANTICS = 0,
2654+
REGISTER_LIST_KIND_FLOAT_SEMANTICS = 1,
2655+
};
2656+
26512657
typedef struct BNCustomCallingConvention
26522658
{
26532659
void* context;
@@ -2660,6 +2666,12 @@ extern "C"
26602666
uint32_t* (*getFloatArgumentRegisters)(void* ctxt, size_t* count);
26612667
void (*freeRegisterList)(void* ctxt, uint32_t* regs, size_t len);
26622668

2669+
uint32_t* (*getRegisterArgumentClasses)(void* ctxt, size_t* count);
2670+
uint32_t* (*getRegisterArgumentClassLists)(void* ctxt, uint32_t classId, size_t* count);
2671+
uint32_t* (*getRegisterArgumentLists)(void* ctxt, size_t* count);
2672+
uint32_t* (*getRegisterArgumentListRegs)(void* ctxt, uint32_t regListId, size_t* count);
2673+
BNRegisterListKind (*getRegisterArgumentListKind)(void* ctxt, uint32_t regListId);
2674+
26632675
bool (*areArgumentRegistersSharedIndex)(void* ctxt);
26642676
bool (*isStackReservedForArgumentRegisters)(void* ctxt);
26652677
bool (*isStackAdjustedOnReturn)(void* ctxt);
@@ -7123,6 +7135,14 @@ extern "C"
71237135
BINARYNINJACOREAPI uint32_t* BNGetIntegerArgumentRegisters(BNCallingConvention* cc, size_t* count);
71247136
BINARYNINJACOREAPI uint32_t* BNGetFloatArgumentRegisters(BNCallingConvention* cc, size_t* count);
71257137
BINARYNINJACOREAPI bool BNAreArgumentRegistersSharedIndex(BNCallingConvention* cc);
7138+
7139+
// New register-list/class API
7140+
BINARYNINJACOREAPI uint32_t* BNGetRegisterArgumentClasses(BNCallingConvention* cc, size_t* count);
7141+
BINARYNINJACOREAPI uint32_t* BNGetRegisterArgumentClassLists(BNCallingConvention* cc, uint32_t classId, size_t* count);
7142+
BINARYNINJACOREAPI uint32_t* BNGetRegisterArgumentLists(BNCallingConvention* cc, size_t* count);
7143+
BINARYNINJACOREAPI uint32_t* BNGetRegisterArgumentListRegs(BNCallingConvention* cc, uint32_t regListId, size_t* count);
7144+
BINARYNINJACOREAPI BNRegisterListKind BNGetRegisterArgumentListKind(BNCallingConvention* cc, uint32_t regListId);
7145+
71267146
BINARYNINJACOREAPI bool BNAreArgumentRegistersUsedForVarArgs(BNCallingConvention* cc);
71277147
BINARYNINJACOREAPI bool BNIsStackReservedForArgumentRegisters(BNCallingConvention* cc);
71287148
BINARYNINJACOREAPI bool BNIsStackAdjustedOnReturn(BNCallingConvention* cc);

rust/src/calling_convention.rs

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ use crate::variable::Variable;
3434
// CallingConvention impl
3535
// dataflow callbacks
3636

37+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
38+
#[repr(u32)]
39+
pub enum RegisterListKind {
40+
IntegerSemantics = 0,
41+
FloatSemantics = 1,
42+
}
43+
3744
pub trait CallingConvention: Sync {
3845
fn caller_saved_registers(&self) -> Vec<RegisterId>;
3946
fn callee_saved_registers(&self) -> Vec<RegisterId>;
@@ -53,6 +60,27 @@ pub trait CallingConvention: Sync {
5360

5461
fn implicitly_defined_registers(&self) -> Vec<RegisterId>;
5562
fn are_argument_registers_used_for_var_args(&self) -> bool;
63+
64+
// Register-list/class based API with default implementations
65+
fn register_argument_classes(&self) -> Vec<u32> {
66+
Vec::new()
67+
}
68+
69+
fn register_argument_class_lists(&self, _class_id: u32) -> Vec<u32> {
70+
Vec::new()
71+
}
72+
73+
fn register_argument_lists(&self) -> Vec<u32> {
74+
Vec::new()
75+
}
76+
77+
fn register_argument_list_regs(&self, _reg_list_id: u32) -> Vec<RegisterId> {
78+
Vec::new()
79+
}
80+
81+
fn register_argument_list_kind(&self, _reg_list_id: u32) -> RegisterListKind {
82+
RegisterListKind::IntegerSemantics
83+
}
5684
}
5785

5886
pub fn register_calling_convention<A, C>(arch: &A, name: &str, cc: C) -> Ref<CoreCallingConvention>
@@ -290,6 +318,102 @@ where
290318
})
291319
}
292320

321+
extern "C" fn cb_register_argument_classes<C>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
322+
where
323+
C: CallingConvention,
324+
{
325+
ffi_wrap!("CallingConvention::register_argument_classes", unsafe {
326+
let ctxt = &*(ctxt as *mut CustomCallingConventionContext<C>);
327+
let mut class_ids = ctxt.cc.register_argument_classes();
328+
329+
// SAFETY: `count` is an out parameter
330+
*count = class_ids.len();
331+
let ptr = class_ids.as_mut_ptr();
332+
std::mem::forget(class_ids);
333+
ptr
334+
})
335+
}
336+
337+
extern "C" fn cb_register_argument_class_lists<C>(
338+
ctxt: *mut c_void,
339+
class_id: u32,
340+
count: *mut usize,
341+
) -> *mut u32
342+
where
343+
C: CallingConvention,
344+
{
345+
ffi_wrap!("CallingConvention::register_argument_class_lists", unsafe {
346+
let ctxt = &*(ctxt as *mut CustomCallingConventionContext<C>);
347+
let mut list_ids = ctxt.cc.register_argument_class_lists(class_id);
348+
349+
// SAFETY: `count` is an out parameter
350+
*count = list_ids.len();
351+
let ptr = list_ids.as_mut_ptr();
352+
std::mem::forget(list_ids);
353+
ptr
354+
})
355+
}
356+
357+
extern "C" fn cb_register_argument_lists<C>(
358+
ctxt: *mut c_void,
359+
count: *mut usize,
360+
) -> *mut u32
361+
where
362+
C: CallingConvention,
363+
{
364+
ffi_wrap!("CallingConvention::register_argument_lists", unsafe {
365+
let ctxt = &*(ctxt as *mut CustomCallingConventionContext<C>);
366+
let mut list_ids = ctxt.cc.register_argument_lists();
367+
368+
// SAFETY: `count` is an out parameter
369+
*count = list_ids.len();
370+
let ptr = list_ids.as_mut_ptr();
371+
std::mem::forget(list_ids);
372+
ptr
373+
})
374+
}
375+
376+
extern "C" fn cb_register_argument_list_regs<C>(
377+
ctxt: *mut c_void,
378+
reg_list_id: u32,
379+
count: *mut usize,
380+
) -> *mut u32
381+
where
382+
C: CallingConvention,
383+
{
384+
ffi_wrap!("CallingConvention::register_argument_list_regs", unsafe {
385+
let ctxt = &*(ctxt as *mut CustomCallingConventionContext<C>);
386+
let mut regs: Vec<_> = ctxt
387+
.cc
388+
.register_argument_list_regs(reg_list_id)
389+
.iter()
390+
.map(|r| r.0)
391+
.collect();
392+
393+
// SAFETY: `count` is an out parameter
394+
*count = regs.len();
395+
let ptr = regs.as_mut_ptr();
396+
std::mem::forget(regs);
397+
ptr
398+
})
399+
}
400+
401+
extern "C" fn cb_register_argument_list_kind<C>(
402+
ctxt: *mut c_void,
403+
reg_list_id: u32,
404+
) -> BNRegisterListKind
405+
where
406+
C: CallingConvention,
407+
{
408+
ffi_wrap!("CallingConvention::register_argument_list_kind", unsafe {
409+
let ctxt = &*(ctxt as *mut CustomCallingConventionContext<C>);
410+
match ctxt.cc.register_argument_list_kind(reg_list_id) {
411+
RegisterListKind::IntegerSemantics => BNRegisterListKind::REGISTER_LIST_KIND_INTEGER_SEMANTICS,
412+
RegisterListKind::FloatSemantics => BNRegisterListKind::REGISTER_LIST_KIND_FLOAT_SEMANTICS,
413+
}
414+
})
415+
}
416+
293417
#[allow(clippy::extra_unused_type_parameters)]
294418
extern "C" fn cb_incoming_reg_value<C>(
295419
_ctxt: *mut c_void,
@@ -392,6 +516,12 @@ where
392516
getFloatArgumentRegisters: Some(cb_float_args::<C>),
393517
freeRegisterList: Some(cb_free_register_list),
394518

519+
getRegisterArgumentClasses: Some(cb_register_argument_classes::<C>),
520+
getRegisterArgumentClassLists: Some(cb_register_argument_class_lists::<C>),
521+
getRegisterArgumentListRegs: Some(cb_register_argument_list_regs::<C>),
522+
getRegisterArgumentLists: Some(cb_register_argument_lists::<C>),
523+
getRegisterArgumentListKind: Some(cb_register_argument_list_kind::<C>),
524+
395525
areArgumentRegistersSharedIndex: Some(cb_arg_shared_index::<C>),
396526
isStackReservedForArgumentRegisters: Some(cb_stack_reserved_arg_regs::<C>),
397527
isStackAdjustedOnReturn: Some(cb_stack_adjusted_on_return::<C>),
@@ -611,6 +741,69 @@ impl CallingConvention for CoreCallingConvention {
611741
}
612742
}
613743

744+
fn register_argument_classes(&self) -> Vec<u32> {
745+
unsafe {
746+
let mut count = 0;
747+
let classes_ptr = BNGetRegisterArgumentClasses(self.handle, &mut count);
748+
let classes: Vec<u32> = std::slice::from_raw_parts(classes_ptr, count)
749+
.iter()
750+
.copied()
751+
.collect();
752+
BNFreeRegisterList(classes_ptr);
753+
classes
754+
}
755+
}
756+
757+
fn register_argument_class_lists(&self, class_id: u32) -> Vec<u32> {
758+
unsafe {
759+
let mut count = 0;
760+
let lists_ptr = BNGetRegisterArgumentClassLists(self.handle, class_id, &mut count);
761+
let lists: Vec<u32> = std::slice::from_raw_parts(lists_ptr, count)
762+
.iter()
763+
.copied()
764+
.collect();
765+
BNFreeRegisterList(lists_ptr);
766+
lists
767+
}
768+
}
769+
770+
fn register_argument_list_regs(&self, reg_list_id: u32) -> Vec<RegisterId> {
771+
unsafe {
772+
let mut count = 0;
773+
let regs_ptr = BNGetRegisterArgumentListRegs(self.handle, reg_list_id, &mut count);
774+
let regs: Vec<RegisterId> = std::slice::from_raw_parts(regs_ptr, count)
775+
.iter()
776+
.copied()
777+
.map(RegisterId::from)
778+
.collect();
779+
BNFreeRegisterList(regs_ptr);
780+
regs
781+
}
782+
}
783+
784+
fn register_argument_lists(&self) -> Vec<u32> {
785+
unsafe {
786+
let mut count = 0;
787+
let lists_ptr = BNGetRegisterArgumentLists(self.handle, &mut count);
788+
let lists: Vec<u32> = std::slice::from_raw_parts(lists_ptr, count)
789+
.iter()
790+
.copied()
791+
.collect();
792+
BNFreeRegisterList(lists_ptr);
793+
lists
794+
}
795+
}
796+
797+
fn register_argument_list_kind(&self, reg_list_id: u32) -> RegisterListKind {
798+
unsafe {
799+
let kind = BNGetRegisterArgumentListKind(self.handle, reg_list_id);
800+
match kind {
801+
BNRegisterListKind::REGISTER_LIST_KIND_INTEGER_SEMANTICS => RegisterListKind::IntegerSemantics,
802+
BNRegisterListKind::REGISTER_LIST_KIND_FLOAT_SEMANTICS => RegisterListKind::FloatSemantics,
803+
}
804+
}
805+
}
806+
614807
fn arg_registers_shared_index(&self) -> bool {
615808
unsafe { BNAreArgumentRegistersSharedIndex(self.handle) }
616809
}

0 commit comments

Comments
 (0)