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