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

Generated by: LCOV version 2.1-1