Skip to content

Commit ee6abdd

Browse files
committed
replace Vec into_raw_parts with Box
1 parent 53a7033 commit ee6abdd

File tree

2 files changed

+56
-69
lines changed

2 files changed

+56
-69
lines changed

rust/src/architecture.rs

Lines changed: 42 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,17 +1162,18 @@ impl Architecture for CoreArchitecture {
11621162
&mut result as *mut _,
11631163
&mut count as *mut _,
11641164
) {
1165-
let vec = Vec::<BNInstructionTextToken>::from_raw_parts(result, count, count)
1165+
let vec = slice::from_raw_parts(result, count)
11661166
.iter()
1167-
.map(|x| InstructionTextToken::from_raw(x))
1167+
.map(|x| InstructionTextToken::from_raw(x).to_owned())
11681168
.collect();
1169+
BNFreeInstructionText(result, count);
11691170
Some((consumed, vec))
11701171
} else {
11711172
None
11721173
}
11731174
}
11741175
}
1175-
1176+
11761177
fn instruction_llil(
11771178
&self,
11781179
data: &[u8],
@@ -1811,27 +1812,25 @@ where
18111812
let data = unsafe { slice::from_raw_parts(data, *len) };
18121813
let result = unsafe { &mut *result };
18131814

1814-
match custom_arch.instruction_text(data, addr) {
1815-
Some((res_size, mut res_tokens)) => {
1816-
unsafe {
1817-
// TODO: Can't use into_raw_parts as it's unstable so we do this instead...
1818-
let r_ptr = res_tokens.as_mut_ptr();
1819-
let r_count = res_tokens.len();
1820-
mem::forget(res_tokens);
1821-
1822-
*result = &mut (*r_ptr).0;
1823-
*count = r_count;
1824-
*len = res_size;
1825-
}
1826-
true
1827-
}
1828-
None => false,
1815+
let Some((res_size, res_tokens)) = custom_arch.instruction_text(data, addr) else {
1816+
return false;
1817+
};
1818+
1819+
let res_tokens: Box<[_]> = res_tokens.into_boxed_slice();
1820+
unsafe {
1821+
let res_tokens = Box::leak(res_tokens);
1822+
let r_ptr = res_tokens.as_mut_ptr();
1823+
let r_count = res_tokens.len();
1824+
1825+
*result = &mut (*r_ptr).0;
1826+
*count = r_count;
1827+
*len = res_size;
18291828
}
1829+
true
18301830
}
18311831

18321832
extern "C" fn cb_free_instruction_text(tokens: *mut BNInstructionTextToken, count: usize) {
1833-
let _tokens =
1834-
unsafe { Vec::from_raw_parts(tokens as *mut InstructionTextToken, count, count) };
1833+
let _tokens = unsafe { Box::from_raw(ptr::slice_from_raw_parts_mut(tokens, count)) };
18351834
}
18361835

18371836
extern "C" fn cb_instruction_llil<A>(
@@ -1931,15 +1930,7 @@ where
19311930
if len == 0 {
19321931
ptr::null_mut()
19331932
} else {
1934-
let mut res = Vec::with_capacity(len + 1);
1935-
1936-
res.push(len as u32);
1937-
1938-
for i in items {
1939-
res.push(i);
1940-
}
1941-
1942-
assert!(res.len() == len + 1);
1933+
let mut res: Box<[_]> = [len as u32].into_iter().chain(items).collect();
19431934

19441935
let raw = res.as_mut_ptr();
19451936
mem::forget(res);
@@ -2280,7 +2271,8 @@ where
22802271
unsafe {
22812272
let actual_start = regs.offset(-1);
22822273
let len = *actual_start + 1;
2283-
let _regs = Vec::from_raw_parts(actual_start, len as usize, len as usize);
2274+
let regs_ptr = ptr::slice_from_raw_parts_mut(actual_start, len.try_into().unwrap());
2275+
let _regs = Box::from_raw(regs_ptr);
22842276
}
22852277
}
22862278

@@ -2420,28 +2412,25 @@ where
24202412
{
24212413
let custom_arch = unsafe { &*(ctxt as *mut A) };
24222414

2423-
if let Some(intrinsic) = custom_arch.intrinsic_from_id(intrinsic) {
2424-
let inputs = intrinsic.inputs();
2425-
let mut res = Vec::with_capacity(inputs.len());
2426-
for input in inputs {
2427-
res.push(input.into_raw());
2428-
}
2429-
2430-
unsafe {
2431-
*count = res.len();
2432-
if res.is_empty() {
2433-
ptr::null_mut()
2434-
} else {
2435-
let raw = res.as_mut_ptr();
2436-
mem::forget(res);
2437-
raw
2438-
}
2439-
}
2440-
} else {
2415+
let Some(intrinsic) = custom_arch.intrinsic_from_id(intrinsic) else {
24412416
unsafe {
24422417
*count = 0;
24432418
}
2444-
ptr::null_mut()
2419+
return ptr::null_mut();
2420+
};
2421+
2422+
let inputs = intrinsic.inputs();
2423+
let mut res: Box<[_]> = inputs.into_iter().map(|input| input.into_raw()).collect();
2424+
2425+
unsafe {
2426+
*count = res.len();
2427+
if res.is_empty() {
2428+
ptr::null_mut()
2429+
} else {
2430+
let raw = res.as_mut_ptr();
2431+
mem::forget(res);
2432+
raw
2433+
}
24452434
}
24462435
}
24472436

@@ -2453,8 +2442,8 @@ where
24532442

24542443
if !nt.is_null() {
24552444
unsafe {
2456-
let list = Vec::from_raw_parts(nt, count, count);
2457-
for nt in list {
2445+
let name_and_types = Box::from_raw(ptr::slice_from_raw_parts_mut(nt, count));
2446+
for nt in name_and_types.into_iter() {
24582447
BnString::from_raw(nt.name);
24592448
}
24602449
}
@@ -2473,10 +2462,7 @@ where
24732462

24742463
if let Some(intrinsic) = custom_arch.intrinsic_from_id(intrinsic) {
24752464
let inputs = intrinsic.outputs();
2476-
let mut res = Vec::with_capacity(inputs.len());
2477-
for input in inputs {
2478-
res.push(input.into());
2479-
}
2465+
let mut res: Box<[_]> = inputs.iter().map(|input| input.as_ref().into()).collect();
24802466

24812467
unsafe {
24822468
*count = res.len();
@@ -2505,9 +2491,7 @@ where
25052491
{
25062492
let _custom_arch = unsafe { &*(ctxt as *mut A) };
25072493
if !tl.is_null() {
2508-
unsafe {
2509-
let _list = Vec::from_raw_parts(tl, count, count);
2510-
}
2494+
let _type_list = unsafe { Box::from_raw(ptr::slice_from_raw_parts_mut(tl, count)) };
25112495
}
25122496
}
25132497

rust/src/disassembly.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub type InstructionTextTokenContext = BNInstructionTextTokenContext;
7373
// IndirectImportToken = 69,
7474
// ExternalSymbolToken = 70,
7575

76-
#[repr(C)]
76+
#[repr(transparent)]
7777
pub struct InstructionTextToken(pub(crate) BNInstructionTextToken);
7878

7979
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -99,8 +99,8 @@ pub enum InstructionTextTokenContents {
9999
}
100100

101101
impl InstructionTextToken {
102-
pub(crate) unsafe fn from_raw(raw: &BNInstructionTextToken) -> Self {
103-
Self(*raw)
102+
pub(crate) unsafe fn from_raw(raw: &BNInstructionTextToken) -> &Self {
103+
mem::transmute(raw)
104104
}
105105

106106
pub fn new(text: &str, contents: InstructionTextTokenContents) -> Self {
@@ -254,13 +254,16 @@ impl Clone for InstructionTextToken {
254254
}
255255
}
256256

257-
// TODO : There is almost certainly a memory leak here - in the case where
258-
// `impl CoreOwnedArrayProvider for InstructionTextToken` doesn't get triggered
259-
// impl Drop for InstructionTextToken {
260-
// fn drop(&mut self) {
261-
// let _owned = unsafe { BnString::from_raw(self.0.text) };
262-
// }
263-
// }
257+
impl Drop for InstructionTextToken {
258+
fn drop(&mut self) {
259+
if !self.0.text.is_null() {
260+
let _owned = unsafe { BnString::from_raw(self.0.text) };
261+
}
262+
if !self.0.typeNames.is_null() && self.0.namesCount != 0 {
263+
unsafe { BNFreeStringList(self.0.typeNames, self.0.namesCount) }
264+
}
265+
}
266+
}
264267

265268
pub struct DisassemblyTextLine(pub(crate) BNDisassemblyTextLine);
266269

@@ -290,7 +293,7 @@ impl DisassemblyTextLine {
290293
unsafe {
291294
std::slice::from_raw_parts::<BNInstructionTextToken>(self.0.tokens, self.0.count)
292295
.iter()
293-
.map(|&x| InstructionTextToken::from_raw(&x))
296+
.map(|x| InstructionTextToken::from_raw(x).clone())
294297
.collect()
295298
}
296299
}

0 commit comments

Comments
 (0)