LCOV - code coverage report
Current view: top level - src/macho - commands.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 73.6 % 363 267
Test Date: 2024-11-30:00:00:00 Functions: 92.2 % 128 118

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

Generated by: LCOV version 2.1-1