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