Skip to content

Commit b34ddd0

Browse files
committed
Pass length to free flag conditions list callback and remove libc from rust api
Allows language bindings like rust to free conditions lists sanely
1 parent 121c165 commit b34ddd0

File tree

14 files changed

+134
-93
lines changed

14 files changed

+134
-93
lines changed

arch/msp430/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

arch/riscv/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

architecture.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ BNFlagConditionForSemanticClass* Architecture::GetFlagConditionsForSemanticFlagG
477477
}
478478

479479

480-
void Architecture::FreeFlagConditionsForSemanticFlagGroupCallback(void*, BNFlagConditionForSemanticClass* conditions)
480+
void Architecture::FreeFlagConditionsForSemanticFlagGroupCallback(void*, BNFlagConditionForSemanticClass* conditions, size_t)
481481
{
482482
delete[] conditions;
483483
}

binaryninjaapi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7931,7 +7931,7 @@ namespace BinaryNinja {
79317931
static BNFlagConditionForSemanticClass* GetFlagConditionsForSemanticFlagGroupCallback(
79327932
void* ctxt, uint32_t semGroup, size_t* count);
79337933
static void FreeFlagConditionsForSemanticFlagGroupCallback(
7934-
void* ctxt, BNFlagConditionForSemanticClass* conditions);
7934+
void* ctxt, BNFlagConditionForSemanticClass* conditions, size_t count);
79357935
static uint32_t* GetFlagsWrittenByFlagWriteTypeCallback(void* ctxt, uint32_t writeType, size_t* count);
79367936
static uint32_t GetSemanticClassForFlagWriteTypeCallback(void* ctxt, uint32_t writeType);
79377937
static size_t GetFlagWriteLowLevelILCallback(void* ctxt, BNLowLevelILOperation op, size_t size,

binaryninjacore.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 85
40+
#define BN_CURRENT_CORE_ABI_VERSION 86
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 82
47+
#define BN_MINIMUM_CORE_ABI_VERSION 86
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -1854,7 +1854,7 @@ extern "C"
18541854
uint32_t* (*getFlagsRequiredForSemanticFlagGroup)(void* ctxt, uint32_t semGroup, size_t* count);
18551855
BNFlagConditionForSemanticClass* (*getFlagConditionsForSemanticFlagGroup)(
18561856
void* ctxt, uint32_t semGroup, size_t* count);
1857-
void (*freeFlagConditionsForSemanticFlagGroup)(void* ctxt, BNFlagConditionForSemanticClass* conditions);
1857+
void (*freeFlagConditionsForSemanticFlagGroup)(void* ctxt, BNFlagConditionForSemanticClass* conditions, size_t count);
18581858
uint32_t* (*getFlagsWrittenByFlagWriteType)(void* ctxt, uint32_t writeType, size_t* count);
18591859
uint32_t (*getSemanticClassForFlagWriteType)(void* ctxt, uint32_t writeType);
18601860
size_t (*getFlagWriteLowLevelIL)(void* ctxt, BNLowLevelILOperation op, size_t size, uint32_t flagWriteType,

python/architecture.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ def _get_flag_conditions_for_semantic_flag_group(self, ctxt, sem_group, count):
914914
count[0] = 0
915915
return None
916916

917-
def _free_flag_conditions_for_semantic_flag_group(self, ctxt, conditions):
917+
def _free_flag_conditions_for_semantic_flag_group(self, ctxt, conditions, count):
918918
try:
919919
buf = ctypes.cast(conditions, ctypes.c_void_p)
920920
if buf.value not in self._pending_condition_lists:

rust/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ noexports = []
1111
[dependencies]
1212
lazy_static = "1.4.0"
1313
log = { version = "0.4", features = ["std"] }
14-
libc = "0.2"
1514
rayon = { version = "1.8", optional = true }
1615
binaryninjacore-sys = { path = "binaryninjacore-sys" }
1716

rust/src/architecture.rs

Lines changed: 84 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,117 +1941,133 @@ where
19411941
None => BnString::new("invalid_flag_group").into_raw(),
19421942
}
19431943
}
1944-
1944+
19451945
extern "C" fn cb_registers_full_width<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
19461946
where
19471947
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
19481948
{
19491949
let custom_arch = unsafe { &*(ctxt as *mut A) };
1950-
let mut regs = custom_arch.registers_full_width();
1950+
let mut regs: Vec<_> = custom_arch
1951+
.registers_full_width()
1952+
.iter()
1953+
.map(|r| r.id())
1954+
.collect();
19511955

19521956
// SAFETY: `count` is an out parameter
19531957
unsafe { *count = regs.len() };
19541958
let regs_ptr = regs.as_mut_ptr();
19551959
mem::forget(regs);
1956-
regs_ptr as *mut _
1960+
regs_ptr
19571961
}
19581962

