LCOV - code coverage report
Current view: top level - src/macho - commands.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 70.5 % 403 284
Test Date: 2025-08-10:00:00:00 Functions: 87.5 % 144 126

            Line data    Source code
       1              : use std::marker::PhantomData;
       2              : 
       3              : use lief_ffi as ffi;
       4              : pub mod build_version;
       5              : pub mod code_signature;
       6              : pub mod code_signature_dir;
       7              : pub mod data_in_code;
       8              : pub mod dyld_chained_fixups;
       9              : pub mod dyld_environment;
      10              : pub mod dyld_export_trie;
      11              : pub mod dyldinfo;
      12              : pub mod dylib;
      13              : pub mod dylinker;
      14              : pub mod dynamic_symbol_command;
      15              : pub mod encryption_info;
      16              : pub mod functionstarts;
      17              : pub mod function_variants;
      18              : pub mod function_variant_fixups;
      19              : pub mod atom_info;
      20              : pub mod linker_opt_hint;
      21              : pub mod main_cmd;
      22              : pub mod rpath;
      23              : pub mod routine;
      24              : pub mod segment;
      25              : pub mod segment_split_info;
      26              : pub mod source_version;
      27              : pub mod sub_framework;
      28              : pub mod sub_client;
      29              : pub mod symbol_command;
      30              : pub mod thread_command;
      31              : pub mod two_level_hints;
      32              : pub mod uuid;
      33              : pub mod version_min;
      34              : pub mod note;
      35              : pub mod unknown;
      36              : 
      37              : #[doc(inline)]
      38              : pub use build_version::BuildVersion;
      39              : #[doc(inline)]
      40              : pub use code_signature::CodeSignature;
      41              : #[doc(inline)]
      42              : pub use code_signature_dir::CodeSignatureDir;
      43              : #[doc(inline)]
      44              : pub use data_in_code::DataInCode;
      45              : #[doc(inline)]
      46              : pub use dyld_chained_fixups::DyldChainedFixups;
      47              : #[doc(inline)]
      48              : pub use dyld_environment::DyldEnvironment;
      49              : #[doc(inline)]
      50              : pub use dyld_export_trie::DyldExportsTrie;
      51              : #[doc(inline)]
      52              : pub use dyldinfo::DyldInfo;
      53              : #[doc(inline)]
      54              : pub use dylib::{Dylib, Libraries};
      55              : #[doc(inline)]
      56              : pub use dylinker::Dylinker;
      57              : #[doc(inline)]
      58              : pub use dynamic_symbol_command::DynamicSymbolCommand;
      59              : #[doc(inline)]
      60              : pub use encryption_info::EncryptionInfo;
      61              : #[doc(inline)]
      62              : pub use functionstarts::FunctionStarts;
      63              : #[doc(inline)]
      64              : pub use function_variants::FunctionVariants;
      65              : #[doc(inline)]
      66              : pub use function_variant_fixups::FunctionVariantFixups;
      67              : #[doc(inline)]
      68              : pub use atom_info::AtomInfo;
      69              : #[doc(inline)]
      70              : pub use linker_opt_hint::LinkerOptHint;
      71              : #[doc(inline)]
      72              : pub use main_cmd::Main;
      73              : #[doc(inline)]
      74              : pub use rpath::RPath;
      75              : #[doc(inline)]
      76              : pub use routine::Routine;
      77              : #[doc(inline)]
      78              : pub use segment::Segment;
      79              : #[doc(inline)]
      80              : pub use segment_split_info::SegmentSplitInfo;
      81              : #[doc(inline)]
      82              : pub use source_version::SourceVersion;
      83              : #[doc(inline)]
      84              : pub use sub_framework::SubFramework;
      85              : #[doc(inline)]
      86              : pub use sub_client::SubClient;
      87              : #[doc(inline)]
      88              : pub use symbol_command::SymbolCommand;
      89              : #[doc(inline)]
      90              : pub use thread_command::ThreadCommand;
      91              : #[doc(inline)]
      92              : pub use two_level_hints::TwoLevelHints;
      93              : #[doc(inline)]
      94              : pub use uuid::UUID;
      95              : #[doc(inline)]
      96              : pub use version_min::VersionMin;
      97              : #[doc(inline)]
      98              : pub use note::Note;
      99              : #[doc(inline)]
     100              : pub use unknown::Unknown;
     101              : 
     102              : use crate::common::FromFFI;
     103              : use crate::{declare_iterator, to_slice};
     104              : 
     105       396756 : #[derive(Debug, Copy, Clone)]
     106              : pub enum LoadCommandTypes {
     107              :     BuildVersion,
     108              :     CodeSignature,
     109              :     DataInCode,
     110              :     DyldChainedFixups,
     111              :     DyldEnvironment,
     112              :     DyldExportsTrie,
     113              :     DyldInfo,
     114              :     DyldInfoOnly,
     115              :     DylibCodeSignDrs,
     116              :     Dysymtab,
     117              :     EncryptionInfo,
     118              :     EncryptionInfo64,
     119              :     FilesetEntry,
     120              :     FunctionStarts,
     121              :     Fvmfile,
     122              :     Ident,
     123              :     Idfvmlib,
     124              :     IdDylib,
     125              :     IdDylinker,
     126              :     LazyLoadDylib,
     127              :     LinkerOptimizationHint,
     128              :     LinkerOption,
     129              :     LoadFvmLib,
     130              :     LoadDylib,
     131              :     LoadDylinker,
     132              :     LoadUpwardDylib,
     133              :     LoadWeakDylib,
     134              :     Main,
     135              :     Note,
     136              :     PrebindCksum,
     137              :     PreboundDylib,
     138              :     Prepage,
     139              :     ReExportDylib,
     140              :     Routines,
     141              :     Routines64,
     142              :     Rpath,
     143              :     Segment,
     144              :     Segment64,
     145              :     SegmentSplitInfo,
     146              :     SourceVersion,
     147              :     SubClient,
     148              :     SubFramework,
     149              :     SubLibrary,
     150              :     SubUmbrella,
     151              :     Symseg,
     152              :     Symtab,
     153              :     Thread,
     154              :     TwoLevelHints,
     155              :     Unixthread,
     156              :     Uuid,
     157              :     VersionMinIphoneOS,
     158              :     VersionMinMacOSX,
     159              :     VersionMinTvOS,
     160              :     VersionMinWatchOS,
     161              :     AtomInfo,
     162              :     FunctionVariants,
     163              :     FunctionVariantsFixups,
     164              :     TargetTriple,
     165              : 
     166              :     LiefUnknown,
     167              :     Unknown(u64),
     168              : }
     169              : impl LoadCommandTypes {
     170              :     const LC_BUILD_VERSION: u64 = 0x00000032;
     171              :     const LC_CODE_SIGNATURE: u64 = 0x0000001D;
     172              :     const LC_DATA_IN_CODE: u64 = 0x00000029;
     173              :     const LC_DYLD_CHAINED_FIXUPS: u64 = 0x80000034;
     174              :     const LC_DYLD_ENVIRONMENT: u64 = 0x00000027;
     175              :     const LC_DYLD_EXPORTS_TRIE: u64 = 0x80000033;
     176              :     const LC_DYLD_INFO: u64 = 0x00000022;
     177              :     const LC_DYLD_INFO_ONLY: u64 = 0x80000022;
     178              :     const LC_DYLIB_CODE_SIGN_DRS: u64 = 0x0000002B;
     179              :     const LC_DYSYMTAB: u64 = 0x0000000B;
     180              :     const LC_ENCRYPTION_INFO: u64 = 0x00000021;
     181              :     const LC_ENCRYPTION_INFO_64: u64 = 0x0000002C;
     182              :     const LC_FILESET_ENTRY: u64 = 0x80000035;
     183              :     const LC_FUNCTION_STARTS: u64 = 0x00000026;
     184              :     const LC_FVMFILE: u64 = 0x00000009;
     185              :     const LC_IDENT: u64 = 0x00000008;
     186              :     const LC_IDFVMLIB: u64 = 0x00000007;
     187              :     const LC_ID_DYLIB: u64 = 0x0000000D;
     188              :     const LC_ID_DYLINKER: u64 = 0x0000000F;
     189              :     const LC_LAZY_LOAD_DYLIB: u64 = 0x00000020;
     190              :     const LC_LINKER_OPTIMIZATION_HINT: u64 = 0x0000002E;
     191              :     const LC_LINKER_OPTION: u64 = 0x0000002D;
     192              :     const LC_LOADFVMLIB: u64 = 0x00000006;
     193              :     const LC_LOAD_DYLIB: u64 = 0x0000000C;
     194              :     const LC_LOAD_DYLINKER: u64 = 0x0000000E;
     195              :     const LC_LOAD_UPWARD_DYLIB: u64 = 0x80000023;
     196              :     const LC_LOAD_WEAK_DYLIB: u64 = 0x80000018;
     197              :     const LC_MAIN: u64 = 0x80000028;
     198              :     const LC_NOTE: u64 = 0x00000031;
     199              :     const LC_PREBIND_CKSUM: u64 = 0x00000017;
     200              :     const LC_PREBOUND_DYLIB: u64 = 0x00000010;
     201              :     const LC_PREPAGE: u64 = 0x0000000A;
     202              :     const LC_REEXPORT_DYLIB: u64 = 0x8000001F;
     203              :     const LC_ROUTINES: u64 = 0x00000011;
     204              :     const LC_ROUTINES_64: u64 = 0x0000001A;
     205              :     const LC_RPATH: u64 = 0x8000001C;
     206              :     const LC_SEGMENT: u64 = 0x00000001;
     207              :     const LC_SEGMENT_64: u64 = 0x00000019;
     208              :     const LC_SEGMENT_SPLIT_INFO: u64 = 0x0000001E;
     209              :     const LC_SOURCE_VERSION: u64 = 0x0000002A;
     210              :     const LC_SUB_CLIENT: u64 = 0x00000014;
     211              :     const LC_SUB_FRAMEWORK: u64 = 0x00000012;
     212              :     const LC_SUB_LIBRARY: u64 = 0x00000015;
     213              :     const LC_SUB_UMBRELLA: u64 = 0x00000013;
     214              :     const LC_SYMSEG: u64 = 0x00000003;
     215              :     const LC_SYMTAB: u64 = 0x00000002;
     216              :     const LC_THREAD: u64 = 0x00000004;
     217              :     const LC_TWOLEVEL_HINTS: u64 = 0x00000016;
     218              :     const LC_UNIXTHREAD: u64 = 0x00000005;
     219              :     const LC_UUID: u64 = 0x0000001B;
     220              :     const LC_VERSION_MIN_IPHONEOS: u64 = 0x00000025;
     221              :     const LC_VERSION_MIN_MACOSX: u64 = 0x00000024;
     222              :     const LC_VERSION_MIN_TVOS: u64 = 0x0000002F;
     223              :     const LC_VERSION_MIN_WATCHOS: u64 = 0x00000030;
     224              :     const LC_ATOM_INFO: u64 = 0x00000036;
     225              :     const LC_FUNCTION_VARIANTS: u64 = 0x00000037;
     226              :     const LC_FUNCTION_VARIANT_FIXUPS: u64 = 0x00000038;
     227              :     const LC_TARGET_TRIPLE: u64 = 0x00000039;
     228              : 
     229              :     const LIEF_UNKNOWN: u64 = 0xffee0001;
     230              : 
     231       396756 :     pub fn from_value(value: u64) -> Self {
     232       396756 :         match value {
     233          504 :             LoadCommandTypes::LC_BUILD_VERSION => LoadCommandTypes::BuildVersion,
     234          216 :             LoadCommandTypes::LC_CODE_SIGNATURE => LoadCommandTypes::CodeSignature,
     235          288 :             LoadCommandTypes::LC_DATA_IN_CODE => LoadCommandTypes::DataInCode,
     236           72 :             LoadCommandTypes::LC_DYLD_CHAINED_FIXUPS => LoadCommandTypes::DyldChainedFixups,
     237           24 :             LoadCommandTypes::LC_DYLD_ENVIRONMENT => LoadCommandTypes::DyldEnvironment,
     238           96 :             LoadCommandTypes::LC_DYLD_EXPORTS_TRIE => LoadCommandTypes::DyldExportsTrie,
     239            0 :             LoadCommandTypes::LC_DYLD_INFO => LoadCommandTypes::DyldInfo,
     240          216 :             LoadCommandTypes::LC_DYLD_INFO_ONLY => LoadCommandTypes::DyldInfoOnly,
     241           24 :             LoadCommandTypes::LC_DYLIB_CODE_SIGN_DRS => LoadCommandTypes::DylibCodeSignDrs,
     242          360 :             LoadCommandTypes::LC_DYSYMTAB => LoadCommandTypes::Dysymtab,
     243           24 :             LoadCommandTypes::LC_ENCRYPTION_INFO => LoadCommandTypes::EncryptionInfo,
     244            0 :             LoadCommandTypes::LC_ENCRYPTION_INFO_64 => LoadCommandTypes::EncryptionInfo64,
     245            0 :             LoadCommandTypes::LC_FILESET_ENTRY => LoadCommandTypes::FilesetEntry,
     246          312 :             LoadCommandTypes::LC_FUNCTION_STARTS => LoadCommandTypes::FunctionStarts,
     247            0 :             LoadCommandTypes::LC_FVMFILE => LoadCommandTypes::Fvmfile,
     248            0 :             LoadCommandTypes::LC_IDENT => LoadCommandTypes::Ident,
     249            0 :             LoadCommandTypes::LC_IDFVMLIB => LoadCommandTypes::Idfvmlib,
     250          240 :             LoadCommandTypes::LC_ID_DYLIB => LoadCommandTypes::IdDylib,
     251            0 :             LoadCommandTypes::LC_ID_DYLINKER => LoadCommandTypes::IdDylinker,
     252            0 :             LoadCommandTypes::LC_LAZY_LOAD_DYLIB => LoadCommandTypes::LazyLoadDylib,
     253              :             LoadCommandTypes::LC_LINKER_OPTIMIZATION_HINT => {
     254           24 :                 LoadCommandTypes::LinkerOptimizationHint
     255              :             }
     256            0 :             LoadCommandTypes::LC_LINKER_OPTION => LoadCommandTypes::LinkerOption,
     257            0 :             LoadCommandTypes::LC_LOADFVMLIB => LoadCommandTypes::LoadFvmLib,
     258        68196 :             LoadCommandTypes::LC_LOAD_DYLIB => LoadCommandTypes::LoadDylib,
     259           96 :             LoadCommandTypes::LC_LOAD_DYLINKER => LoadCommandTypes::LoadDylinker,
     260         2184 :             LoadCommandTypes::LC_LOAD_UPWARD_DYLIB => LoadCommandTypes::LoadUpwardDylib,
     261          720 :             LoadCommandTypes::LC_LOAD_WEAK_DYLIB => LoadCommandTypes::LoadWeakDylib,
     262           72 :             LoadCommandTypes::LC_MAIN => LoadCommandTypes::Main,
     263         4320 :             LoadCommandTypes::LC_NOTE => LoadCommandTypes::Note,
     264            0 :             LoadCommandTypes::LC_PREBIND_CKSUM => LoadCommandTypes::PrebindCksum,
     265            0 :             LoadCommandTypes::LC_PREBOUND_DYLIB => LoadCommandTypes::PreboundDylib,
     266            0 :             LoadCommandTypes::LC_PREPAGE => LoadCommandTypes::Prepage,
     267         8592 :             LoadCommandTypes::LC_REEXPORT_DYLIB => LoadCommandTypes::ReExportDylib,
     268            0 :             LoadCommandTypes::LC_ROUTINES => LoadCommandTypes::Routines,
     269           24 :             LoadCommandTypes::LC_ROUTINES_64 => LoadCommandTypes::Routines64,
     270           36 :             LoadCommandTypes::LC_RPATH => LoadCommandTypes::Rpath,
     271       186252 :             LoadCommandTypes::LC_SEGMENT => LoadCommandTypes::Segment,
     272       121584 :             LoadCommandTypes::LC_SEGMENT_64 => LoadCommandTypes::Segment64,
     273           96 :             LoadCommandTypes::LC_SEGMENT_SPLIT_INFO => LoadCommandTypes::SegmentSplitInfo,
     274          312 :             LoadCommandTypes::LC_SOURCE_VERSION => LoadCommandTypes::SourceVersion,
     275          456 :             LoadCommandTypes::LC_SUB_CLIENT => LoadCommandTypes::SubClient,
     276           48 :             LoadCommandTypes::LC_SUB_FRAMEWORK => LoadCommandTypes::SubFramework,
     277            0 :             LoadCommandTypes::LC_SUB_LIBRARY => LoadCommandTypes::SubLibrary,
     278            0 :             LoadCommandTypes::LC_SUB_UMBRELLA => LoadCommandTypes::SubUmbrella,
     279            0 :             LoadCommandTypes::LC_SYMSEG => LoadCommandTypes::Symseg,
     280          360 :             LoadCommandTypes::LC_SYMTAB => LoadCommandTypes::Symtab,
     281            0 :             LoadCommandTypes::LC_THREAD => LoadCommandTypes::Thread,
     282           24 :             LoadCommandTypes::LC_TWOLEVEL_HINTS => LoadCommandTypes::TwoLevelHints,
     283           24 :             LoadCommandTypes::LC_UNIXTHREAD => LoadCommandTypes::Unixthread,
     284          696 :             LoadCommandTypes::LC_UUID => LoadCommandTypes::Uuid,
     285           48 :             LoadCommandTypes::LC_VERSION_MIN_IPHONEOS => LoadCommandTypes::VersionMinIphoneOS,
     286          144 :             LoadCommandTypes::LC_VERSION_MIN_MACOSX => LoadCommandTypes::VersionMinMacOSX,
     287            0 :             LoadCommandTypes::LC_VERSION_MIN_TVOS => LoadCommandTypes::VersionMinTvOS,
     288            0 :             LoadCommandTypes::LC_VERSION_MIN_WATCHOS => LoadCommandTypes::VersionMinWatchOS,
     289            0 :             LoadCommandTypes::LC_ATOM_INFO => LoadCommandTypes::AtomInfo,
     290           24 :             LoadCommandTypes::LC_FUNCTION_VARIANTS => LoadCommandTypes::FunctionVariants,
     291            0 :             LoadCommandTypes::LC_FUNCTION_VARIANT_FIXUPS => LoadCommandTypes::FunctionVariantsFixups,
     292            0 :             LoadCommandTypes::LC_TARGET_TRIPLE => LoadCommandTypes::TargetTriple,
     293           48 :             LoadCommandTypes::LIEF_UNKNOWN => LoadCommandTypes::LiefUnknown,
     294            0 :             _ => LoadCommandTypes::Unknown(value),
     295              :         }
     296       396756 :     }
     297              : }
     298              : 
     299         5976 : #[derive(Debug)]
     300              : /// Enum that wraps all the different Mach-O load commands (`LC_xxx`).
     301              : /// Note that all these commands implements the trait: [`Command`]
     302              : pub enum Commands<'a> {
     303              :     Generic(Generic<'a>),
     304              :     BuildVersion(BuildVersion<'a>),
     305              :     CodeSignature(CodeSignature<'a>),
     306              :     CodeSignatureDir(CodeSignatureDir<'a>),
     307              :     DataInCode(DataInCode<'a>),
     308              :     DyldChainedFixups(DyldChainedFixups<'a>),
     309              :     DyldEnvironment(DyldEnvironment<'a>),
     310              :     DyldExportsTrie(DyldExportsTrie<'a>),
     311              :     DyldInfo(DyldInfo<'a>),
     312              :     Dylib(Dylib<'a>),
     313              :     Dylinker(Dylinker<'a>),
     314              :     DynamicSymbolCommand(DynamicSymbolCommand<'a>),
     315              :     EncryptionInfo(EncryptionInfo<'a>),
     316              :     FunctionStarts(FunctionStarts<'a>),
     317              :     LinkerOptHint(LinkerOptHint<'a>),
     318              :     Main(Main<'a>),
     319              :     RPath(RPath<'a>),
     320              :     Routine(Routine<'a>),
     321              :     Segment(Segment<'a>),
     322              :     SegmentSplitInfo(SegmentSplitInfo<'a>),
     323              :     SourceVersion(SourceVersion<'a>),
     324              :     SubFramework(SubFramework<'a>),
     325              :     SubClient(SubClient<'a>),
     326              :     SymbolCommand(SymbolCommand<'a>),
     327              :     ThreadCommand(ThreadCommand<'a>),
     328              :     TwoLevelHints(TwoLevelHints<'a>),
     329              :     UUID(UUID<'a>),
     330              :     VersionMin(VersionMin<'a>),
     331              :     AtomInfo(AtomInfo<'a>),
     332              :     Note(Note<'a>),
     333              :     FunctionVariants(FunctionVariants<'a>),
     334              :     FunctionVariantFixups(FunctionVariantFixups<'a>),
     335              :     Unknown(Unknown<'a>),
     336              : }
     337              : 
     338              : impl<'a> Commands<'a> {
     339         5976 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::MachO_Command>) -> Self {
     340         5976 :         unsafe {
     341         5976 :             let cmd_ref = ffi_entry.as_ref().unwrap();
     342         5976 : 
     343         5976 :             if ffi::MachO_Dylib::classof(cmd_ref) {
     344         1128 :                 let raw = {
     345         1128 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     346         1128 :                     type To = cxx::UniquePtr<ffi::MachO_Dylib>;
     347         1128 :                     std::mem::transmute::<From, To>(ffi_entry)
     348         1128 :                 };
     349         1128 :                 Commands::Dylib(Dylib::from_ffi(raw))
     350         4848 :             } else if ffi::MachO_Main::classof(cmd_ref) {
     351           36 :                 let raw = {
     352           36 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     353           36 :                     type To = cxx::UniquePtr<ffi::MachO_Main>;
     354           36 :                     std::mem::transmute::<From, To>(ffi_entry)
     355           36 :                 };
     356           36 :                 Commands::Main(Main::from_ffi(raw))
     357         4812 :             } else if ffi::MachO_SegmentCommand::classof(cmd_ref) {
     358         1044 :                 let raw = {
     359         1044 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     360         1044 :                     type To = cxx::UniquePtr<ffi::MachO_SegmentCommand>;
     361         1044 :                     std::mem::transmute::<From, To>(ffi_entry)
     362         1044 :                 };
     363         1044 :                 Commands::Segment(Segment::from_ffi(raw))
     364         3768 :             } else if ffi::MachO_DyldInfo::classof(cmd_ref) {
     365          108 :                 let raw = {
     366          108 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     367          108 :                     type To = cxx::UniquePtr<ffi::MachO_DyldInfo>;
     368          108 :                     std::mem::transmute::<From, To>(ffi_entry)
     369          108 :                 };
     370          108 :                 Commands::DyldInfo(DyldInfo::from_ffi(raw))
     371         3660 :             } else if ffi::MachO_UUIDCommand::classof(cmd_ref) {
     372          348 :                 let raw = {
     373          348 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     374          348 :                     type To = cxx::UniquePtr<ffi::MachO_UUIDCommand>;
     375          348 :                     std::mem::transmute::<From, To>(ffi_entry)
     376          348 :                 };
     377          348 :                 Commands::UUID(UUID::from_ffi(raw))
     378         3312 :             } else if ffi::MachO_Dylinker::classof(cmd_ref) {
     379           48 :                 let raw = {
     380           48 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     381           48 :                     type To = cxx::UniquePtr<ffi::MachO_Dylinker>;
     382           48 :                     std::mem::transmute::<From, To>(ffi_entry)
     383           48 :                 };
     384           48 :                 Commands::Dylinker(Dylinker::from_ffi(raw))
     385         3264 :             } else if ffi::MachO_FunctionStarts::classof(cmd_ref) {
     386          156 :                 let raw = {
     387          156 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     388          156 :                     type To = cxx::UniquePtr<ffi::MachO_FunctionStarts>;
     389          156 :                     std::mem::transmute::<From, To>(ffi_entry)
     390          156 :                 };
     391          156 :                 Commands::FunctionStarts(FunctionStarts::from_ffi(raw))
     392         3108 :             } else if ffi::MachO_SourceVersion::classof(cmd_ref) {
     393          156 :                 let raw = {
     394          156 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     395          156 :                     type To = cxx::UniquePtr<ffi::MachO_SourceVersion>;
     396          156 :                     std::mem::transmute::<From, To>(ffi_entry)
     397          156 :                 };
     398          156 :                 Commands::SourceVersion(SourceVersion::from_ffi(raw))
     399         2952 :             } else if ffi::MachO_ThreadCommand::classof(cmd_ref) {
     400           12 :                 let raw = {
     401           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     402           12 :                     type To = cxx::UniquePtr<ffi::MachO_ThreadCommand>;
     403           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     404           12 :                 };
     405           12 :                 Commands::ThreadCommand(ThreadCommand::from_ffi(raw))
     406         2940 :             } else if ffi::MachO_RPathCommand::classof(cmd_ref) {
     407           24 :                 let raw = {
     408           24 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     409           24 :                     type To = cxx::UniquePtr<ffi::MachO_RPathCommand>;
     410           24 :                     std::mem::transmute::<From, To>(ffi_entry)
     411           24 :                 };
     412           24 :                 Commands::RPath(RPath::from_ffi(raw))
     413         2916 :             } else if ffi::MachO_Routine::classof(cmd_ref) {
     414           12 :                 let raw = {
     415           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     416           12 :                     type To = cxx::UniquePtr<ffi::MachO_Routine>;
     417           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     418           12 :                 };
     419           12 :                 Commands::Routine(Routine::from_ffi(raw))
     420         2904 :             } else if ffi::MachO_SymbolCommand::classof(cmd_ref) {
     421          180 :                 let raw = {
     422          180 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     423          180 :                     type To = cxx::UniquePtr<ffi::MachO_SymbolCommand>;
     424          180 :                     std::mem::transmute::<From, To>(ffi_entry)
     425          180 :                 };
     426          180 :                 Commands::SymbolCommand(SymbolCommand::from_ffi(raw))
     427         2724 :             } else if ffi::MachO_DynamicSymbolCommand::classof(cmd_ref) {
     428          180 :                 let raw = {
     429          180 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     430          180 :                     type To = cxx::UniquePtr<ffi::MachO_DynamicSymbolCommand>;
     431          180 :                     std::mem::transmute::<From, To>(ffi_entry)
     432          180 :                 };
     433          180 :                 Commands::DynamicSymbolCommand(DynamicSymbolCommand::from_ffi(raw))
     434         2544 :             } else if ffi::MachO_CodeSignature::classof(cmd_ref) {
     435          108 :                 let raw = {
     436          108 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     437          108 :                     type To = cxx::UniquePtr<ffi::MachO_CodeSignature>;
     438          108 :                     std::mem::transmute::<From, To>(ffi_entry)
     439          108 :                 };
     440          108 :                 Commands::CodeSignature(CodeSignature::from_ffi(raw))
     441         2436 :             } else if ffi::MachO_CodeSignatureDir::classof(cmd_ref) {
     442           12 :                 let raw = {
     443           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     444           12 :                     type To = cxx::UniquePtr<ffi::MachO_CodeSignatureDir>;
     445           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     446           12 :                 };
     447           12 :                 Commands::CodeSignatureDir(CodeSignatureDir::from_ffi(raw))
     448         2424 :             } else if ffi::MachO_DataInCode::classof(cmd_ref) {
     449          144 :                 let raw = {
     450          144 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     451          144 :                     type To = cxx::UniquePtr<ffi::MachO_DataInCode>;
     452          144 :                     std::mem::transmute::<From, To>(ffi_entry)
     453          144 :                 };
     454          144 :                 Commands::DataInCode(DataInCode::from_ffi(raw))
     455         2280 :             } else if ffi::MachO_SegmentSplitInfo::classof(cmd_ref) {
     456           48 :                 let raw = {
     457           48 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     458           48 :                     type To = cxx::UniquePtr<ffi::MachO_SegmentSplitInfo>;
     459           48 :                     std::mem::transmute::<From, To>(ffi_entry)
     460           48 :                 };
     461           48 :                 Commands::SegmentSplitInfo(SegmentSplitInfo::from_ffi(raw))
     462         2232 :             } else if ffi::MachO_EncryptionInfo::classof(cmd_ref) {
     463           12 :                 let raw = {
     464           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     465           12 :                     type To = cxx::UniquePtr<ffi::MachO_EncryptionInfo>;
     466           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     467           12 :                 };
     468           12 :                 Commands::EncryptionInfo(EncryptionInfo::from_ffi(raw))
     469         2220 :             } else if ffi::MachO_SubFramework::classof(cmd_ref) {
     470           24 :                 let raw = {
     471           24 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     472           24 :                     type To = cxx::UniquePtr<ffi::MachO_SubFramework>;
     473           24 :                     std::mem::transmute::<From, To>(ffi_entry)
     474           24 :                 };
     475           24 :                 Commands::SubFramework(SubFramework::from_ffi(raw))
     476         2196 :             } else if ffi::MachO_SubClient::classof(cmd_ref) {
     477          228 :                 let raw = {
     478          228 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     479          228 :                     type To = cxx::UniquePtr<ffi::MachO_SubClient>;
     480          228 :                     std::mem::transmute::<From, To>(ffi_entry)
     481          228 :                 };
     482          228 :                 Commands::SubClient(SubClient::from_ffi(raw))
     483         1968 :             } else if ffi::MachO_DyldEnvironment::classof(cmd_ref) {
     484           12 :                 let raw = {
     485           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     486           12 :                     type To = cxx::UniquePtr<ffi::MachO_DyldEnvironment>;
     487           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     488           12 :                 };
     489           12 :                 Commands::DyldEnvironment(DyldEnvironment::from_ffi(raw))
     490         1956 :             } else if ffi::MachO_BuildVersion::classof(cmd_ref) {
     491          252 :                 let raw = {
     492          252 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     493          252 :                     type To = cxx::UniquePtr<ffi::MachO_BuildVersion>;
     494          252 :                     std::mem::transmute::<From, To>(ffi_entry)
     495          252 :                 };
     496          252 :                 Commands::BuildVersion(BuildVersion::from_ffi(raw))
     497         1704 :             } else if ffi::MachO_DyldChainedFixups::classof(cmd_ref) {
     498           36 :                 let raw = {
     499           36 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     500           36 :                     type To = cxx::UniquePtr<ffi::MachO_DyldChainedFixups>;
     501           36 :                     std::mem::transmute::<From, To>(ffi_entry)
     502           36 :                 };
     503           36 :                 Commands::DyldChainedFixups(DyldChainedFixups::from_ffi(raw))
     504         1668 :             } else if ffi::MachO_DyldExportsTrie::classof(cmd_ref) {
     505           48 :                 let raw = {
     506           48 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     507           48 :                     type To = cxx::UniquePtr<ffi::MachO_DyldExportsTrie>;
     508           48 :                     std::mem::transmute::<From, To>(ffi_entry)
     509           48 :                 };
     510           48 :                 Commands::DyldExportsTrie(DyldExportsTrie::from_ffi(raw))
     511         1620 :             } else if ffi::MachO_TwoLevelHints::classof(cmd_ref) {
     512           12 :                 let raw = {
     513           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     514           12 :                     type To = cxx::UniquePtr<ffi::MachO_TwoLevelHints>;
     515           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     516           12 :                 };
     517           12 :                 Commands::TwoLevelHints(TwoLevelHints::from_ffi(raw))
     518         1608 :             } else if ffi::MachO_LinkerOptHint::classof(cmd_ref) {
     519           12 :                 let raw = {
     520           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     521           12 :                     type To = cxx::UniquePtr<ffi::MachO_LinkerOptHint>;
     522           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     523           12 :                 };
     524           12 :                 Commands::LinkerOptHint(LinkerOptHint::from_ffi(raw))
     525         1596 :             } else if ffi::MachO_VersionMin::classof(cmd_ref) {
     526           96 :                 let raw = {
     527           96 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     528           96 :                     type To = cxx::UniquePtr<ffi::MachO_VersionMin>;
     529           96 :                     std::mem::transmute::<From, To>(ffi_entry)
     530           96 :                 };
     531           96 :                 Commands::VersionMin(VersionMin::from_ffi(raw))
     532         1500 :             } else if ffi::MachO_UnknownCommand::classof(cmd_ref) {
     533           48 :                 let raw = {
     534           48 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     535           48 :                     type To = cxx::UniquePtr<ffi::MachO_UnknownCommand>;
     536           48 :                     std::mem::transmute::<From, To>(ffi_entry)
     537           48 :                 };
     538           48 :                 Commands::Unknown(Unknown::from_ffi(raw))
     539         1452 :             } else if ffi::MachO_AtomInfo::classof(cmd_ref) {
     540            0 :                 let raw = {
     541            0 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     542            0 :                     type To = cxx::UniquePtr<ffi::MachO_AtomInfo>;
     543            0 :                     std::mem::transmute::<From, To>(ffi_entry)
     544            0 :                 };
     545            0 :                 Commands::AtomInfo(AtomInfo::from_ffi(raw))
     546         1452 :             } else if ffi::MachO_NoteCommand::classof(cmd_ref) {
     547         1440 :                 let raw = {
     548         1440 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     549         1440 :                     type To = cxx::UniquePtr<ffi::MachO_NoteCommand>;
     550         1440 :                     std::mem::transmute::<From, To>(ffi_entry)
     551         1440 :                 };
     552         1440 :                 Commands::Note(Note::from_ffi(raw))
     553           12 :             } else if ffi::MachO_FunctionVariants::classof(cmd_ref) {
     554           12 :                 let raw = {
     555           12 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     556           12 :                     type To = cxx::UniquePtr<ffi::MachO_FunctionVariants>;
     557           12 :                     std::mem::transmute::<From, To>(ffi_entry)
     558           12 :                 };
     559           12 :                 Commands::FunctionVariants(FunctionVariants::from_ffi(raw))
     560            0 :             } else if ffi::MachO_FunctionVariantFixups::classof(cmd_ref) {
     561            0 :                 let raw = {
     562            0 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     563            0 :                     type To = cxx::UniquePtr<ffi::MachO_FunctionVariantFixups>;
     564            0 :                     std::mem::transmute::<From, To>(ffi_entry)
     565            0 :                 };
     566            0 :                 Commands::FunctionVariantFixups(FunctionVariantFixups::from_ffi(raw))
     567              :             } else {
     568            0 :                 Commands::Generic(Generic::from_ffi(ffi_entry))
     569              :             }
     570              :         }
     571         5976 :     }
     572              : }
     573              : 
     574              : pub struct Generic<'a> {
     575              :     ptr: cxx::UniquePtr<ffi::MachO_Command>,
     576              :     _owner: PhantomData<&'a ffi::MachO_Binary>,
     577              : }
     578              : 
     579              : impl std::fmt::Debug for Generic<'_> {
     580            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     581            0 :         f.debug_struct("Generic").finish()
     582            0 :     }
     583              : }
     584              : 
     585              : impl FromFFI<ffi::MachO_Command> for Generic<'_> {
     586            0 :     fn from_ffi(cmd: cxx::UniquePtr<ffi::MachO_Command>) -> Self {
     587            0 :         Self {
     588            0 :             ptr: cmd,
     589            0 :             _owner: PhantomData,
     590            0 :         }
     591            0 :     }
     592              : }
     593              : 
     594              : /// Trait shared by **all** the load command: [`Commands`]
     595              : pub trait Command {
     596              :     #[doc(hidden)]
     597              :     fn get_base(&self) -> &ffi::MachO_Command;
     598              : 
     599              :     /// Size of the command (should be greater than ``sizeof(load_command)``)
     600       396756 :     fn size(&self) -> u32 {
     601       396756 :         self.get_base().size()
     602       396756 :     }
     603              : 
     604              :     /// Offset of the command within the *Load Command Table*
     605       396756 :     fn offset(&self) -> u64 {
     606       396756 :         self.get_base().command_offset()
     607       396756 :     }
     608              : 
     609              :     /// The command's type
     610       396756 :     fn command_type(&self) -> LoadCommandTypes {
     611       396756 :         LoadCommandTypes::from_value(self.get_base().cmd_type())
     612       396756 :     }
     613              : 
     614              :     /// The raw command as a slice of bytes
     615       396756 :     fn data(&self) -> &[u8] {
     616       396756 :         to_slice!(self.get_base().data());
     617       396756 :     }
     618              : }
     619              : 
     620              : impl Command for Commands<'_> {
     621            0 :     fn get_base(&self) -> &ffi::MachO_Command {
     622            0 :         match &self {
     623            0 :             Commands::Generic(cmd) => {
     624            0 :                 cmd.get_base()
     625              :             }
     626            0 :             Commands::BuildVersion(cmd) => {
     627            0 :                 cmd.get_base()
     628              :             }
     629            0 :             Commands::CodeSignature(cmd) => {
     630            0 :                 cmd.get_base()
     631              :             }
     632            0 :             Commands::CodeSignatureDir(cmd) => {
     633            0 :                 cmd.get_base()
     634              :             }
     635            0 :             Commands::DataInCode(cmd) => {
     636            0 :                 cmd.get_base()
     637              :             }
     638            0 :             Commands::DyldChainedFixups(cmd) => {
     639            0 :                 cmd.get_base()
     640              :             }
     641            0 :             Commands::DyldEnvironment(cmd) => {
     642            0 :                 cmd.get_base()
     643              :             }
     644            0 :             Commands::DyldExportsTrie(cmd) => {
     645            0 :                 cmd.get_base()
     646              :             }
     647            0 :             Commands::DyldInfo(cmd) => {
     648            0 :                 cmd.get_base()
     649              :             }
     650            0 :             Commands::Dylib(cmd) => {
     651            0 :                 cmd.get_base()
     652              :             }
     653            0 :             Commands::Dylinker(cmd) => {
     654            0 :                 cmd.get_base()
     655              :             }
     656            0 :             Commands::DynamicSymbolCommand(cmd) => {
     657            0 :                 cmd.get_base()
     658              :             }
     659            0 :             Commands::EncryptionInfo(cmd) => {
     660            0 :                 cmd.get_base()
     661              :             }
     662            0 :             Commands::FunctionStarts(cmd) => {
     663            0 :                 cmd.get_base()
     664              :             }
     665            0 :             Commands::LinkerOptHint(cmd) => {
     666            0 :                 cmd.get_base()
     667              :             }
     668            0 :             Commands::Main(cmd) => {
     669            0 :                 cmd.get_base()
     670              :             }
     671            0 :             Commands::Routine(cmd) => {
     672            0 :                 cmd.get_base()
     673              :             }
     674            0 :             Commands::RPath(cmd) => {
     675            0 :                 cmd.get_base()
     676              :             }
     677            0 :             Commands::Segment(cmd) => {
     678            0 :                 cmd.get_base()
     679              :             }
     680            0 :             Commands::SegmentSplitInfo(cmd) => {
     681            0 :                 cmd.get_base()
     682              :             }
     683            0 :             Commands::SourceVersion(cmd) => {
     684            0 :                 cmd.get_base()
     685              :             }
     686            0 :             Commands::SubFramework(cmd) => {
     687            0 :                 cmd.get_base()
     688              :             }
     689            0 :             Commands::SubClient(cmd) => {
     690            0 :                 cmd.get_base()
     691              :             }
     692            0 :             Commands::SymbolCommand(cmd) => {
     693            0 :                 cmd.get_base()
     694              :             }
     695            0 :             Commands::ThreadCommand(cmd) => {
     696            0 :                 cmd.get_base()
     697              :             }
     698            0 :             Commands::TwoLevelHints(cmd) => {
     699            0 :                 cmd.get_base()
     700              :             }
     701            0 :             Commands::UUID(cmd) => {
     702            0 :                 cmd.get_base()
     703              :             }
     704            0 :             Commands::VersionMin(cmd) => {
     705            0 :                 cmd.get_base()
     706              :             }
     707            0 :             Commands::AtomInfo(cmd) => {
     708            0 :                 cmd.get_base()
     709              :             }
     710            0 :             Commands::Note(cmd) => {
     711            0 :                 cmd.get_base()
     712              :             }
     713            0 :             Commands::FunctionVariants(cmd) => {
     714            0 :                 cmd.get_base()
     715              :             }
     716            0 :             Commands::FunctionVariantFixups(cmd) => {
     717            0 :                 cmd.get_base()
     718              :             }
     719            0 :             Commands::Unknown(cmd) => {
     720            0 :                 cmd.get_base()
     721              :             }
     722              :         }
     723            0 :     }
     724              : }
     725              : 
     726              : impl Command for Generic<'_> {
     727            0 :     fn get_base(&self) -> &ffi::MachO_Command {
     728            0 :         self.ptr.as_ref().unwrap()
     729            0 :     }
     730              : }
     731              : 
     732              : impl std::fmt::Debug for &dyn Command {
     733       396756 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     734       396756 :         f.debug_struct("Command")
     735       396756 :             .field("offset", &self.offset())
     736       396756 :             .field("size", &self.size())
     737       396756 :             .field("type", &self.command_type())
     738       396756 :             .field("data_len", &self.data().len())
     739       396756 :             .finish()
     740       396756 :     }
     741              : }
     742              : 
     743         5976 : declare_iterator!(
     744         5976 :     CommandsIter,
     745         5976 :     Commands<'a>,
     746         5976 :     ffi::MachO_Command,
     747         5976 :     ffi::MachO_Binary,
     748         5976 :     ffi::MachO_Binary_it_commands
     749         5976 : );
        

Generated by: LCOV version 2.1-1