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