19591963
extern "C" fn cb_registers_all<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
19601964
where
19611965
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
19621966
{
19631967
let custom_arch = unsafe { &*(ctxt as *mut A) };
1964-
let mut regs = custom_arch.registers_all();
1968+
let mut regs: Vec<_> = custom_arch.registers_all().iter().map(|r| r.id()).collect();
19651969

19661970
// SAFETY: `count` is an out parameter
19671971
unsafe { *count = regs.len() };
19681972
let regs_ptr = regs.as_mut_ptr();
19691973
mem::forget(regs);
1970-
regs_ptr as *mut _
1974+
regs_ptr
19711975
}
19721976

19731977
extern "C" fn cb_registers_global<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
19741978
where
19751979
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
19761980
{
19771981
let custom_arch = unsafe { &*(ctxt as *mut A) };
1978-
let mut regs = custom_arch.registers_global();
1982+
let mut regs: Vec<_> = custom_arch
1983+
.registers_global()
1984+
.iter()
1985+
.map(|r| r.id())
1986+
.collect();
19791987

19801988
// SAFETY: `count` is an out parameter
19811989
unsafe { *count = regs.len() };
19821990
let regs_ptr = regs.as_mut_ptr();
19831991
mem::forget(regs);
1984-
regs_ptr as *mut _
1992+
regs_ptr
19851993
}
19861994

19871995
extern "C" fn cb_registers_system<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
19881996
where
19891997
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
19901998
{
19911999
let custom_arch = unsafe { &*(ctxt as *mut A) };
1992-
let mut regs = custom_arch.registers_system();
2000+
let mut regs: Vec<_> = custom_arch
2001+
.registers_system()
2002+
.iter()
2003+
.map(|r| r.id())
2004+
.collect();
19932005

19942006
// SAFETY: `count` is an out parameter
19952007
unsafe { *count = regs.len() };
19962008
let regs_ptr = regs.as_mut_ptr();
19972009
mem::forget(regs);
1998-
regs_ptr as *mut _
2010+
regs_ptr
19992011
}
20002012

20012013
extern "C" fn cb_flags<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
20022014
where
20032015
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
20042016
{
20052017
let custom_arch = unsafe { &*(ctxt as *mut A) };
2006-
let mut flags = custom_arch.flags();
2018+
let mut flags: Vec<_> = custom_arch.flags().iter().map(|f| f.id()).collect();
20072019

20082020
// SAFETY: `count` is an out parameter
20092021
unsafe { *count = flags.len() };
2010-
let regs_ptr = flags.as_mut_ptr();
2022+
let flags_ptr = flags.as_mut_ptr();
20112023
mem::forget(flags);
2012-
regs_ptr as *mut _
2024+
flags_ptr
20132025
}
20142026

20152027
extern "C" fn cb_flag_write_types<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
20162028
where
20172029
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
20182030
{
20192031
let custom_arch = unsafe { &*(ctxt as *mut A) };
2020-
let mut flag_writes = custom_arch.flag_write_types();
2032+
let mut flag_writes: Vec<_> = custom_arch
2033+
.flag_write_types()
2034+
.iter()
2035+
.map(|f| f.id())
2036+
.collect();
20212037

20222038
// SAFETY: `count` is an out parameter
20232039
unsafe { *count = flag_writes.len() };
2024-
let regs_ptr = flag_writes.as_mut_ptr();
2040+
let flags_ptr = flag_writes.as_mut_ptr();
20252041
mem::forget(flag_writes);
2026-
regs_ptr as *mut _
2042+
flags_ptr
20272043
}
20282044

