1pub mod build_version;
2pub mod codesign;
3pub mod dyld_chained_fixup;
4pub mod dyld_exports_trie;
5pub mod dyld_info;
6pub mod dylib;
7pub mod dylib_use;
8pub mod dylinker;
9pub mod dysymtab;
10pub mod encryption_info;
11pub mod entry_point;
12pub mod fileset_entry;
13pub mod function_starts;
14pub mod linkedit_data;
15pub mod linker_option;
16pub mod note;
17pub mod prebind_cksum;
18pub mod prebound_dylib;
19pub mod routines;
20pub mod rpath;
21pub mod segment;
22pub mod source_version;
23pub mod sub_client;
24pub mod sub_framework;
25pub mod sub_library;
26pub mod sub_umbrella;
27pub mod symseg;
28pub mod symtab;
29pub mod thread;
30pub mod two_level_hints;
31pub mod uuid;
32pub mod version_min;
33
34use std::io::{Read, Seek, SeekFrom};
35
36use crate::header::MachHeader;
37use crate::macho::{MachOErr, MachOResult};
38use nom::bytes::complete::take;
39use nom::number::complete::le_u32;
40use nom::IResult;
41use nom_derive::{Nom, Parse};
42
43pub use build_version::BuildVersionCommand;
45pub use codesign::CodeSignCommand;
46pub use dyld_chained_fixup::DyldChainedFixupCommand;
47pub use dyld_exports_trie::DyldExportsTrie;
48pub use dyld_info::DyldInfoCommand;
49pub use dylib::DylibCommand;
50pub use dylinker::DylinkerCommand;
51pub use dysymtab::DysymtabCommand;
52pub use encryption_info::{EncryptionInfoCommand, EncryptionInfoCommand64};
53pub use entry_point::EntryPointCommand;
54pub use fileset_entry::FilesetEntryCommand;
55pub use function_starts::FunctionStartsCommand;
56pub use linkedit_data::LinkeditDataCommand;
57pub use linker_option::LinkerOptionCommand;
58pub use note::NoteCommand;
59pub use prebind_cksum::PrebindCksumCommand;
60pub use prebound_dylib::PreboundDylibCommand;
61pub use routines::RoutinesCommand64;
62pub use rpath::RpathCommand;
63pub use segment::{SegmentCommand32, SegmentCommand64};
64pub use source_version::SourceVersionCommand;
65pub use sub_client::SubClientCommand;
66pub use sub_framework::SubFrameworkCommand;
67pub use sub_library::SubLibraryCommand;
68pub use sub_umbrella::SubUmbrellaCommand;
69pub use symseg::SymsegCommand;
70pub use symtab::SymtabCommand;
71pub use thread::ThreadCommand;
72pub use two_level_hints::TwoLevelHintsCommand;
73pub use uuid::UuidCommand;
74pub use version_min::VersionMinCommand;
75
76
77pub trait LoadCommandParser {
78 fn parse(ldcmd: &[u8]) -> MachOResult<Self>
79 where
80 Self: Sized;
81 fn serialize(&self) -> Vec<u8>;
82}
83
84fn pad_to_size(buf: &mut Vec<u8>, size: usize) {
85 let pad_size = size.checked_sub(buf.len()).expect(&format!(
86 "Serialized buf size exceeds cmdsize. Expected: {}, Actual: {}",
87 size,
88 buf.len()
89 ));
90 buf.extend(vec![0u8; pad_size]);
91}
92
93pub trait LoadCommandResolver<T, R> {
94 fn resolve(&self, buf: &mut T) -> MachOResult<R>;
95}
96
97#[derive(Debug, Clone, Copy)]
98pub struct LoadCommandBase {
99 pub cmd: LCLoadCommand,
100 pub cmdsize: u32,
101}
102
103impl LoadCommandBase {
104 pub fn parse<'a>(bytes: &[u8]) -> IResult<&[u8], LoadCommandBase> {
105 let (bytes, cmd) = LCLoadCommand::parse_le(bytes)?;
106 let (bytes, cmdsize) = le_u32(bytes)?;
107
108 Ok((bytes, LoadCommandBase { cmd, cmdsize }))
109 }
110
111 pub fn skip(bytes: &[u8]) -> IResult<&[u8], ()> {
112 let (remaining, _) = take(8usize)(bytes)?;
113 Ok((remaining, ()))
114 }
115}
116
117#[repr(u32)]
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Nom)]
119pub enum LCLoadCommand {
120 None = 0x0,
122 LcSegment = 0x1,
123 LcSymtab = 0x2,
124 LcSymseg = 0x3,
125 LcThread = 0x4,
126 LcUnixThread = 0x5,
127 LcDysymtab = 0xb,
128 LcLoadDylib = 0xc,
129 LcIdDylib = 0xd,
130 LcLoadDylinker = 0xe,
131 LcIdDylinker = 0xf,
132 LcPreboundDylib = 0x10,
133 LcRoutines = 0x11,
134 LcSubFramework = 0x12,
135 LcSubUmbrella = 0x13,
136 LcSubClient = 0x14,
137 LcSubLibrary = 0x15,
138 LcTwolevelHints = 0x16,
139 LcPrebindCksum = 0x17,
140 LcLoadWeakDylib = 0x18 | Self::LC_REQ_DYLD,
141 LcSegment64 = 0x19,
142 LcRoutines64 = 0x1a,
143 LcUuid = 0x1b,
144 LcRpath = 0x1c | Self::LC_REQ_DYLD,
145 LcCodeSignature = 0x1d,
146 LcSegmentSplitInfo = 0x1e,
147 LcReexportDylib = 0x1f | Self::LC_REQ_DYLD,
148 LcLazyLoadDylib = 0x20,
149 LcEncryptionInfo = 0x21,
150 LcDyldInfo = 0x22,
151 LcDyldInfoOnly = 0x22 | Self::LC_REQ_DYLD,
152 LcLoadUpwardDylib = 0x23 | Self::LC_REQ_DYLD,
153 LcVersionMinMacosx = 0x24,
154 LcVersionMinIphoneos = 0x25,
155 LcFunctionStarts = 0x26,
156 LcDyldEnvironment = 0x27,
157 LcMain = 0x28 | Self::LC_REQ_DYLD,
158 LcDataInCode = 0x29,
159 LcSourceVersion = 0x2A,
160 LcDylibCodeSignDrs = 0x2B,
161 LcEncryptionInfo64 = 0x2C,
162 LcLinkerOption = 0x2D,
163 LcLinkerOptimizationHint = 0x2E,
164 LcVersionMinTvos = 0x2F,
165 LcVersionMinWatchos = 0x30,
166 LcNote = 0x31,
167 LcBuildVersion = 0x32,
168 LcDyldExportsTrie = 0x33 | Self::LC_REQ_DYLD,
169 LcDyldChainedFixups = 0x34 | Self::LC_REQ_DYLD,
170 LcFilesetEntry = 0x35 | Self::LC_REQ_DYLD,
171 LcAtomInfo = 0x36,
172}
173
174impl LCLoadCommand {
175 pub const LC_REQ_DYLD: u32 = 0x80000000;
176
177 pub fn serialize(&self) -> Vec<u8> {
178 (*self as u32).to_le_bytes().to_vec()
179 }
180}
181
182#[derive(Debug, PartialEq, Eq)]
183pub enum LoadCommand {
184 None,
185 Segment32(SegmentCommand32),
186 Symtab(SymtabCommand),
187 Symseg(SymsegCommand),
188 Thread(ThreadCommand),
189 UnixThread(ThreadCommand),
190 Dysymtab(DysymtabCommand),
191 LoadDylib(DylibCommand),
192 DylibId(DylibCommand),
193 LoadDylinker(DylinkerCommand),
194 IdDylinker(DylinkerCommand),
195 PreboundDylib(PreboundDylibCommand),
196 Routines(RoutinesCommand64),
197 SubFramework(SubFrameworkCommand),
198 SubUmbrella(SubUmbrellaCommand),
199 SubClient(SubClientCommand),
200 SubLibrary(SubLibraryCommand),
201 TwoLevelHints(TwoLevelHintsCommand),
202 PrebindCksum(PrebindCksumCommand),
203 LoadWeakDylib(DylibCommand),
204 Segment64(SegmentCommand64),
205 Routines64(RoutinesCommand64),
206 UUID(UuidCommand),
207 Rpath(RpathCommand),
208 CodeSignature(CodeSignCommand),
209 SegmentSplitInfo(LinkeditDataCommand),
210 ReexportDylib(DylibCommand),
211 LazyLoadDylib(DylibCommand),
212 EncryptionInfo(EncryptionInfoCommand),
213 DyldInfo(DyldInfoCommand),
214 DyldInfoOnly(DyldInfoCommand),
215 LoadUpwardDylib(DylibCommand),
216 VersionMinMacosx(VersionMinCommand),
217 VersionMinIphoneos(VersionMinCommand),
218 FunctionStarts(FunctionStartsCommand),
219 DyldEnvironment(DylinkerCommand),
220 Main(EntryPointCommand),
221 DataInCode(LinkeditDataCommand),
222 SourceVersion(SourceVersionCommand),
223 DylibCodeSignDrs(LinkeditDataCommand),
224 EncryptionInfo64(EncryptionInfoCommand64),
225 LinkerOption(LinkerOptionCommand),
226 LinkerOptimizationHint(LinkeditDataCommand),
227 VersionMinTvos(VersionMinCommand),
228 VersionMinWatchos(VersionMinCommand),
229 Note(NoteCommand),
230 BuildVersion(BuildVersionCommand),
231 DyldExportsTrie(DyldExportsTrie),
232 DyldChainedFixups(DyldChainedFixupCommand),
233 FilesetEntry(FilesetEntryCommand),
234 AtomInfo(LinkeditDataCommand),
235}
236
237pub fn iterate_load_commands<F, T>(
238 buf: &mut T,
239 header: MachHeader,
240 mut f: F,
241) -> MachOResult<Vec<LoadCommand>>
242where
243 F: FnMut(
244 LoadCommandBase,
245 &[u8],
246 ) -> MachOResult<LoadCommand>,
247 T: Seek + Read,
248{
249 let mut ldcmds = vec![0u8; header.sizeofcmds() as usize];
250 buf.seek(SeekFrom::Start(header.size() as u64))
251 .map_err(|e| MachOErr::IOError(e))?;
252 buf.read_exact(&mut ldcmds).map_err(|e| MachOErr::IOError(e))?;
253
254 let mut results = Vec::new();
255 let mut remaining_ldcmds = &ldcmds[..];
256
257 for i in 0..header.ncmds() {
258 let (_, base) = LoadCommandBase::parse(remaining_ldcmds).map_err(|_| MachOErr::ParsingError(format!("Unable to parse load command base for index {}", i)))?;
259
260 let cmdsize = base.cmdsize as usize;
261 if cmdsize > remaining_ldcmds.len() {
262 return Err(MachOErr::InvalidValue(format!("Load command size exceeds available data at index {}", i)));
263 }
264
265 let cmd_bytes = &remaining_ldcmds[..cmdsize];
266 let result = f(base, cmd_bytes)?;
267 results.push(result);
268
269 remaining_ldcmds = &remaining_ldcmds[cmdsize..];
270 }
271
272 Ok(results)
273}
274
275impl LoadCommand {
276 pub fn parse_all<T>(buf: &mut T, header: MachHeader) -> MachOResult<Vec<Self>>
277 where
278 T: Seek + Read,
279 {
280 let cmds =
281 iterate_load_commands(
282 buf,
283 header,
284 |base, ldcmd| LoadCommand::parse(base, ldcmd)
285 )?;
286
287 Ok(cmds)
288 }
289
290 pub fn parse(
291 base: LoadCommandBase,
292 ldcmd: &[u8],
293 ) -> MachOResult<Self>
294 {
295 match base.cmd {
296 LCLoadCommand::LcSegment => {
297 Ok(LoadCommand::Segment32(SegmentCommand32::parse(ldcmd)?))
298 }
299 LCLoadCommand::LcSegment64 => {
300 Ok(LoadCommand::Segment64(SegmentCommand64::parse(ldcmd)?))
301 }
302 LCLoadCommand::LcLoadDylib
303 | LCLoadCommand::LcIdDylib
304 | LCLoadCommand::LcLoadWeakDylib
305 | LCLoadCommand::LcReexportDylib
306 | LCLoadCommand::LcLazyLoadDylib
307 | LCLoadCommand::LcLoadUpwardDylib => {
308 let cmd = DylibCommand::parse(ldcmd)?;
309 match base.clone().cmd {
310 LCLoadCommand::LcLoadDylib => Ok(LoadCommand::LoadDylib(cmd)),
311 LCLoadCommand::LcIdDylib => Ok(LoadCommand::DylibId(cmd)),
312 LCLoadCommand::LcLoadWeakDylib => Ok(LoadCommand::LoadWeakDylib(cmd)),
313 LCLoadCommand::LcReexportDylib => Ok(LoadCommand::ReexportDylib(cmd)),
314 LCLoadCommand::LcLazyLoadDylib => Ok(LoadCommand::LazyLoadDylib(cmd)),
315 LCLoadCommand::LcLoadUpwardDylib => {
316 Ok(LoadCommand::LoadUpwardDylib(cmd))
317 }
318 _ => unreachable!(),
319 }
320 }
321 LCLoadCommand::LcSymtab => {
322 Ok(LoadCommand::Symtab(SymtabCommand::parse(ldcmd)?))
323 }
324 LCLoadCommand::LcSymseg => {
325 Ok(LoadCommand::Symseg(SymsegCommand::parse(ldcmd)?))
326 }
327 LCLoadCommand::LcThread | LCLoadCommand::LcUnixThread => {
328 let cmd = ThreadCommand::parse(ldcmd)?;
329 match base.cmd {
330 LCLoadCommand::LcThread => Ok(LoadCommand::Thread(cmd)),
331 LCLoadCommand::LcUnixThread => Ok(LoadCommand::UnixThread(cmd)),
332 _ => unreachable!(),
333 }
334 }
335 LCLoadCommand::LcDysymtab => {
336 Ok(LoadCommand::Dysymtab(DysymtabCommand::parse(ldcmd)?))
337 }
338 LCLoadCommand::LcLoadDylinker
339 | LCLoadCommand::LcIdDylinker
340 | LCLoadCommand::LcDyldEnvironment => {
341 let cmd = DylinkerCommand::parse(ldcmd)?;
342 match base.cmd {
343 LCLoadCommand::LcLoadDylinker => Ok(LoadCommand::LoadDylinker(cmd)),
344 LCLoadCommand::LcIdDylinker => Ok(LoadCommand::IdDylinker(cmd)),
345 LCLoadCommand::LcDyldEnvironment => {
346 Ok(LoadCommand::DyldEnvironment(cmd))
347 }
348 _ => unreachable!(),
349 }
350 }
351 LCLoadCommand::LcPreboundDylib => {
352 Ok(LoadCommand::PreboundDylib(PreboundDylibCommand::parse(ldcmd)?))
353 }
354 LCLoadCommand::LcRoutines | LCLoadCommand::LcRoutines64 => {
355 let cmd = RoutinesCommand64::parse(ldcmd)?;
356 match base.cmd {
357 LCLoadCommand::LcRoutines => Ok(LoadCommand::Routines(cmd)),
358 LCLoadCommand::LcRoutines64 => Ok(LoadCommand::Routines64(cmd)),
359 _ => unreachable!(),
360 }
361 }
362 LCLoadCommand::LcSubFramework => {
363 Ok(LoadCommand::SubFramework(SubFrameworkCommand::parse(ldcmd)?))
364 }
365 LCLoadCommand::LcSubUmbrella => {
366 Ok(LoadCommand::SubUmbrella(SubUmbrellaCommand::parse(ldcmd)?))
367 }
368 LCLoadCommand::LcSubClient => {
369 Ok(LoadCommand::SubClient(SubClientCommand::parse(ldcmd)?))
370 }
371 LCLoadCommand::LcSubLibrary => {
372 Ok(LoadCommand::SubLibrary(SubLibraryCommand::parse(ldcmd)?))
373 }
374 LCLoadCommand::LcTwolevelHints => {
375 Ok(LoadCommand::TwoLevelHints(TwoLevelHintsCommand::parse(ldcmd)?))
376 }
377 LCLoadCommand::LcPrebindCksum => {
378 Ok(LoadCommand::PrebindCksum(PrebindCksumCommand::parse(ldcmd)?))
379 }
380 LCLoadCommand::LcUuid => {
381 Ok(LoadCommand::UUID(UuidCommand::parse(ldcmd)?))
382 }
383 LCLoadCommand::LcRpath => {
384 Ok(LoadCommand::Rpath(RpathCommand::parse(ldcmd)?))
385 }
386 LCLoadCommand::LcFunctionStarts => {
387 Ok(LoadCommand::FunctionStarts(FunctionStartsCommand::parse(ldcmd)?))
388 }
389 LCLoadCommand::LcCodeSignature => {
390 Ok(LoadCommand::CodeSignature(CodeSignCommand::parse(ldcmd)?))
391 }
392 LCLoadCommand::LcDyldChainedFixups => {
393 Ok(LoadCommand::DyldChainedFixups(DyldChainedFixupCommand::parse(ldcmd)?))
394 }
395 LCLoadCommand::LcDyldExportsTrie => {
396 Ok(LoadCommand::DyldExportsTrie(DyldExportsTrie::parse(ldcmd)?))
397 }
398 LCLoadCommand::LcSegmentSplitInfo
399 | LCLoadCommand::LcDataInCode
400 | LCLoadCommand::LcDylibCodeSignDrs
401 | LCLoadCommand::LcLinkerOptimizationHint
402 | LCLoadCommand::LcAtomInfo => {
403 let (_, cmd) = LinkeditDataCommand::parse(ldcmd)?;
404 match base.cmd {
405 LCLoadCommand::LcSegmentSplitInfo => {
406 Ok(LoadCommand::SegmentSplitInfo(cmd))
407 }
408 LCLoadCommand::LcDataInCode => Ok(LoadCommand::DataInCode(cmd)),
409 LCLoadCommand::LcDylibCodeSignDrs => {
410 Ok(LoadCommand::DylibCodeSignDrs(cmd))
411 }
412 LCLoadCommand::LcLinkerOptimizationHint => {
413 Ok(LoadCommand::LinkerOptimizationHint(cmd))
414 }
415 LCLoadCommand::LcAtomInfo => Ok(LoadCommand::AtomInfo(cmd)),
416 _ => unreachable!(),
417 }
418 }
419 LCLoadCommand::LcEncryptionInfo => {
420 Ok(LoadCommand::EncryptionInfo(EncryptionInfoCommand::parse(ldcmd)?))
421 }
422 LCLoadCommand::LcDyldInfo | LCLoadCommand::LcDyldInfoOnly => {
423 let cmd = DyldInfoCommand::parse(ldcmd)?;
424 match base.cmd {
425 LCLoadCommand::LcDyldInfo => Ok(LoadCommand::DyldInfo(cmd)),
426 LCLoadCommand::LcDyldInfoOnly => Ok(LoadCommand::DyldInfoOnly(cmd)),
427 _ => unreachable!(),
428 }
429 }
430 LCLoadCommand::LcVersionMinMacosx
431 | LCLoadCommand::LcVersionMinIphoneos
432 | LCLoadCommand::LcVersionMinTvos
433 | LCLoadCommand::LcVersionMinWatchos => {
434 let cmd = VersionMinCommand::parse(ldcmd)?;
435 match base.cmd {
436 LCLoadCommand::LcVersionMinMacosx => {
437 Ok(LoadCommand::VersionMinMacosx(cmd))
438 }
439 LCLoadCommand::LcVersionMinIphoneos => {
440 Ok(LoadCommand::VersionMinIphoneos(cmd))
441 }
442 LCLoadCommand::LcVersionMinTvos => {
443 Ok(LoadCommand::VersionMinTvos(cmd))
444 }
445 LCLoadCommand::LcVersionMinWatchos => {
446 Ok(LoadCommand::VersionMinWatchos(cmd))
447 }
448 _ => unreachable!(),
449 }
450 }
451 LCLoadCommand::LcMain => {
452 Ok(LoadCommand::Main(EntryPointCommand::parse(ldcmd)?))
453 }
454 LCLoadCommand::LcSourceVersion => {
455 Ok(LoadCommand::SourceVersion(SourceVersionCommand::parse(ldcmd)?))
456 }
457 LCLoadCommand::LcEncryptionInfo64 => {
458 Ok(LoadCommand::EncryptionInfo64(EncryptionInfoCommand64::parse(ldcmd)?))
459 }
460 LCLoadCommand::LcLinkerOption => {
461 Ok(LoadCommand::LinkerOption(LinkerOptionCommand::parse(ldcmd)?))
462 }
463 LCLoadCommand::LcNote => {
464 Ok(LoadCommand::Note(NoteCommand::parse(ldcmd)?))
465 }
466 LCLoadCommand::LcBuildVersion => {
467 Ok(LoadCommand::BuildVersion(BuildVersionCommand::parse(ldcmd)?))
468 }
469 LCLoadCommand::LcFilesetEntry => {
470 Ok(LoadCommand::FilesetEntry(FilesetEntryCommand::parse(ldcmd)?))
471 }
472 LCLoadCommand::None => Err(MachOErr::UnknownLoadCommand),
473 }
474 }
475
476 pub fn serialize(&self) -> Vec<u8> {
477 match self {
478 LoadCommand::None => vec![],
479 LoadCommand::Segment32(cmd) => cmd.serialize(),
480 LoadCommand::Symtab(cmd) => cmd.serialize(),
481 LoadCommand::Symseg(cmd) => cmd.serialize(),
482 LoadCommand::Thread(cmd) => cmd.serialize(),
483 LoadCommand::UnixThread(cmd) => cmd.serialize(),
484 LoadCommand::Dysymtab(cmd) => cmd.serialize(),
485 LoadCommand::LoadDylib(cmd) => cmd.serialize(),
486 LoadCommand::DylibId(cmd) => cmd.serialize(),
487 LoadCommand::LoadDylinker(cmd) => cmd.serialize(),
488 LoadCommand::IdDylinker(cmd) => cmd.serialize(),
489 LoadCommand::PreboundDylib(cmd) => cmd.serialize(),
490 LoadCommand::Routines(cmd) => cmd.serialize(),
491 LoadCommand::SubFramework(cmd) => cmd.serialize(),
492 LoadCommand::SubUmbrella(cmd) => cmd.serialize(),
493 LoadCommand::SubClient(cmd) => cmd.serialize(),
494 LoadCommand::SubLibrary(cmd) => cmd.serialize(),
495 LoadCommand::TwoLevelHints(cmd) => cmd.serialize(),
496 LoadCommand::PrebindCksum(cmd) => cmd.serialize(),
497 LoadCommand::LoadWeakDylib(cmd) => cmd.serialize(),
498 LoadCommand::Segment64(cmd) => cmd.serialize(),
499 LoadCommand::Routines64(cmd) => cmd.serialize(),
500 LoadCommand::UUID(cmd) => cmd.serialize(),
501 LoadCommand::Rpath(cmd) => cmd.serialize(),
502 LoadCommand::CodeSignature(cmd) => cmd.serialize(),
503 LoadCommand::SegmentSplitInfo(cmd) => cmd.serialize(),
504 LoadCommand::ReexportDylib(cmd) => cmd.serialize(),
505 LoadCommand::LazyLoadDylib(cmd) => cmd.serialize(),
506 LoadCommand::EncryptionInfo(cmd) => cmd.serialize(),
507 LoadCommand::DyldInfo(cmd) => cmd.serialize(),
508 LoadCommand::DyldInfoOnly(cmd) => cmd.serialize(),
509 LoadCommand::LoadUpwardDylib(cmd) => cmd.serialize(),
510 LoadCommand::VersionMinMacosx(cmd) => cmd.serialize(),
511 LoadCommand::VersionMinIphoneos(cmd) => cmd.serialize(),
512 LoadCommand::FunctionStarts(cmd) => cmd.serialize(),
513 LoadCommand::DyldEnvironment(cmd) => cmd.serialize(),
514 LoadCommand::Main(cmd) => cmd.serialize(),
515 LoadCommand::DataInCode(cmd) => cmd.serialize(),
516 LoadCommand::SourceVersion(cmd) => cmd.serialize(),
517 LoadCommand::DylibCodeSignDrs(cmd) => cmd.serialize(),
518 LoadCommand::EncryptionInfo64(cmd) => cmd.serialize(),
519 LoadCommand::LinkerOption(cmd) => cmd.serialize(),
520 LoadCommand::LinkerOptimizationHint(cmd) => cmd.serialize(),
521 LoadCommand::VersionMinTvos(cmd) => cmd.serialize(),
522 LoadCommand::VersionMinWatchos(cmd) => cmd.serialize(),
523 LoadCommand::Note(cmd) => cmd.serialize(),
524 LoadCommand::BuildVersion(cmd) => cmd.serialize(),
525 LoadCommand::DyldExportsTrie(cmd) => cmd.serialize(),
526 LoadCommand::DyldChainedFixups(cmd) => cmd.serialize(),
527 LoadCommand::FilesetEntry(cmd) => cmd.serialize(),
528 LoadCommand::AtomInfo(cmd) => cmd.serialize(),
529 }
530 }
531}