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