20292045
extern "C" fn cb_semantic_flag_classes<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
20302046
where
20312047
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
20322048
{
20332049
let custom_arch = unsafe { &*(ctxt as *mut A) };
2034-
let mut flag_classes = custom_arch.flag_classes();
2050+
let mut flag_classes: Vec<_> = custom_arch.flag_classes().iter().map(|f| f.id()).collect();
20352051

20362052
// SAFETY: `count` is an out parameter
20372053
unsafe { *count = flag_classes.len() };
2038-
let regs_ptr = flag_classes.as_mut_ptr();
2054+
let flags_ptr = flag_classes.as_mut_ptr();
20392055
mem::forget(flag_classes);
2040-
regs_ptr as *mut _
2056+
flags_ptr
20412057
}
20422058

20432059
extern "C" fn cb_semantic_flag_groups<A>(ctxt: *mut c_void, count: *mut usize) -> *mut u32
20442060
where
20452061
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
20462062
{
20472063
let custom_arch = unsafe { &*(ctxt as *mut A) };
2048-
let mut flag_groups = custom_arch.flag_groups();
2064+
let mut flag_groups: Vec<_> = custom_arch.flag_groups().iter().map(|f| f.id()).collect();
20492065

20502066
// SAFETY: `count` is an out parameter
20512067
unsafe { *count = flag_groups.len() };
2052-
let regs_ptr = flag_groups.as_mut_ptr();
2068+
let flags_ptr = flag_groups.as_mut_ptr();
20532069
mem::forget(flag_groups);
2054-
regs_ptr as *mut _
2070+
flags_ptr
20552071
}
20562072

20572073
extern "C" fn cb_flag_role<A>(ctxt: *mut c_void, flag: u32, class: u32) -> BNFlagRole
@@ -2081,13 +2097,17 @@ where
20812097
{
20822098
let custom_arch = unsafe { &*(ctxt as *mut A) };
20832099
let class = custom_arch.flag_class_from_id(class);
2084-
let mut flags = custom_arch.flags_required_for_flag_condition(cond, class);
2100+
let mut flags: Vec<_> = custom_arch
2101+
.flags_required_for_flag_condition(cond, class)
2102+
.iter()
2103+
.map(|f| f.id())
2104+
.collect();
20852105

20862106
// SAFETY: `count` is an out parameter
20872107
unsafe { *count = flags.len() };
2088-
let regs_ptr = flags.as_mut_ptr();
2108+
let flags_ptr = flags.as_mut_ptr();
20892109
mem::forget(flags);
2090-
regs_ptr as *mut _
2110+
flags_ptr
20912111
}
20922112

