schnauzer/types/load_command/
mod.rs1use crate::X64Context;
2
3use super::fmt_ext::*;
4use super::Section;
5use super::RcReader;
6use super::Result;
7use scroll::{Endian, IOread};
8
9use std::fmt::Debug;
10use std::io::{Seek, SeekFrom};
11
12use super::auto_enum_fields::*;
13use schnauzer_derive::AutoEnumFields;
14
15pub mod constants;
16pub use constants::*;
17
18pub mod common;
19pub use common::*;
20
21pub mod segment_command;
22pub use segment_command::*;
23
24pub mod symtab_command;
25pub use symtab_command::*;
26
27pub mod dylib_command;
28pub use dylib_command::*;
29
30pub mod sub_framework_command;
31pub use sub_framework_command::*;
32
33pub mod sub_client_command;
34pub use sub_client_command::*;
35
36pub mod sub_umbrella_command;
37pub use sub_umbrella_command::*;
38
39pub mod sub_library_command;
40pub use sub_library_command::*;
41
42pub mod prebound_dylib_command;
43pub use prebound_dylib_command::*;
44
45pub mod dylinker_command;
46pub use dylinker_command::*;
47
48pub mod thread_command;
49pub use thread_command::*;
50
51pub mod routines_command;
52pub use routines_command::*;
53
54pub mod dysymtab_command;
55pub use dysymtab_command::*;
56
57pub mod twolevel_hints_command;
58pub use twolevel_hints_command::*;
59
60pub mod prebind_cksum_command;
61pub use prebind_cksum_command::*;
62
63pub mod uuid_command;
64pub use uuid_command::*;
65
66pub mod rpath_command;
67pub use rpath_command::*;
68
69pub mod linkedit_data_command;
70pub use linkedit_data_command::*;
71
72pub mod encryption_info_command;
73pub use encryption_info_command::*;
74
75pub mod version_min_command;
76pub use version_min_command::*;
77
78pub mod build_version_command;
79pub use build_version_command::*;
80
81pub mod dyld_info_command;
82pub use dyld_info_command::*;
83
84pub mod linker_option_command;
85pub use linker_option_command::*;
86
87pub mod note_command;
88pub use note_command::*;
89
90pub mod source_version_command;
91pub use source_version_command::*;
92
93pub mod entry_point_command;
94pub use entry_point_command::*;
95
96pub mod fvmfile_command;
97pub use fvmfile_command::*;
98
99pub mod symseg_command;
100pub use symseg_command::*;
101
102#[derive(AutoEnumFields)]
104pub struct LoadCommand {
105 pub cmd: u32,
106 pub cmdsize: u32,
107
108 pub variant: LcVariant,
109}
110
111impl Debug for LoadCommand {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 f.debug_struct("LoadCommand")
114 .field("cmd", &load_command_to_string(self.cmd))
115 .field("cmdsize", &self.cmdsize)
116 .field("variant", &self.variant)
117 .finish()
118 }
119}
120
121impl LoadCommand {
122 pub(super) fn parse(
123 reader: RcReader,
124 base_offset: usize,
125 endian: scroll::Endian,
126 is_64: bool,
127 object_file_offset: u64,
128 ) -> Result<LoadCommand> {
129 let mut reader_mut = reader.borrow_mut();
130 reader_mut.seek(SeekFrom::Start(base_offset as u64))?;
131
132 let cmd: u32 = reader_mut.ioread_with(endian)?;
133 let cmdsize: u32 = reader_mut.ioread_with(endian)?;
134
135 std::mem::drop(reader_mut);
136
137 let variant = LcVariant::parse(
138 reader.clone(),
139 cmd,
140 base_offset,
141 endian,
142 is_64,
143 object_file_offset,
144 )?;
145
146 Ok(LoadCommand {
147 cmd,
148 cmdsize,
149 variant,
150 })
151 }
152}
153
154#[derive(Debug, AutoEnumFields)]
157pub enum LcVariant {
158 Segment32(LcSegment),
160 Segment64(LcSegment),
162 IdDylib(LcDylib),
164 LoadDylib(LcDylib),
166 LoadWeakDylib(LcDylib),
168 ReexportDylib(LcDylib),
170 Subframework(LcSubframework),
172 Subclient(LcSubclient),
174 Subumbrella(LcSubumbrella),
176 Sublibrary(LcSublibrary),
178 PreboundDylib(LcPreboundDylib),
180 IdDylinker(LcDylinker),
182 LoadDylinker(LcDylinker),
184 DyldEnvironment(LcDylinker),
186 Thread(LcThread),
188 UnixThread(LcThread),
190 Routines(LcRoutines),
192 Routines64(LcRoutines64),
194 Symtab(LcSymtab),
196 Dysimtab(LcDysimtab),
198 TwoLevelHints(LcTwoLevelHints),
200 PrebindChekSum(LcPrebindChekSum),
202 Uuid(LcUuid),
204 Rpath(LcRpath),
206 CodeSignature(LcLinkEditData),
208 SegmentSplitInfo(LcLinkEditData),
210 FunctionStarts(LcLinkEditData),
212 DataInCode(LcLinkEditData),
214 DylibCodeSignature(LcLinkEditData),
216 LinkerOptimizationHint(LcLinkEditData),
218 EncryptionInfo(LcEncryptionInfo),
220 EncryptionInfo64(LcEncryptionInfo64),
222 VersionMinMacOsx(LcVersionMin),
224 VersionMinIphoneOs(LcVersionMin),
226 VersionMinWatchOs(LcVersionMin),
228 VersionMinTvOs(LcVersionMin),
230 BuildVersion(LcBuildVersion),
232 DyldInfo(LcDyldInfo),
234 DyldInfoOnly(LcDyldInfo),
236 LinkerOption(LcLinkerOption),
238 SymSeg(LcSymSeg),
240 FvmFile(LcFvmFile),
242 EntryPoint(LcEntryPoint),
244 SourceVersion(LcSourceVersion),
246 Note(LcNote),
248 Other,
250}
251
252impl LcVariant {
253 fn parse(
254 reader: RcReader,
255 cmd: u32,
256 command_offset: usize,
257 endian: Endian,
258 is_64: bool,
259 object_file_offset: u64,
260 ) -> Result<Self> {
261 let reader_clone = reader.clone();
262 let mut reader_mut = reader.borrow_mut();
263 let base_offset = reader_mut.stream_position()? as usize;
264 match cmd {
266 LC_SEGMENT => {
267 let c = LcSegment::parse(reader_clone, base_offset, object_file_offset, X64Context::Off(endian))?;
268 Ok(Self::Segment32(c))
269 }
270 LC_SEGMENT_64 => {
271 std::mem::drop(reader_mut);
272 let c = LcSegment::parse(reader_clone, base_offset, object_file_offset, X64Context::On(endian))?;
273 Ok(Self::Segment64(c))
274 }
275 LC_ID_DYLIB => {
276 std::mem::drop(reader_mut);
277 let c = LcDylib::parse(reader_clone, command_offset, base_offset, endian)?;
278 Ok(Self::IdDylib(c))
279 }
280 LC_LOAD_DYLIB => {
281 std::mem::drop(reader_mut);
282 let c = LcDylib::parse(reader_clone, command_offset, base_offset, endian)?;
283 Ok(Self::LoadDylib(c))
284 }
285 LC_LOAD_WEAK_DYLIB => {
286 std::mem::drop(reader_mut);
287 let c = LcDylib::parse(reader_clone, command_offset, base_offset, endian)?;
288 Ok(Self::LoadWeakDylib(c))
289 }
290 LC_REEXPORT_DYLIB => {
291 std::mem::drop(reader_mut);
292 let c = LcDylib::parse(reader_clone, command_offset, base_offset, endian)?;
293 Ok(Self::ReexportDylib(c))
294 }
295 LC_SUB_FRAMEWORK => {
296 std::mem::drop(reader_mut);
297 let c = LcSubframework::parse(reader_clone, command_offset, base_offset, endian)?;
298 Ok(Self::Subframework(c))
299 }
300 LC_SUB_CLIENT => {
301 std::mem::drop(reader_mut);
302 let c = LcSubclient::parse(reader_clone, command_offset, base_offset, endian)?;
303 Ok(Self::Subclient(c))
304 }
305 LC_SUB_UMBRELLA => {
306 std::mem::drop(reader_mut);
307 let c = LcSubumbrella::parse(reader_clone, command_offset, base_offset, endian)?;
308 Ok(Self::Subumbrella(c))
309 }
310 LC_SUB_LIBRARY => {
311 std::mem::drop(reader_mut);
312 let c = LcSublibrary::parse(reader_clone, command_offset, base_offset, endian)?;
313 Ok(Self::Sublibrary(c))
314 }
315 LC_PREBOUND_DYLIB => {
316 std::mem::drop(reader_mut);
317 let c = LcPreboundDylib::parse(reader_clone, command_offset, base_offset, endian)?;
318 Ok(Self::PreboundDylib(c))
319 }
320 LC_ID_DYLINKER => {
321 std::mem::drop(reader_mut);
322 let c = LcDylinker::parse(reader_clone, command_offset, base_offset, endian)?;
323 Ok(Self::IdDylinker(c))
324 }
325 LC_LOAD_DYLINKER => {
326 std::mem::drop(reader_mut);
327 let c = LcDylinker::parse(reader_clone, command_offset, base_offset, endian)?;
328 Ok(Self::LoadDylinker(c))
329 }
330 LC_DYLD_ENVIRONMENT => {
331 std::mem::drop(reader_mut);
332 let c = LcDylinker::parse(reader_clone, command_offset, base_offset, endian)?;
333 Ok(Self::DyldEnvironment(c))
334 }
335 LC_THREAD => {
336 let c = reader_mut.ioread_with(endian)?;
337 Ok(Self::Thread(c))
338 }
339 LC_UNIXTHREAD => {
340 let c = reader_mut.ioread_with(endian)?;
341 Ok(Self::Thread(c))
342 }
343 LC_ROUTINES => {
344 let c = reader_mut.ioread_with(endian)?;
345 Ok(Self::Routines(c))
346 }
347 LC_ROUTINES_64 => {
348 let c = reader_mut.ioread_with(endian)?;
349 Ok(Self::Routines64(c))
350 }
351 LC_SYMTAB => {
352 std::mem::drop(reader_mut);
353 let c =
354 LcSymtab::parse(reader_clone, is_64, base_offset, endian, object_file_offset)?;
355 Ok(Self::Symtab(c))
356 }
357 LC_DYSYMTAB => {
358 let c = reader_mut.ioread_with(endian)?;
359 Ok(Self::Dysimtab(c))
360 }
361 LC_TWOLEVEL_HINTS => {
362 let c = reader_mut.ioread_with(endian)?;
363 Ok(Self::TwoLevelHints(c))
364 }
365 LC_PREBIND_CKSUM => {
366 let c = reader_mut.ioread_with(endian)?;
367 Ok(Self::PrebindChekSum(c))
368 }
369 LC_UUID => {
370 let c = reader_mut.ioread_with(endian)?;
371 Ok(Self::Uuid(c))
372 }
373 LC_RPATH => {
374 std::mem::drop(reader_mut);
375 let c = LcRpath::parse(reader_clone, command_offset, base_offset, endian)?;
376 Ok(Self::Rpath(c))
377 }
378 LC_CODE_SIGNATURE => {
379 let c = reader_mut.ioread_with(endian)?;
380 Ok(Self::CodeSignature(c))
381 }
382 LC_SEGMENT_SPLIT_INFO => {
383 let c = reader_mut.ioread_with(endian)?;
384 Ok(Self::SegmentSplitInfo(c))
385 }
386 LC_FUNCTION_STARTS => {
387 let c = reader_mut.ioread_with(endian)?;
388 Ok(Self::FunctionStarts(c))
389 }
390 LC_DATA_IN_CODE => {
391 let c = reader_mut.ioread_with(endian)?;
392 Ok(Self::DataInCode(c))
393 }
394 LC_DYLIB_CODE_SIGN_DRS => {
395 let c = reader_mut.ioread_with(endian)?;
396 Ok(Self::DylibCodeSignature(c))
397 }
398 LC_LINKER_OPTIMIZATION_HINT => {
399 let c = reader_mut.ioread_with(endian)?;
400 Ok(Self::LinkerOptimizationHint(c))
401 }
402 LC_ENCRYPTION_INFO => {
403 let c = reader_mut.ioread_with(endian)?;
404 Ok(Self::EncryptionInfo(c))
405 }
406 LC_ENCRYPTION_INFO_64 => {
407 let c = reader_mut.ioread_with(endian)?;
408 Ok(Self::EncryptionInfo64(c))
409 }
410 LC_VERSION_MIN_MACOSX => {
411 let c = reader_mut.ioread_with(endian)?;
412 Ok(Self::VersionMinMacOsx(c))
413 }
414 LC_VERSION_MIN_IPHONEOS => {
415 let c = reader_mut.ioread_with(endian)?;
416 Ok(Self::VersionMinIphoneOs(c))
417 }
418 LC_VERSION_MIN_WATCHOS => {
419 let c = reader_mut.ioread_with(endian)?;
420 Ok(Self::VersionMinWatchOs(c))
421 }
422 LC_VERSION_MIN_TVOS => {
423 let c = reader_mut.ioread_with(endian)?;
424 Ok(Self::VersionMinTvOs(c))
425 }
426 LC_BUILD_VERSION => {
427 let c = reader_mut.ioread_with(endian)?;
428 Ok(Self::BuildVersion(c))
429 }
430 LC_DYLD_INFO => {
431 let c = reader_mut.ioread_with(endian)?;
432 Ok(Self::DyldInfo(c))
433 }
434 LC_DYLD_INFO_ONLY => {
435 let c = reader_mut.ioread_with(endian)?;
436 Ok(Self::DyldInfoOnly(c))
437 }
438 LC_LINKER_OPTION => {
439 let c = reader_mut.ioread_with(endian)?;
440 Ok(Self::LinkerOption(c))
441 }
442 LC_SYMSEG => {
443 let c = reader_mut.ioread_with(endian)?;
444 Ok(Self::SymSeg(c))
445 }
446 LC_FVMFILE => {
447 std::mem::drop(reader_mut);
448 let c = LcFvmFile::parse(reader_clone, command_offset, base_offset, endian)?;
449 Ok(Self::FvmFile(c))
450 }
451 LC_MAIN => {
452 let c = reader_mut.ioread_with(endian)?;
453 Ok(Self::EntryPoint(c))
454 }
455 LC_SOURCE_VERSION => {
456 let c = reader_mut.ioread_with(endian)?;
457 Ok(Self::SourceVersion(c))
458 }
459 LC_NOTE => {
460 let c = reader_mut.ioread_with(endian)?;
461 Ok(Self::Note(c))
462 }
463 _ => Ok(Self::Other),
464 }
465 }
466}