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