20932113
extern "C" fn cb_flags_required_for_semantic_flag_group<A>(
@@ -2101,13 +2121,13 @@ where
21012121
let custom_arch = unsafe { &*(ctxt as *mut A) };
21022122

21032123
if let Some(group) = custom_arch.flag_group_from_id(group) {
2104-
let mut flags = group.flags_required();
2105-
2124+
let mut flags: Vec<_> = group.flags_required().iter().map(|f| f.id()).collect();
2125+
21062126
// SAFETY: `count` is an out parameter
21072127
unsafe { *count = flags.len() };
2108-
let regs_ptr = flags.as_mut_ptr();
2128+
let flags_ptr = flags.as_mut_ptr();
21092129
mem::forget(flags);
2110-
regs_ptr as *mut _
2130+
flags_ptr
21112131
} else {
21122132
unsafe {
21132133
*count = 0;
@@ -2128,23 +2148,19 @@ where
21282148

21292149
if let Some(group) = custom_arch.flag_group_from_id(group) {
21302150
let flag_conditions = group.flag_conditions();
2151+
let mut flags = flag_conditions
2152+
.iter()
2153+
.map(|(&class, &condition)| BNFlagConditionForSemanticClass {
2154+
semanticClass: class.id(),
2155+
condition,
2156+
})
2157+
.collect::<Vec<_>>();
21312158

2132-
unsafe {
2133-
let allocation_size =
2134-
mem::size_of::<BNFlagConditionForSemanticClass>() * flag_conditions.len();
2135-
let result = libc::malloc(allocation_size) as *mut BNFlagConditionForSemanticClass;
2136-
let out_slice = slice::from_raw_parts_mut(result, flag_conditions.len());
2137-
2138-
for (i, (class, cond)) in flag_conditions.iter().enumerate() {
2139-
let out = out_slice.get_unchecked_mut(i);
2140-
2141-
out.semanticClass = class.id();
2142-
out.condition = *cond;
2143-
}
2144-
2145-
*count = flag_conditions.len();
2146-
result
2147-
}
2159+
// SAFETY: `count` is an out parameter
2160+
unsafe { *count = flags.len() };
2161+
let flags_ptr = flags.as_mut_ptr();
2162+
mem::forget(flags);
2163+
flags_ptr
21482164
} else {
21492165
unsafe {
21502166
*count = 0;
@@ -2156,11 +2172,17 @@ where
21562172
extern "C" fn cb_free_flag_conditions_for_semantic_flag_group<A>(
21572173
_ctxt: *mut c_void,
21582174
conds: *mut BNFlagConditionForSemanticClass,
2175+
count: usize,
21592176
) where
21602177
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
21612178
{
2179+
if conds.is_null() {
2180+
return;
2181+
}
2182+
21622183
unsafe {
2163-
libc::free(conds as *mut _);
2184+
let flags_ptr = ptr::slice_from_raw_parts_mut(conds, count);
2185+
let _flags = Box::from_raw(flags_ptr);
21642186
}
21652187
}
21662188

@@ -2175,13 +2197,14 @@ where
21752197
let custom_arch = unsafe { &*(ctxt as *mut A) };
21762198

21772199
if let Some(write_type) = custom_arch.flag_write_from_id(write_type) {
2178-
let mut written = write_type.flags_written();
2179-
2200+
let mut flags_written: Vec<_> =
2201+
write_type.flags_written().iter().map(|f| f.id()).collect();
2202+
21802203
// SAFETY: `count` is an out parameter
2181-
unsafe { *count = written.len() };
2182-
let regs_ptr = written.as_mut_ptr();
2183-
mem::forget(written);
2184-
regs_ptr as *mut _
2204+
unsafe { *count = flags_written.len() };
2205+
let flags_ptr = flags_written.as_mut_ptr();
2206+
mem::forget(flags_written);
2207+
flags_ptr
21852208
} else {
21862209
unsafe {
21872210
*count = 0;
@@ -2387,13 +2410,17 @@ where
23872410
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
23882411
{
23892412
let custom_arch = unsafe { &*(ctxt as *mut A) };
2390-
let mut regs = custom_arch.register_stacks();
2413+
let mut regs: Vec<_> = custom_arch
2414+
.register_stacks()
2415+
.iter()
2416+
.map(|r| r.id())
2417+
.collect();
23912418

23922419
// SAFETY: Passed in to be written
23932420
unsafe { *count = regs.len() };
23942421
let regs_ptr = regs.as_mut_ptr();
23952422
mem::forget(regs);
2396-
regs_ptr as *mut _
2423+
regs_ptr
23972424
}
23982425

23992426
extern "C" fn cb_reg_stack_info<A>(
@@ -2449,13 +2476,13 @@ where
24492476
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
24502477
{
24512478
let custom_arch = unsafe { &*(ctxt as *mut A) };
2452-
let mut intrinsics = custom_arch.intrinsics();
2453-
2479+
let mut intrinsics: Vec<_> = custom_arch.intrinsics().iter().map(|i| i.id()).collect();
2480+
24542481
// SAFETY: Passed in to be written
24552482
unsafe { *count = intrinsics.len() };
2456-
let regs_ptr = intrinsics.as_mut_ptr();
2483+
let intrinsics_ptr = intrinsics.as_mut_ptr();
24572484
mem::forget(intrinsics);
2458-
regs_ptr as *mut _
2485+
intrinsics_ptr
24592486
}
24602487

24612488
extern "C" fn cb_intrinsic_inputs<A>(

0 commit comments

Comments
 (0)