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 259832 : #[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 259832 : pub fn from_value(value: u64) -> Self {
212 259832 : match value {
213 80 : LoadCommandTypes::LC_BUILD_VERSION => LoadCommandTypes::BuildVersion,
214 128 : LoadCommandTypes::LC_CODE_SIGNATURE => LoadCommandTypes::CodeSignature,
215 176 : LoadCommandTypes::LC_DATA_IN_CODE => LoadCommandTypes::DataInCode,
216 32 : LoadCommandTypes::LC_DYLD_CHAINED_FIXUPS => LoadCommandTypes::DyldChainedFixups,
217 16 : LoadCommandTypes::LC_DYLD_ENVIRONMENT => LoadCommandTypes::DyldEnvironment,
218 48 : LoadCommandTypes::LC_DYLD_EXPORTS_TRIE => LoadCommandTypes::DyldExportsTrie,
219 0 : LoadCommandTypes::LC_DYLD_INFO => LoadCommandTypes::DyldInfo,
220 144 : LoadCommandTypes::LC_DYLD_INFO_ONLY => LoadCommandTypes::DyldInfoOnly,
221 16 : LoadCommandTypes::LC_DYLIB_CODE_SIGN_DRS => LoadCommandTypes::DylibCodeSignDrs,
222 224 : LoadCommandTypes::LC_DYSYMTAB => LoadCommandTypes::Dysymtab,
223 16 : LoadCommandTypes::LC_ENCRYPTION_INFO => LoadCommandTypes::EncryptionInfo,
224 0 : LoadCommandTypes::LC_ENCRYPTION_INFO_64 => LoadCommandTypes::EncryptionInfo64,
225 0 : LoadCommandTypes::LC_FILESET_ENTRY => LoadCommandTypes::FilesetEntry,
226 192 : 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 144 : 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 16 : LoadCommandTypes::LinkerOptimizationHint
235 : }
236 0 : LoadCommandTypes::LC_LINKER_OPTION => LoadCommandTypes::LinkerOption,
237 0 : LoadCommandTypes::LC_LOADFVMLIB => LoadCommandTypes::LoadFvmLib,
238 45424 : LoadCommandTypes::LC_LOAD_DYLIB => LoadCommandTypes::LoadDylib,
239 64 : LoadCommandTypes::LC_LOAD_DYLINKER => LoadCommandTypes::LoadDylinker,
240 1456 : LoadCommandTypes::LC_LOAD_UPWARD_DYLIB => LoadCommandTypes::LoadUpwardDylib,
241 480 : LoadCommandTypes::LC_LOAD_WEAK_DYLIB => LoadCommandTypes::LoadWeakDylib,
242 48 : 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 5728 : LoadCommandTypes::LC_REEXPORT_DYLIB => LoadCommandTypes::ReExportDylib,
248 0 : LoadCommandTypes::LC_ROUTINES => LoadCommandTypes::Routines,
249 16 : LoadCommandTypes::LC_ROUTINES_64 => LoadCommandTypes::Routines64,
250 24 : LoadCommandTypes::LC_RPATH => LoadCommandTypes::Rpath,
251 124168 : LoadCommandTypes::LC_SEGMENT => LoadCommandTypes::Segment,
252 79976 : LoadCommandTypes::LC_SEGMENT_64 => LoadCommandTypes::Segment64,
253 64 : LoadCommandTypes::LC_SEGMENT_SPLIT_INFO => LoadCommandTypes::SegmentSplitInfo,
254 192 : LoadCommandTypes::LC_SOURCE_VERSION => LoadCommandTypes::SourceVersion,
255 304 : LoadCommandTypes::LC_SUB_CLIENT => LoadCommandTypes::SubClient,
256 32 : 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 224 : LoadCommandTypes::LC_SYMTAB => LoadCommandTypes::Symtab,
261 0 : LoadCommandTypes::LC_THREAD => LoadCommandTypes::Thread,
262 16 : LoadCommandTypes::LC_TWOLEVEL_HINTS => LoadCommandTypes::TwoLevelHints,
263 16 : LoadCommandTypes::LC_UNIXTHREAD => LoadCommandTypes::Unixthread,
264 208 : LoadCommandTypes::LC_UUID => LoadCommandTypes::Uuid,
265 32 : LoadCommandTypes::LC_VERSION_MIN_IPHONEOS => LoadCommandTypes::VersionMinIphoneOS,
266 96 : 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 32 : LoadCommandTypes::LIEF_UNKNOWN => LoadCommandTypes::LiefUnknown,
270 0 : _ => LoadCommandTypes::Unknown(value),
271 : }
272 259832 : }
273 : }
274 :
275 2400 : #[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 2400 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::MachO_Command>) -> Self {
312 2400 : unsafe {
313 2400 : let cmd_ref = ffi_entry.as_ref().unwrap();
314 2400 :
315 2400 : if ffi::MachO_Dylib::classof(cmd_ref) {
316 728 : let raw = {
317 728 : type From = cxx::UniquePtr<ffi::MachO_Command>;
318 728 : type To = cxx::UniquePtr<ffi::MachO_Dylib>;
319 728 : std::mem::transmute::<From, To>(ffi_entry)
320 728 : };
321 728 : Commands::Dylib(Dylib::from_ffi(raw))
322 1672 : } else if ffi::MachO_Main::classof(cmd_ref) {
323 24 : let raw = {
324 24 : type From = cxx::UniquePtr<ffi::MachO_Command>;
325 24 : type To = cxx::UniquePtr<ffi::MachO_Main>;
326 24 : std::mem::transmute::<From, To>(ffi_entry)
327 24 : };
328 24 : Commands::Main(Main::from_ffi(raw))
329 1648 : } else if ffi::MachO_SegmentCommand::classof(cmd_ref) {
330 424 : let raw = {
331 424 : type From = cxx::UniquePtr<ffi::MachO_Command>;
332 424 : type To = cxx::UniquePtr<ffi::MachO_SegmentCommand>;
333 424 : std::mem::transmute::<From, To>(ffi_entry)
334 424 : };
335 424 : Commands::Segment(Segment::from_ffi(raw))
336 1224 : } else if ffi::MachO_DyldInfo::classof(cmd_ref) {
337 72 : let raw = {
338 72 : type From = cxx::UniquePtr<ffi::MachO_Command>;
339 72 : type To = cxx::UniquePtr<ffi::MachO_DyldInfo>;
340 72 : std::mem::transmute::<From, To>(ffi_entry)
341 72 : };
342 72 : Commands::DyldInfo(DyldInfo::from_ffi(raw))
343 1152 : } else if ffi::MachO_UUIDCommand::classof(cmd_ref) {
344 104 : let raw = {
345 104 : type From = cxx::UniquePtr<ffi::MachO_Command>;
346 104 : type To = cxx::UniquePtr<ffi::MachO_UUIDCommand>;
347 104 : std::mem::transmute::<From, To>(ffi_entry)
348 104 : };
349 104 : Commands::UUID(UUID::from_ffi(raw))
350 1048 : } else if ffi::MachO_Dylinker::classof(cmd_ref) {
351 32 : let raw = {
352 32 : type From = cxx::UniquePtr<ffi::MachO_Command>;
353 32 : type To = cxx::UniquePtr<ffi::MachO_Dylinker>;
354 32 : std::mem::transmute::<From, To>(ffi_entry)
355 32 : };
356 32 : Commands::Dylinker(Dylinker::from_ffi(raw))
357 1016 : } else if ffi::MachO_FunctionStarts::classof(cmd_ref) {
358 96 : let raw = {
359 96 : type From = cxx::UniquePtr<ffi::MachO_Command>;
360 96 : type To = cxx::UniquePtr<ffi::MachO_FunctionStarts>;
361 96 : std::mem::transmute::<From, To>(ffi_entry)
362 96 : };
363 96 : Commands::FunctionStarts(FunctionStarts::from_ffi(raw))
364 920 : } else if ffi::MachO_SourceVersion::classof(cmd_ref) {
365 96 : let raw = {
366 96 : type From = cxx::UniquePtr<ffi::MachO_Command>;
367 96 : type To = cxx::UniquePtr<ffi::MachO_SourceVersion>;
368 96 : std::mem::transmute::<From, To>(ffi_entry)
369 96 : };
370 96 : Commands::SourceVersion(SourceVersion::from_ffi(raw))
371 824 : } else if ffi::MachO_ThreadCommand::classof(cmd_ref) {
372 8 : let raw = {
373 8 : type From = cxx::UniquePtr<ffi::MachO_Command>;
374 8 : type To = cxx::UniquePtr<ffi::MachO_ThreadCommand>;
375 8 : std::mem::transmute::<From, To>(ffi_entry)
376 8 : };
377 8 : Commands::ThreadCommand(ThreadCommand::from_ffi(raw))
378 816 : } else if ffi::MachO_RPathCommand::classof(cmd_ref) {
379 16 : let raw = {
380 16 : type From = cxx::UniquePtr<ffi::MachO_Command>;
381 16 : type To = cxx::UniquePtr<ffi::MachO_RPathCommand>;
382 16 : std::mem::transmute::<From, To>(ffi_entry)
383 16 : };
384 16 : Commands::RPath(RPath::from_ffi(raw))
385 800 : } else if ffi::MachO_Routine::classof(cmd_ref) {
386 8 : let raw = {
387 8 : type From = cxx::UniquePtr<ffi::MachO_Command>;
388 8 : type To = cxx::UniquePtr<ffi::MachO_Routine>;
389 8 : std::mem::transmute::<From, To>(ffi_entry)
390 8 : };
391 8 : Commands::Routine(Routine::from_ffi(raw))
392 792 : } else if ffi::MachO_SymbolCommand::classof(cmd_ref) {
393 112 : let raw = {
394 112 : type From = cxx::UniquePtr<ffi::MachO_Command>;
395 112 : type To = cxx::UniquePtr<ffi::MachO_SymbolCommand>;
396 112 : std::mem::transmute::<From, To>(ffi_entry)
397 112 : };
398 112 : Commands::SymbolCommand(SymbolCommand::from_ffi(raw))
399 680 : } else if ffi::MachO_DynamicSymbolCommand::classof(cmd_ref) {
400 112 : let raw = {
401 112 : type From = cxx::UniquePtr<ffi::MachO_Command>;
402 112 : type To = cxx::UniquePtr<ffi::MachO_DynamicSymbolCommand>;
403 112 : std::mem::transmute::<From, To>(ffi_entry)
404 112 : };
405 112 : Commands::DynamicSymbolCommand(DynamicSymbolCommand::from_ffi(raw))
406 568 : } else if ffi::MachO_CodeSignature::classof(cmd_ref) {
407 64 : let raw = {
408 64 : type From = cxx::UniquePtr<ffi::MachO_Command>;
409 64 : type To = cxx::UniquePtr<ffi::MachO_CodeSignature>;
410 64 : std::mem::transmute::<From, To>(ffi_entry)
411 64 : };
412 64 : Commands::CodeSignature(CodeSignature::from_ffi(raw))
413 504 : } else if ffi::MachO_CodeSignatureDir::classof(cmd_ref) {
414 8 : let raw = {
415 8 : type From = cxx::UniquePtr<ffi::MachO_Command>;
416 8 : type To = cxx::UniquePtr<ffi::MachO_CodeSignatureDir>;
417 8 : std::mem::transmute::<From, To>(ffi_entry)
418 8 : };
419 8 : Commands::CodeSignatureDir(CodeSignatureDir::from_ffi(raw))
420 496 : } else if ffi::MachO_DataInCode::classof(cmd_ref) {
421 88 : let raw = {
422 88 : type From = cxx::UniquePtr<ffi::MachO_Command>;
423 88 : type To = cxx::UniquePtr<ffi::MachO_DataInCode>;
424 88 : std::mem::transmute::<From, To>(ffi_entry)
425 88 : };
426 88 : Commands::DataInCode(DataInCode::from_ffi(raw))
427 408 : } else if ffi::MachO_SegmentSplitInfo::classof(cmd_ref) {
428 32 : let raw = {
429 32 : type From = cxx::UniquePtr<ffi::MachO_Command>;
430 32 : type To = cxx::UniquePtr<ffi::MachO_SegmentSplitInfo>;
431 32 : std::mem::transmute::<From, To>(ffi_entry)
432 32 : };
433 32 : Commands::SegmentSplitInfo(SegmentSplitInfo::from_ffi(raw))
434 376 : } else if ffi::MachO_EncryptionInfo::classof(cmd_ref) {
435 8 : let raw = {
436 8 : type From = cxx::UniquePtr<ffi::MachO_Command>;
437 8 : type To = cxx::UniquePtr<ffi::MachO_EncryptionInfo>;
438 8 : std::mem::transmute::<From, To>(ffi_entry)
439 8 : };
440 8 : Commands::EncryptionInfo(EncryptionInfo::from_ffi(raw))
441 368 : } else if ffi::MachO_SubFramework::classof(cmd_ref) {
442 16 : let raw = {
443 16 : type From = cxx::UniquePtr<ffi::MachO_Command>;
444 16 : type To = cxx::UniquePtr<ffi::MachO_SubFramework>;
445 16 : std::mem::transmute::<From, To>(ffi_entry)
446 16 : };
447 16 : Commands::SubFramework(SubFramework::from_ffi(raw))
448 352 : } else if ffi::MachO_SubClient::classof(cmd_ref) {
449 152 : let raw = {
450 152 : type From = cxx::UniquePtr<ffi::MachO_Command>;
451 152 : type To = cxx::UniquePtr<ffi::MachO_SubClient>;
452 152 : std::mem::transmute::<From, To>(ffi_entry)
453 152 : };
454 152 : Commands::SubClient(SubClient::from_ffi(raw))
455 200 : } else if ffi::MachO_DyldEnvironment::classof(cmd_ref) {
456 8 : let raw = {
457 8 : type From = cxx::UniquePtr<ffi::MachO_Command>;
458 8 : type To = cxx::UniquePtr<ffi::MachO_DyldEnvironment>;
459 8 : std::mem::transmute::<From, To>(ffi_entry)
460 8 : };
461 8 : Commands::DyldEnvironment(DyldEnvironment::from_ffi(raw))
462 192 : } else if ffi::MachO_BuildVersion::classof(cmd_ref) {
463 40 : let raw = {
464 40 : type From = cxx::UniquePtr<ffi::MachO_Command>;
465 40 : type To = cxx::UniquePtr<ffi::MachO_BuildVersion>;
466 40 : std::mem::transmute::<From, To>(ffi_entry)
467 40 : };
468 40 : Commands::BuildVersion(BuildVersion::from_ffi(raw))
469 152 : } else if ffi::MachO_DyldChainedFixups::classof(cmd_ref) {
470 16 : let raw = {
471 16 : type From = cxx::UniquePtr<ffi::MachO_Command>;
472 16 : type To = cxx::UniquePtr<ffi::MachO_DyldChainedFixups>;
473 16 : std::mem::transmute::<From, To>(ffi_entry)
474 16 : };
475 16 : Commands::DyldChainedFixups(DyldChainedFixups::from_ffi(raw))
476 136 : } else if ffi::MachO_DyldExportsTrie::classof(cmd_ref) {
477 24 : let raw = {
478 24 : type From = cxx::UniquePtr<ffi::MachO_Command>;
479 24 : type To = cxx::UniquePtr<ffi::MachO_DyldExportsTrie>;
480 24 : std::mem::transmute::<From, To>(ffi_entry)
481 24 : };
482 24 : Commands::DyldExportsTrie(DyldExportsTrie::from_ffi(raw))
483 112 : } else if ffi::MachO_TwoLevelHints::classof(cmd_ref) {
484 8 : let raw = {
485 8 : type From = cxx::UniquePtr<ffi::MachO_Command>;
486 8 : type To = cxx::UniquePtr<ffi::MachO_TwoLevelHints>;
487 8 : std::mem::transmute::<From, To>(ffi_entry)
488 8 : };
489 8 : Commands::TwoLevelHints(TwoLevelHints::from_ffi(raw))
490 104 : } else if ffi::MachO_LinkerOptHint::classof(cmd_ref) {
491 8 : let raw = {
492 8 : type From = cxx::UniquePtr<ffi::MachO_Command>;
493 8 : type To = cxx::UniquePtr<ffi::MachO_LinkerOptHint>;
494 8 : std::mem::transmute::<From, To>(ffi_entry)
495 8 : };
496 8 : Commands::LinkerOptHint(LinkerOptHint::from_ffi(raw))
497 96 : } else if ffi::MachO_VersionMin::classof(cmd_ref) {
498 64 : let raw = {
499 64 : type From = cxx::UniquePtr<ffi::MachO_Command>;
500 64 : type To = cxx::UniquePtr<ffi::MachO_VersionMin>;
501 64 : std::mem::transmute::<From, To>(ffi_entry)
502 64 : };
503 64 : Commands::VersionMin(VersionMin::from_ffi(raw))
504 32 : } else if ffi::MachO_UnknownCommand::classof(cmd_ref) {
505 32 : let raw = {
506 32 : type From = cxx::UniquePtr<ffi::MachO_Command>;
507 32 : type To = cxx::UniquePtr<ffi::MachO_UnknownCommand>;
508 32 : std::mem::transmute::<From, To>(ffi_entry)
509 32 : };
510 32 : Commands::Unknown(Unknown::from_ffi(raw))
511 : } else {
512 0 : Commands::Generic(Generic::from_ffi(ffi_entry))
513 : }
514 : }
515 2400 : }
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 259832 : fn size(&self) -> u32 {
545 259832 : self.get_base().size()
546 259832 : }
547 :
548 : /// Offset of the command within the *Load Command Table*
549 259832 : fn offset(&self) -> u64 {
550 259832 : self.get_base().command_offset()
551 259832 : }
552 :
553 : /// The command's type
554 259832 : fn command_type(&self) -> LoadCommandTypes {
555 259832 : LoadCommandTypes::from_value(self.get_base().cmd_type())
556 259832 : }
557 :
558 : /// The raw command as a slice of bytes
559 259832 : fn data(&self) -> &[u8] {
560 259832 : to_slice!(self.get_base().data());
561 259832 : }
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 259832 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
666 259832 : f.debug_struct("Command")
667 259832 : .field("offset", &self.offset())
668 259832 : .field("size", &self.size())
669 259832 : .field("type", &self.command_type())
670 259832 : .field("data_len", &self.data().len())
671 259832 : .finish()
672 259832 : }
673 : }
674 :
675 2400 : declare_iterator!(
676 2400 : CommandsIter,
677 2400 : Commands<'a>,
678 2400 : ffi::MachO_Command,
679 2400 : ffi::MachO_Binary,
680 2400 : ffi::MachO_Binary_it_commands
681 2400 : );
|