LCOV - code coverage report
Current view: top level - src/macho - commands.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 70.9 % 412 292
Test Date: 2026-02-28:00:00:00 Functions: 87.8 % 148 130

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

Generated by: LCOV version 2.1-1