Skip to content

Commit 9004050

Browse files
committed
allow DataVariable and NameAndType to be transmutable
1 parent f408eb3 commit 9004050

File tree

7 files changed

+84
-50
lines changed

7 files changed

+84
-50
lines changed

rust/examples/dwarf/dwarf_export/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,23 +551,23 @@ fn export_data_vars(
551551
dwarf.unit.get_mut(var_die_uid).set(
552552
gimli::DW_AT_name,
553553
AttributeValue::String(
554-
format!("data_{:x}", data_variable.address)
554+
format!("data_{:x}", data_variable.address())
555555
.as_bytes()
556556
.to_vec(),
557557
),
558558
);
559559
}
560560

561561
let mut variable_location = Expression::new();
562-
variable_location.op_addr(Address::Constant(data_variable.address));
562+
variable_location.op_addr(Address::Constant(data_variable.address()));
563563
dwarf.unit.get_mut(var_die_uid).set(
564564
gimli::DW_AT_location,
565565
AttributeValue::Exprloc(variable_location),
566566
);
567567

568568
if let Some(target_die_uid) = export_type(
569-
format!("{}", data_variable.t.contents),
570-
data_variable.t.contents.as_ref(),
569+
format!("{}", data_variable.t()),
570+
data_variable.t(),
571571
bv,
572572
defined_types,
573573
dwarf,

rust/examples/dwarf/shared/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ pub fn create_section_reader<'a, Endian: 'a + Endianity>(
8888
if let Some(data_var) = view
8989
.data_variables()
9090
.iter()
91-
.find(|var| var.address == symbol.address())
91+
.find(|var| var.address() == symbol.address())
9292
{
9393
// TODO : This should eventually be wrapped by some DataView sorta thingy thing, like how python does it
94-
let data_type = data_var.type_with_confidence().contents;
95-
let data = view.read_vec(data_var.address, data_type.width() as usize);
94+
let data_type = data_var.t();
95+
let data = view.read_vec(data_var.address(), data_type.width() as usize);
9696
let element_type = data_type.element_type().unwrap().contents;
9797

9898
if let Some(current_section_header) = data

rust/src/architecture.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ pub trait Intrinsic: Sized + Clone + Copy {
313313
fn id(&self) -> u32;
314314

315315
/// Reeturns the list of the input names and types for this intrinsic.
316-
fn inputs(&self) -> Vec<NameAndType<String>>;
316+
fn inputs(&self) -> Vec<NameAndType>;
317317

318318
/// Returns the list of the output types for this intrinsic.
319319
fn outputs(&self) -> Vec<Conf<Ref<Type>>>;
@@ -650,7 +650,7 @@ impl Intrinsic for UnusedIntrinsic {
650650
fn id(&self) -> u32 {
651651
unreachable!()
652652
}
653-
fn inputs(&self) -> Vec<NameAndType<String>> {
653+
fn inputs(&self) -> Vec<NameAndType> {
654654
unreachable!()
655655
}
656656
fn outputs(&self) -> Vec<Conf<Ref<Type>>> {
@@ -992,7 +992,7 @@ impl Intrinsic for crate::architecture::CoreIntrinsic {
992992
self.1
993993
}
994994

995-
fn inputs(&self) -> Vec<NameAndType<String>> {
995+
fn inputs(&self) -> Vec<NameAndType> {
996996
let mut count: usize = 0;
997997

998998
unsafe {

rust/src/binaryview.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,14 +576,22 @@ pub trait BinaryViewExt: BinaryViewBase {
576576

577577
fn define_auto_data_var(&self, dv: DataVariable) {
578578
unsafe {
579-
BNDefineDataVariable(self.as_ref().handle, dv.address, &mut dv.t.into());
579+
BNDefineDataVariable(
580+
self.as_ref().handle,
581+
dv.address(),
582+
&mut dv.type_with_confidence().into(),
583+
);
580584
}
581585
}
582586

583587
/// You likely would also like to call [`Self::define_user_symbol`] to bind this data variable with a name
584588
fn define_user_data_var(&self, dv: DataVariable) {
585589
unsafe {
586-
BNDefineUserDataVariable(self.as_ref().handle, dv.address, &mut dv.t.into());
590+
BNDefineUserDataVariable(
591+
self.as_ref().handle,
592+
dv.address(),
593+
&mut dv.type_with_confidence().into(),
594+
);
587595
}
588596
}
589597

rust/src/debuginfo.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl DebugInfo {
376376
}
377377

378378
/// Returns a generator of all types provided by a named DebugInfoParser
379-
pub fn types_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<NameAndType<String>> {
379+
pub fn types_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<NameAndType> {
380380
let parser_name = parser_name.into_bytes_with_nul();
381381

382382
let mut count: usize = 0;
@@ -387,10 +387,10 @@ impl DebugInfo {
387387
&mut count,
388388
)
389389
};
390-
let result: Vec<NameAndType<String>> = unsafe {
390+
let result: Vec<NameAndType> = unsafe {
391391
slice::from_raw_parts_mut(debug_types_ptr, count)
392392
.iter()
393-
.map(NameAndType::<String>::from_raw)
393+
.map(NameAndType::from_raw)
394394
.collect()
395395
};
396396

@@ -399,13 +399,13 @@ impl DebugInfo {
399399
}
400400

401401
/// A generator of all types provided by DebugInfoParsers
402-
pub fn types(&self) -> Vec<NameAndType<String>> {
402+
pub fn types(&self) -> Vec<NameAndType> {
403403
let mut count: usize = 0;
404404
let debug_types_ptr = unsafe { BNGetDebugTypes(self.handle, ptr::null_mut(), &mut count) };
405-
let result: Vec<NameAndType<String>> = unsafe {
405+
let result: Vec<NameAndType> = unsafe {
406406
slice::from_raw_parts_mut(debug_types_ptr, count)
407407
.iter()
408-
.map(NameAndType::<String>::from_raw)
408+
.map(NameAndType::from_raw)
409409
.collect()
410410
};
411411

rust/src/rc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub unsafe trait RefCountable: ToOwned<Owned = Ref<Self>> + Sized {
4343
// Represents an 'owned' reference tracked by the core
4444
// that we are responsible for cleaning up once we're
4545
// done with the encapsulated value.
46+
#[repr(transparent)]
4647
pub struct Ref<T: RefCountable> {
4748
contents: T,
4849
}

rust/src/types.rs

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ pub type MemberScope = BNMemberScope;
5656
////////////////
5757
// Confidence
5858

59+
/// Compatible with the `BNType*WithConfidence` types
60+
#[repr(C)]
5961
pub struct Conf<T> {
6062
pub contents: T,
6163
pub confidence: u8,
@@ -698,6 +700,7 @@ impl Drop for TypeBuilder {
698700
//////////
699701
// Type
700702

703+
#[repr(transparent)]
701704
pub struct Type {
702705
pub(crate) handle: *mut BNType,
703706
}
@@ -2447,12 +2450,10 @@ unsafe impl<'a> CoreArrayWrapper<'a> for QualifiedNameTypeAndId {
24472450
//////////////////////////
24482451
// NameAndType
24492452

2450-
pub struct NameAndType<S: BnStrCompatible> {
2451-
pub name: S,
2452-
pub t: Conf<Ref<Type>>,
2453-
}
2453+
#[repr(transparent)]
2454+
pub struct NameAndType(pub(crate) BNNameAndType);
24542455

2455-
impl NameAndType<String> {
2456+
impl NameAndType {
24562457
pub(crate) fn from_raw(raw: &BNNameAndType) -> Self {
24572458
Self::new(
24582459
raw_to_string(raw.name).unwrap(),
@@ -2462,43 +2463,56 @@ impl NameAndType<String> {
24622463
}
24632464
}
24642465

2465-
impl<S: BnStrCompatible> NameAndType<S> {
2466-
pub fn new(name: S, t: &Ref<Type>, confidence: u8) -> Self {
2467-
Self {
2468-
name,
2469-
t: Conf::new(t.clone(), confidence),
2470-
}
2466+
impl NameAndType {
2467+
pub fn new<S: BnStrCompatible>(name: S, t: &Ref<Type>, confidence: u8) -> Self {
2468+
Self(BNNameAndType {
2469+
name: unsafe { BNAllocString(name.into_bytes_with_nul().as_ref().as_ptr() as *mut _) },
2470+
type_: unsafe { Ref::into_raw(t.to_owned()).handle },
2471+
typeConfidence: confidence,
2472+
})
24712473
}
24722474

24732475
pub(crate) fn into_raw(self) -> BNNameAndType {
2474-
let t = self.t.clone();
2475-
let res = BNNameAndType {
2476-
name: BnString::new(self.name).into_raw(),
2477-
type_: t.contents.handle,
2478-
typeConfidence: self.t.confidence,
2479-
};
2480-
mem::forget(t);
2481-
res
2476+
self.0
24822477
}
24832478

2484-
pub fn type_with_confidence(&self) -> Conf<Ref<Type>> {
2485-
self.t.clone()
2479+
pub fn name(&self) -> &str {
2480+
let c_str = unsafe { CStr::from_ptr(self.0.name) };
2481+
c_str.to_str().unwrap()
2482+
}
2483+
2484+
pub fn t(&self) -> &Type {
2485+
unsafe { mem::transmute::<_, &Type>(&self.0.type_) }
2486+
}
2487+
2488+
pub fn type_with_confidence(&self) -> &Conf<Type> {
2489+
// the struct BNNameAndType contains a Conf inside of it, so this is safe
2490+
unsafe { mem::transmute::<_, &Conf<Type>>(&self.0.type_) }
2491+
}
2492+
}
2493+
2494+
impl Drop for NameAndType {
2495+
fn drop(&mut self) {
2496+
unsafe {
2497+
BNFreeString(self.0.name);
2498+
BNFreeType(self.0.type_);
2499+
}
24862500
}
24872501
}
24882502

2489-
impl<S: BnStrCompatible> CoreArrayProvider for NameAndType<S> {
2503+
impl CoreArrayProvider for NameAndType {
24902504
type Raw = BNNameAndType;
24912505
type Context = ();
24922506
}
24932507

2494-
unsafe impl<S: BnStrCompatible> CoreOwnedArrayProvider for NameAndType<S> {
2508+
unsafe impl CoreOwnedArrayProvider for NameAndType {
24952509
unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
24962510
BNFreeNameAndTypeList(raw, count);
24972511
}
24982512
}
24992513

2500-
unsafe impl<'a, S: 'a + BnStrCompatible> CoreArrayWrapper<'a> for NameAndType<S> {
2501-
type Wrapped = &'a NameAndType<S>;
2514+
unsafe impl<'a> CoreArrayWrapper<'a> for NameAndType {
2515+
type Wrapped = &'a NameAndType;
25022516

25032517
unsafe fn wrap_raw(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped {
25042518
mem::transmute(raw)
@@ -2508,11 +2522,8 @@ unsafe impl<'a, S: 'a + BnStrCompatible> CoreArrayWrapper<'a> for NameAndType<S>
25082522
//////////////////
25092523
// DataVariable
25102524

2511-
pub struct DataVariable {
2512-
pub address: u64,
2513-
pub t: Conf<Ref<Type>>,
2514-
pub auto_discovered: bool,
2515-
}
2525+
#[repr(transparent)]
2526+
pub struct DataVariable(pub(crate) BNDataVariable);
25162527

25172528
// impl DataVariable {
25182529
// pub(crate) fn from_raw(var: &BNDataVariable) -> Self {
@@ -2525,12 +2536,26 @@ pub struct DataVariable {
25252536
// }
25262537

25272538
impl DataVariable {
2539+
pub fn address(&self) -> u64 {
2540+
self.0.address
2541+
}
2542+
2543+
pub fn auto_discovered(&self) -> &bool {
2544+
unsafe { mem::transmute(&self.0.autoDiscovered) }
2545+
}
2546+
2547+
pub fn t(&self) -> &Type {
2548+
unsafe { mem::transmute(&self.0.type_) }
2549+
}
2550+
25282551
pub fn type_with_confidence(&self) -> Conf<Ref<Type>> {
2529-
Conf::new(self.t.contents.clone(), self.t.confidence)
2552+
// if it was not for the `autoDiscovered: bool` between `type_` and
2553+
// `typeConfidence` this could have being a reference, like NameAndType
2554+
Conf::new(self.t().to_owned(), self.0.typeConfidence)
25302555
}
25312556

25322557
pub fn symbol(&self, bv: &BinaryView) -> Option<Ref<Symbol>> {
2533-
bv.symbol_by_address(self.address).ok()
2558+
bv.symbol_by_address(self.0.address).ok()
25342559
}
25352560
}
25362561

0 commit comments

Comments
 (0)