Line data Source code
1 : use super::binary::Binary;
2 : use lief_ffi as ffi;
3 :
4 : use crate::common::FromFFI;
5 : use std::path::Path;
6 :
7 : /// This structure represents a FAT Mach-O
8 : pub struct FatBinary {
9 : pub nb_macho: u32,
10 : ptr: cxx::UniquePtr<ffi::MachO_FatBinary>,
11 : }
12 :
13 : impl FromFFI<ffi::MachO_FatBinary> for FatBinary {
14 348 : fn from_ffi(ptr: cxx::UniquePtr<ffi::MachO_FatBinary>) -> Self {
15 348 : Self {
16 348 : nb_macho: ptr.size(),
17 348 : ptr,
18 348 : }
19 348 : }
20 : }
21 :
22 : impl std::fmt::Debug for FatBinary {
23 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 0 : f.debug_struct("FatBinary")
25 0 : .field("nb_macho", &self.nb_macho)
26 0 : .finish()
27 0 : }
28 : }
29 :
30 : /// Iterator over the different [`crate::macho::Binary`] wrapped by this FAT Mach-O
31 : pub struct FatBinaryIterator<'a> {
32 : index: u32,
33 : fat: &'a FatBinary,
34 : }
35 :
36 : impl FatBinary {
37 : /// Create a FatBinary from the given Mach-O path.
38 16 : pub fn parse<P: AsRef<Path>>(path: P) -> Option<Self> {
39 16 : let ffi = ffi::MachO_FatBinary::parse(path.as_ref().to_str().unwrap());
40 16 : if ffi.is_null() {
41 0 : return None;
42 16 : }
43 16 : Some(FatBinary::from_ffi(ffi))
44 16 : }
45 :
46 : /// Iterator over the [`crate::macho::Binary`]
47 192 : pub fn iter(&self) -> FatBinaryIterator {
48 192 : FatBinaryIterator {
49 192 : index: 0,
50 192 : fat: self,
51 192 : }
52 192 : }
53 : }
54 :
55 : impl<'a> Iterator for FatBinaryIterator<'a> {
56 : type Item = Binary;
57 588 : fn next(&mut self) -> Option<Self::Item> {
58 588 : if self.index >= self.fat.nb_macho {
59 192 : return None;
60 396 : }
61 396 : self.index += 1;
62 396 : Some(Binary::from_ffi(self.fat.ptr.binary_at(self.index - 1)))
63 588 : }
64 : }
65 :
66 : impl<'a> ExactSizeIterator for FatBinaryIterator<'a> {
67 0 : fn len(&self) -> usize {
68 0 : self.fat.nb_macho.try_into().unwrap()
69 0 : }
70 : }
|