Skip to content

Commit

Permalink
capi: Remove consuming From conversions of normalization types
Browse files Browse the repository at this point in the history
Similar to what we did earlier for the inspect module, switch to using
private functions instead of trait implementations when it comes to the
consuming conversion of C objects containing pointers into the
corresponding Rust objects.

Signed-off-by: Daniel Müller <[email protected]>
  • Loading branch information
d-e-s-o committed Dec 20, 2023
1 parent 913be81 commit dbec1c8
Showing 1 changed file with 61 additions and 85 deletions.
146 changes: 61 additions & 85 deletions capi/src/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,30 +96,30 @@ pub struct blaze_user_meta_apk {
pub path: *mut c_char,
}

impl From<Apk> for blaze_user_meta_apk {
fn from(other: Apk) -> Self {
impl blaze_user_meta_apk {
fn from(other: Apk) -> ManuallyDrop<Self> {
let Apk {
path,
_non_exhaustive: (),
} = other;
Self {

let slf = Self {
path: CString::new(path.into_os_string().into_vec())
.expect("encountered path with NUL bytes")
.into_raw(),
}
};
ManuallyDrop::new(slf)
}
}

impl From<blaze_user_meta_apk> for Apk {
fn from(other: blaze_user_meta_apk) -> Self {
let blaze_user_meta_apk { path } = other;
unsafe fn free(self) {
let Self { path } = self;

Apk {
let _apk = Apk {
path: PathBuf::from(OsString::from_vec(
unsafe { CString::from_raw(path) }.into_bytes(),
)),
_non_exhaustive: (),
}
};
}
}

Expand All @@ -136,14 +136,15 @@ pub struct blaze_user_meta_elf {
pub build_id: *mut u8,
}

impl From<Elf> for blaze_user_meta_elf {
fn from(other: Elf) -> Self {
impl blaze_user_meta_elf {
fn from(other: Elf) -> ManuallyDrop<Self> {
let Elf {
path,
build_id,
_non_exhaustive: (),
} = other;
Self {

let slf = Self {
path: CString::new(path.into_os_string().into_vec())
.expect("encountered path with NUL bytes")
.into_raw(),
Expand All @@ -163,27 +164,26 @@ impl From<Elf> for blaze_user_meta_elf {
}
})
.unwrap_or_else(ptr::null_mut),
}
};
ManuallyDrop::new(slf)
}
}

impl From<blaze_user_meta_elf> for Elf {
fn from(other: blaze_user_meta_elf) -> Self {
unsafe fn free(self) {
let blaze_user_meta_elf {
path,
build_id_len,
build_id,
} = other;
} = self;

Elf {
let _elf = Elf {
path: PathBuf::from(OsString::from_vec(
unsafe { CString::from_raw(path) }.into_bytes(),
)),
build_id: (!build_id.is_null()).then(|| unsafe {
Box::<[u8]>::from_raw(slice::from_raw_parts_mut(build_id, build_id_len)).into_vec()
}),
_non_exhaustive: (),
}
};
}
}

Expand All @@ -196,21 +196,18 @@ pub struct blaze_user_meta_unknown {
pub _unused: u8,
}

impl From<Unknown> for blaze_user_meta_unknown {
fn from(other: Unknown) -> Self {
impl blaze_user_meta_unknown {
fn from(other: Unknown) -> ManuallyDrop<Self> {
let Unknown {
_non_exhaustive: (),
} = other;
Self { _unused: 0 }

let slf = Self { _unused: 0 };
ManuallyDrop::new(slf)
}
}

impl From<blaze_user_meta_unknown> for Unknown {
fn from(other: blaze_user_meta_unknown) -> Self {
let blaze_user_meta_unknown { _unused } = other;
Unknown {
_non_exhaustive: (),
}
fn free(self) {
let blaze_user_meta_unknown { _unused } = self;
}
}

Expand Down Expand Up @@ -243,49 +240,42 @@ pub struct blaze_user_meta {
pub variant: blaze_user_meta_variant,
}

impl From<UserMeta> for blaze_user_meta {
fn from(other: UserMeta) -> Self {
match other {
impl blaze_user_meta {
fn from(other: UserMeta) -> ManuallyDrop<Self> {
let slf = match other {
UserMeta::Apk(apk) => Self {
kind: blaze_user_meta_kind::BLAZE_USER_META_APK,
variant: blaze_user_meta_variant {
apk: ManuallyDrop::new(blaze_user_meta_apk::from(apk)),
apk: blaze_user_meta_apk::from(apk),
},
},
UserMeta::Elf(elf) => Self {
kind: blaze_user_meta_kind::BLAZE_USER_META_ELF,
variant: blaze_user_meta_variant {
elf: ManuallyDrop::new(blaze_user_meta_elf::from(elf)),
elf: blaze_user_meta_elf::from(elf),
},
},
UserMeta::Unknown(unknown) => Self {
kind: blaze_user_meta_kind::BLAZE_USER_META_UNKNOWN,
variant: blaze_user_meta_variant {
unknown: ManuallyDrop::new(blaze_user_meta_unknown::from(unknown)),
unknown: blaze_user_meta_unknown::from(unknown),
},
},
_ => unreachable!(),
}
};
ManuallyDrop::new(slf)
}
}

impl From<blaze_user_meta> for UserMeta {
fn from(other: blaze_user_meta) -> Self {
match other.kind {
unsafe fn free(self) {
match self.kind {
blaze_user_meta_kind::BLAZE_USER_META_APK => {
UserMeta::Apk(Apk::from(ManuallyDrop::into_inner(unsafe {
other.variant.apk
})))
ManuallyDrop::into_inner(unsafe { self.variant.apk }).free()
}
blaze_user_meta_kind::BLAZE_USER_META_ELF => {
UserMeta::Elf(Elf::from(ManuallyDrop::into_inner(unsafe {
other.variant.elf
})))
ManuallyDrop::into_inner(unsafe { self.variant.elf }).free()
}
blaze_user_meta_kind::BLAZE_USER_META_UNKNOWN => {
UserMeta::Unknown(Unknown::from(ManuallyDrop::into_inner(unsafe {
other.variant.unknown
})))
ManuallyDrop::into_inner(unsafe { self.variant.unknown }).free()
}
}
}
Expand All @@ -308,16 +298,17 @@ pub struct blaze_normalized_user_output {
pub outputs: *mut blaze_normalized_output,
}

impl From<UserOutput> for blaze_normalized_user_output {
fn from(other: UserOutput) -> Self {
Self {
impl blaze_normalized_user_output {
fn from(other: UserOutput) -> ManuallyDrop<Self> {
let slf = Self {
meta_cnt: other.meta.len(),
metas: unsafe {
Box::into_raw(
other
.meta
.into_iter()
.map(blaze_user_meta::from)
.map(ManuallyDrop::into_inner)
.collect::<Vec<_>>()
.into_boxed_slice(),
)
Expand All @@ -339,7 +330,8 @@ impl From<UserOutput> for blaze_normalized_user_output {
.unwrap()
.as_mut_ptr()
},
}
};
ManuallyDrop::new(slf)
}
}

Expand Down Expand Up @@ -374,7 +366,9 @@ pub unsafe extern "C" fn blaze_normalize_user_addrs(
let addrs = unsafe { slice_from_user_array(addrs, addr_cnt) };
let result = normalizer.normalize_user_addrs(pid.into(), addrs);
match result {
Ok(addrs) => Box::into_raw(Box::new(blaze_normalized_user_output::from(addrs))),
Ok(addrs) => Box::into_raw(Box::new(ManuallyDrop::into_inner(
blaze_normalized_user_output::from(addrs),
))),
Err(_err) => ptr::null_mut(),
}
}
Expand Down Expand Up @@ -412,7 +406,9 @@ pub unsafe extern "C" fn blaze_normalize_user_addrs_sorted(
let addrs = unsafe { slice_from_user_array(addrs, addr_cnt) };
let result = normalizer.normalize_user_addrs_sorted(pid.into(), addrs);
match result {
Ok(addrs) => Box::into_raw(Box::new(blaze_normalized_user_output::from(addrs))),
Ok(addrs) => Box::into_raw(Box::new(ManuallyDrop::into_inner(
blaze_normalized_user_output::from(addrs),
))),
Err(_err) => ptr::null_mut(),
}
}
Expand Down Expand Up @@ -448,7 +444,7 @@ pub unsafe extern "C" fn blaze_user_output_free(output: *mut blaze_normalized_us
.into_vec();

for addr_meta in addr_metas {
let _meta = UserMeta::from(addr_meta);
let () = unsafe { addr_meta.free() };
}
}

Expand Down Expand Up @@ -525,12 +521,8 @@ mod tests {
_non_exhaustive: (),
};

let unknown_new = Unknown::from(blaze_user_meta_unknown::from(unknown.clone()));
assert_eq!(unknown_new, unknown);

let meta = UserMeta::Unknown(unknown_new);
let meta_new = UserMeta::from(blaze_user_meta::from(meta.clone()));
assert_eq!(meta_new, meta);
let unknown = blaze_user_meta_unknown::from(unknown);
let () = ManuallyDrop::into_inner(unknown).free();
}

/// Check that we can convert an [`Apk`] into a [`blaze_user_meta_apk`] and
Expand All @@ -542,20 +534,8 @@ mod tests {
_non_exhaustive: (),
};

let apk_new = Apk::from(blaze_user_meta_apk::from(apk.clone()));
assert_eq!(apk_new, apk);

let apk = Apk {
path: PathBuf::new(),
_non_exhaustive: (),
};

let apk_new = Apk::from(blaze_user_meta_apk::from(apk.clone()));
assert_eq!(apk_new, apk);

let meta = UserMeta::Apk(apk_new);
let meta_new = UserMeta::from(blaze_user_meta::from(meta.clone()));
assert_eq!(meta_new, meta);
let apk = blaze_user_meta_apk::from(apk);
let () = unsafe { ManuallyDrop::into_inner(apk).free() };
}

/// Check that we can convert an [`Elf`] into a [`blaze_user_meta_elf`]
Expand All @@ -568,12 +548,8 @@ mod tests {
_non_exhaustive: (),
};

let elf_new = Elf::from(blaze_user_meta_elf::from(elf.clone()));
assert_eq!(elf_new, elf);

let meta = UserMeta::Elf(elf_new);
let meta_new = UserMeta::from(blaze_user_meta::from(meta.clone()));
assert_eq!(meta_new, meta);
let elf = blaze_user_meta_elf::from(elf);
let () = unsafe { ManuallyDrop::into_inner(elf).free() };
}

/// Make sure that we can create and free a normalizer instance.
Expand All @@ -590,7 +566,7 @@ mod tests {
libc::__errno_location as Addr,
libc::dlopen as Addr,
libc::fopen as Addr,
elf_conversion as Addr,
normalizer_creation as Addr,
normalize_user_addrs as Addr,
];

Expand All @@ -617,7 +593,7 @@ mod tests {
libc::__errno_location as Addr,
libc::dlopen as Addr,
libc::fopen as Addr,
elf_conversion as Addr,
normalizer_creation as Addr,
normalize_user_addrs as Addr,
];
let () = addrs.sort();
Expand Down

0 comments on commit dbec1c8

Please sign in to comment.