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-02-23: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       324790 : #[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       324790 :     pub fn from_value(value: u64) -> Self {
     217       324790 :         match value {
     218          100 :             LoadCommandTypes::LC_BUILD_VERSION => LoadCommandTypes::BuildVersion,
     219          160 :             LoadCommandTypes::LC_CODE_SIGNATURE => LoadCommandTypes::CodeSignature,
     220          220 :             LoadCommandTypes::LC_DATA_IN_CODE => LoadCommandTypes::DataInCode,
     221           40 :             LoadCommandTypes::LC_DYLD_CHAINED_FIXUPS => LoadCommandTypes::DyldChainedFixups,
     222           20 :             LoadCommandTypes::LC_DYLD_ENVIRONMENT => LoadCommandTypes::DyldEnvironment,
     223           60 :             LoadCommandTypes::LC_DYLD_EXPORTS_TRIE => LoadCommandTypes::DyldExportsTrie,
     224            0 :             LoadCommandTypes::LC_DYLD_INFO => LoadCommandTypes::DyldInfo,
     225          180 :             LoadCommandTypes::LC_DYLD_INFO_ONLY => LoadCommandTypes::DyldInfoOnly,
     226           20 :             LoadCommandTypes::LC_DYLIB_CODE_SIGN_DRS => LoadCommandTypes::DylibCodeSignDrs,
     227          280 :             LoadCommandTypes::LC_DYSYMTAB => LoadCommandTypes::Dysymtab,
     228           20 :             LoadCommandTypes::LC_ENCRYPTION_INFO => LoadCommandTypes::EncryptionInfo,
     229            0 :             LoadCommandTypes::LC_ENCRYPTION_INFO_64 => LoadCommandTypes::EncryptionInfo64,
     230            0 :             LoadCommandTypes::LC_FILESET_ENTRY => LoadCommandTypes::FilesetEntry,
     231          240 :             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          180 :             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           20 :                 LoadCommandTypes::LinkerOptimizationHint
     240              :             }
     241            0 :             LoadCommandTypes::LC_LINKER_OPTION => LoadCommandTypes::LinkerOption,
     242            0 :             LoadCommandTypes::LC_LOADFVMLIB => LoadCommandTypes::LoadFvmLib,
     243        56780 :             LoadCommandTypes::LC_LOAD_DYLIB => LoadCommandTypes::LoadDylib,
     244           80 :             LoadCommandTypes::LC_LOAD_DYLINKER => LoadCommandTypes::LoadDylinker,
     245         1820 :             LoadCommandTypes::LC_LOAD_UPWARD_DYLIB => LoadCommandTypes::LoadUpwardDylib,
     246          600 :             LoadCommandTypes::LC_LOAD_WEAK_DYLIB => LoadCommandTypes::LoadWeakDylib,
     247           60 :             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         7160 :             LoadCommandTypes::LC_REEXPORT_DYLIB => LoadCommandTypes::ReExportDylib,
     253            0 :             LoadCommandTypes::LC_ROUTINES => LoadCommandTypes::Routines,
     254           20 :             LoadCommandTypes::LC_ROUTINES_64 => LoadCommandTypes::Routines64,
     255           30 :             LoadCommandTypes::LC_RPATH => LoadCommandTypes::Rpath,
     256       155210 :             LoadCommandTypes::LC_SEGMENT => LoadCommandTypes::Segment,
     257        99970 :             LoadCommandTypes::LC_SEGMENT_64 => LoadCommandTypes::Segment64,
     258           80 :             LoadCommandTypes::LC_SEGMENT_SPLIT_INFO => LoadCommandTypes::SegmentSplitInfo,
     259          240 :             LoadCommandTypes::LC_SOURCE_VERSION => LoadCommandTypes::SourceVersion,
     260          380 :             LoadCommandTypes::LC_SUB_CLIENT => LoadCommandTypes::SubClient,
     261           40 :             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          280 :             LoadCommandTypes::LC_SYMTAB => LoadCommandTypes::Symtab,
     266            0 :             LoadCommandTypes::LC_THREAD => LoadCommandTypes::Thread,
     267           20 :             LoadCommandTypes::LC_TWOLEVEL_HINTS => LoadCommandTypes::TwoLevelHints,
     268           20 :             LoadCommandTypes::LC_UNIXTHREAD => LoadCommandTypes::Unixthread,
     269          260 :             LoadCommandTypes::LC_UUID => LoadCommandTypes::Uuid,
     270           40 :             LoadCommandTypes::LC_VERSION_MIN_IPHONEOS => LoadCommandTypes::VersionMinIphoneOS,
     271          120 :             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           40 :             LoadCommandTypes::LIEF_UNKNOWN => LoadCommandTypes::LiefUnknown,
     276            0 :             _ => LoadCommandTypes::Unknown(value),
     277              :         }
     278       324790 :     }
     279              : }
     280              : 
     281         3000 : #[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         3000 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::MachO_Command>) -> Self {
     319         3000 :         unsafe {
     320         3000 :             let cmd_ref = ffi_entry.as_ref().unwrap();
     321         3000 : 
     322         3000 :             if ffi::MachO_Dylib::classof(cmd_ref) {
     323          910 :                 let raw = {
     324          910 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     325          910 :                     type To = cxx::UniquePtr<ffi::MachO_Dylib>;
     326          910 :                     std::mem::transmute::<From, To>(ffi_entry)
     327          910 :                 };
     328          910 :                 Commands::Dylib(Dylib::from_ffi(raw))
     329         2090 :             } else if ffi::MachO_Main::classof(cmd_ref) {
     330           30 :                 let raw = {
     331           30 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     332           30 :                     type To = cxx::UniquePtr<ffi::MachO_Main>;
     333           30 :                     std::mem::transmute::<From, To>(ffi_entry)
     334           30 :                 };
     335           30 :                 Commands::Main(Main::from_ffi(raw))
     336         2060 :             } else if ffi::MachO_SegmentCommand::classof(cmd_ref) {
     337          530 :                 let raw = {
     338          530 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     339          530 :                     type To = cxx::UniquePtr<ffi::MachO_SegmentCommand>;
     340          530 :                     std::mem::transmute::<From, To>(ffi_entry)
     341          530 :                 };
     342          530 :                 Commands::Segment(Segment::from_ffi(raw))
     343         1530 :             } else if ffi::MachO_DyldInfo::classof(cmd_ref) {
     344           90 :                 let raw = {
     345           90 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     346           90 :                     type To = cxx::UniquePtr<ffi::MachO_DyldInfo>;
     347           90 :                     std::mem::transmute::<From, To>(ffi_entry)
     348           90 :                 };
     349           90 :                 Commands::DyldInfo(DyldInfo::from_ffi(raw))
     350         1440 :             } else if ffi::MachO_UUIDCommand::classof(cmd_ref) {
     351          130 :                 let raw = {
     352          130 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     353          130 :                     type To = cxx::UniquePtr<ffi::MachO_UUIDCommand>;
     354          130 :                     std::mem::transmute::<From, To>(ffi_entry)
     355          130 :                 };
     356          130 :                 Commands::UUID(UUID::from_ffi(raw))
     357         1310 :             } else if ffi::MachO_Dylinker::classof(cmd_ref) {
     358           40 :                 let raw = {
     359           40 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     360           40 :                     type To = cxx::UniquePtr<ffi::MachO_Dylinker>;
     361           40 :                     std::mem::transmute::<From, To>(ffi_entry)
     362           40 :                 };
     363           40 :                 Commands::Dylinker(Dylinker::from_ffi(raw))
     364         1270 :             } else if ffi::MachO_FunctionStarts::classof(cmd_ref) {
     365          120 :                 let raw = {
     366          120 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     367          120 :                     type To = cxx::UniquePtr<ffi::MachO_FunctionStarts>;
     368          120 :                     std::mem::transmute::<From, To>(ffi_entry)
     369          120 :                 };
     370          120 :                 Commands::FunctionStarts(FunctionStarts::from_ffi(raw))
     371         1150 :             } else if ffi::MachO_SourceVersion::classof(cmd_ref) {
     372          120 :                 let raw = {
     373          120 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     374          120 :                     type To = cxx::UniquePtr<ffi::MachO_SourceVersion>;
     375          120 :                     std::mem::transmute::<From, To>(ffi_entry)
     376          120 :                 };
     377          120 :                 Commands::SourceVersion(SourceVersion::from_ffi(raw))
     378         1030 :             } else if ffi::MachO_ThreadCommand::classof(cmd_ref) {
     379           10 :                 let raw = {
     380           10 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     381           10 :                     type To = cxx::UniquePtr<ffi::MachO_ThreadCommand>;
     382           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     383           10 :                 };
     384           10 :                 Commands::ThreadCommand(ThreadCommand::from_ffi(raw))
     385         1020 :             } else if ffi::MachO_RPathCommand::classof(cmd_ref) {
     386           20 :                 let raw = {
     387           20 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     388           20 :                     type To = cxx::UniquePtr<ffi::MachO_RPathCommand>;
     389           20 :                     std::mem::transmute::<From, To>(ffi_entry)
     390           20 :                 };
     391           20 :                 Commands::RPath(RPath::from_ffi(raw))
     392         1000 :             } else if ffi::MachO_Routine::classof(cmd_ref) {
     393           10 :                 let raw = {
     394           10 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     395           10 :                     type To = cxx::UniquePtr<ffi::MachO_Routine>;
     396           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     397           10 :                 };
     398           10 :                 Commands::Routine(Routine::from_ffi(raw))
     399          990 :             } else if ffi::MachO_SymbolCommand::classof(cmd_ref) {
     400          140 :                 let raw = {
     401          140 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     402          140 :                     type To = cxx::UniquePtr<ffi::MachO_SymbolCommand>;
     403          140 :                     std::mem::transmute::<From, To>(ffi_entry)
     404          140 :                 };
     405          140 :                 Commands::SymbolCommand(SymbolCommand::from_ffi(raw))
     406          850 :             } else if ffi::MachO_DynamicSymbolCommand::classof(cmd_ref) {
     407          140 :                 let raw = {
     408          140 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     409          140 :                     type To = cxx::UniquePtr<ffi::MachO_DynamicSymbolCommand>;
     410          140 :                     std::mem::transmute::<From, To>(ffi_entry)
     411          140 :                 };
     412          140 :                 Commands::DynamicSymbolCommand(DynamicSymbolCommand::from_ffi(raw))
     413          710 :             } else if ffi::MachO_CodeSignature::classof(cmd_ref) {
     414           80 :                 let raw = {
     415           80 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     416           80 :                     type To = cxx::UniquePtr<ffi::MachO_CodeSignature>;
     417           80 :                     std::mem::transmute::<From, To>(ffi_entry)
     418           80 :                 };
     419           80 :                 Commands::CodeSignature(CodeSignature::from_ffi(raw))
     420          630 :             } else if ffi::MachO_CodeSignatureDir::classof(cmd_ref) {
     421           10 :                 let raw = {
     422           10 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     423           10 :                     type To = cxx::UniquePtr<ffi::MachO_CodeSignatureDir>;
     424           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     425           10 :                 };
     426           10 :                 Commands::CodeSignatureDir(CodeSignatureDir::from_ffi(raw))
     427          620 :             } else if ffi::MachO_DataInCode::classof(cmd_ref) {
     428          110 :                 let raw = {
     429          110 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     430          110 :                     type To = cxx::UniquePtr<ffi::MachO_DataInCode>;
     431          110 :                     std::mem::transmute::<From, To>(ffi_entry)
     432          110 :                 };
     433          110 :                 Commands::DataInCode(DataInCode::from_ffi(raw))
     434          510 :             } else if ffi::MachO_SegmentSplitInfo::classof(cmd_ref) {
     435           40 :                 let raw = {
     436           40 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     437           40 :                     type To = cxx::UniquePtr<ffi::MachO_SegmentSplitInfo>;
     438           40 :                     std::mem::transmute::<From, To>(ffi_entry)
     439           40 :                 };
     440           40 :                 Commands::SegmentSplitInfo(SegmentSplitInfo::from_ffi(raw))
     441          470 :             } else if ffi::MachO_EncryptionInfo::classof(cmd_ref) {
     442           10 :                 let raw = {
     443           10 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     444           10 :                     type To = cxx::UniquePtr<ffi::MachO_EncryptionInfo>;
     445           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     446           10 :                 };
     447           10 :                 Commands::EncryptionInfo(EncryptionInfo::from_ffi(raw))
     448          460 :             } else if ffi::MachO_SubFramework::classof(cmd_ref) {
     449           20 :                 let raw = {
     450           20 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     451           20 :                     type To = cxx::UniquePtr<ffi::MachO_SubFramework>;
     452           20 :                     std::mem::transmute::<From, To>(ffi_entry)
     453           20 :                 };
     454           20 :                 Commands::SubFramework(SubFramework::from_ffi(raw))
     455          440 :             } else if ffi::MachO_SubClient::classof(cmd_ref) {
     456          190 :                 let raw = {
     457          190 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     458          190 :                     type To = cxx::UniquePtr<ffi::MachO_SubClient>;
     459          190 :                     std::mem::transmute::<From, To>(ffi_entry)
     460          190 :                 };
     461          190 :                 Commands::SubClient(SubClient::from_ffi(raw))
     462          250 :             } else if ffi::MachO_DyldEnvironment::classof(cmd_ref) {
     463           10 :                 let raw = {
     464           10 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     465           10 :                     type To = cxx::UniquePtr<ffi::MachO_DyldEnvironment>;
     466           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     467           10 :                 };
     468           10 :                 Commands::DyldEnvironment(DyldEnvironment::from_ffi(raw))
     469          240 :             } else if ffi::MachO_BuildVersion::classof(cmd_ref) {
     470           50 :                 let raw = {
     471           50 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     472           50 :                     type To = cxx::UniquePtr<ffi::MachO_BuildVersion>;
     473           50 :                     std::mem::transmute::<From, To>(ffi_entry)
     474           50 :                 };
     475           50 :                 Commands::BuildVersion(BuildVersion::from_ffi(raw))
     476          190 :             } else if ffi::MachO_DyldChainedFixups::classof(cmd_ref) {
     477           20 :                 let raw = {
     478           20 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     479           20 :                     type To = cxx::UniquePtr<ffi::MachO_DyldChainedFixups>;
     480           20 :                     std::mem::transmute::<From, To>(ffi_entry)
     481           20 :                 };
     482           20 :                 Commands::DyldChainedFixups(DyldChainedFixups::from_ffi(raw))
     483          170 :             } else if ffi::MachO_DyldExportsTrie::classof(cmd_ref) {
     484           30 :                 let raw = {
     485           30 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     486           30 :                     type To = cxx::UniquePtr<ffi::MachO_DyldExportsTrie>;
     487           30 :                     std::mem::transmute::<From, To>(ffi_entry)
     488           30 :                 };
     489           30 :                 Commands::DyldExportsTrie(DyldExportsTrie::from_ffi(raw))
     490          140 :             } else if ffi::MachO_TwoLevelHints::classof(cmd_ref) {
     491           10 :                 let raw = {
     492           10 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     493           10 :                     type To = cxx::UniquePtr<ffi::MachO_TwoLevelHints>;
     494           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     495           10 :                 };
     496           10 :                 Commands::TwoLevelHints(TwoLevelHints::from_ffi(raw))
     497          130 :             } else if ffi::MachO_LinkerOptHint::classof(cmd_ref) {
     498           10 :                 let raw = {
     499           10 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     500           10 :                     type To = cxx::UniquePtr<ffi::MachO_LinkerOptHint>;
     501           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     502           10 :                 };
     503           10 :                 Commands::LinkerOptHint(LinkerOptHint::from_ffi(raw))
     504          120 :             } else if ffi::MachO_VersionMin::classof(cmd_ref) {
     505           80 :                 let raw = {
     506           80 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     507           80 :                     type To = cxx::UniquePtr<ffi::MachO_VersionMin>;
     508           80 :                     std::mem::transmute::<From, To>(ffi_entry)
     509           80 :                 };
     510           80 :                 Commands::VersionMin(VersionMin::from_ffi(raw))
     511           40 :             } else if ffi::MachO_UnknownCommand::classof(cmd_ref) {
     512           40 :                 let raw = {
     513           40 :                     type From = cxx::UniquePtr<ffi::MachO_Command>;
     514           40 :                     type To = cxx::UniquePtr<ffi::MachO_UnknownCommand>;
     515           40 :                     std::mem::transmute::<From, To>(ffi_entry)
     516           40 :                 };
     517           40 :                 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         3000 :     }
     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       324790 :     fn size(&self) -> u32 {
     559       324790 :         self.get_base().size()
     560       324790 :     }
     561              : 
     562              :     /// Offset of the command within the *Load Command Table*
     563       324790 :     fn offset(&self) -> u64 {
     564       324790 :         self.get_base().command_offset()
     565       324790 :     }
     566              : 
     567              :     /// The command's type
     568       324790 :     fn command_type(&self) -> LoadCommandTypes {
     569       324790 :         LoadCommandTypes::from_value(self.get_base().cmd_type())
     570       324790 :     }
     571              : 
     572              :     /// The raw command as a slice of bytes
     573       324790 :     fn data(&self) -> &[u8] {
     574       324790 :         to_slice!(self.get_base().data());
     575       324790 :     }
     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       324790 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     683       324790 :         f.debug_struct("Command")
     684       324790 :             .field("offset", &self.offset())
     685       324790 :             .field("size", &self.size())
     686       324790 :             .field("type", &self.command_type())
     687       324790 :             .field("data_len", &self.data().len())
     688       324790 :             .finish()
     689       324790 :     }
     690              : }
     691              : 
     692         3000 : declare_iterator!(
     693         3000 :     CommandsIter,
     694         3000 :     Commands<'a>,
     695         3000 :     ffi::MachO_Command,
     696         3000 :     ffi::MachO_Binary,
     697         3000 :     ffi::MachO_Binary_it_commands
     698         3000 : );
        

Generated by: LCOV version 2.1-1