Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mach/load_command: Add some missing load commands #240

Merged
merged 5 commits into from
Oct 13, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions src/mach/load_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,8 @@ pub const SIZEOF_RPATH_COMMAND: usize = 12;
#[repr(C)]
#[derive(Debug, Clone, Copy, Pread, Pwrite, IOread, IOwrite, SizeWith)]
pub struct LinkeditDataCommand {
/// LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS or LC_LINKER_OPTIMIZATION_HINT.
/// LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
/// LC_DYLIB_CODE_SIGN_DRS, LC_LINKER_OPTIMIZATION_HINT, LC_DYLD_EXPORTS_TRIE, or LC_DYLD_CHAINED_FIXUPS.
pub cmd: u32,
/// sizeof(struct linkedit_data_command)
pub cmdsize: u32,
Expand Down Expand Up @@ -1001,10 +1002,10 @@ pub const SIZEOF_ENCRYPTION_INFO_COMMAND_64: usize = 24;
/// The version_min_command contains the min OS version on which this
/// binary was built to run.
///
/// LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
#[repr(C)]
#[derive(Debug, Clone, Copy, Pread, Pwrite, IOread, IOwrite, SizeWith)]
pub struct VersionMinCommand {
/// LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS, or LC_VERSION_MIN_WATCHOS.
pub cmd: u32,
pub cmdsize: u32,
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
Expand All @@ -1014,6 +1015,7 @@ pub struct VersionMinCommand {
}

impl VersionMinCommand {
// TODO: Needs a discriminant for TvOS, WatchOS.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we ought to break this interface. Maybe add a new #[non_exhaustive] enum Platform and add a fn platform(&self) -> Platform while we're at it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM! I can make that part of this PR.

pub fn new(is_ios: bool) -> Self {
VersionMinCommand {
cmd: if is_ios {
Expand Down Expand Up @@ -1184,6 +1186,8 @@ pub const LC_REEXPORT_DYLIB: u32 = 0x1f | LC_REQ_DYLD;
pub const LC_DYLD_INFO_ONLY: u32 = 0x22 | LC_REQ_DYLD;
pub const LC_LOAD_UPWARD_DYLIB: u32 = 0x23 | LC_REQ_DYLD;
pub const LC_MAIN: u32 = 0x28 | LC_REQ_DYLD;
pub const LC_DYLD_EXPORTS_TRIE: u32 = 0x33 | LC_REQ_DYLD;
pub const LC_DYLD_CHAINED_FIXUPS: u32 = 0x34 | LC_REQ_DYLD;
pub const LC_SEGMENT: u32 = 0x1;
pub const LC_SYMTAB: u32 = 0x2;
pub const LC_SYMSEG: u32 = 0x3;
Expand Down Expand Up @@ -1225,6 +1229,10 @@ pub const LC_DYLIB_CODE_SIGN_DRS: u32 = 0x2B;
pub const LC_ENCRYPTION_INFO_64: u32 = 0x2C;
pub const LC_LINKER_OPTION: u32 = 0x2D;
pub const LC_LINKER_OPTIMIZATION_HINT: u32 = 0x2E;
pub const LC_VERSION_MIN_TVOS: u32 = 0x2F;
pub const LC_VERSION_MIN_WATCHOS: u32 = 0x30;
pub const LC_NOTE: u32 = 0x31;
pub const LC_BUILD_VERSION: u32 = 0x32;

pub fn cmd_to_str(cmd: u32) -> &'static str {
match cmd {
Expand Down Expand Up @@ -1275,6 +1283,12 @@ pub fn cmd_to_str(cmd: u32) -> &'static str {
LC_ENCRYPTION_INFO_64 => "LC_ENCRYPTION_INFO_64",
LC_LINKER_OPTION => "LC_LINKER_OPTION",
LC_LINKER_OPTIMIZATION_HINT => "LC_LINKER_OPTIMIZATION_HINT",
LC_VERSION_MIN_TVOS => "LC_VERSION_MIN_TVOS",
LC_VERSION_MIN_WATCHOS => "LC_VERSION_MIN_WATCHOS",
LC_NOTE => "LC_NOTE",
LC_BUILD_VERSION => "LC_BUILD_VERSION",
LC_DYLD_EXPORTS_TRIE => "LC_DYLD_EXPORTS_TRIE",
LC_DYLD_CHAINED_FIXUPS => "LC_DYLD_CHAINED_FIXUPS",
_ => "LC_UNKNOWN",
}
}
Expand Down Expand Up @@ -1334,6 +1348,10 @@ pub enum CommandVariant {
DylibCodeSignDrs(LinkeditDataCommand),
LinkerOption(LinkeditDataCommand),
LinkerOptimizationHint(LinkeditDataCommand),
VersionMinTvos(VersionMinCommand),
VersionMinWatchos(VersionMinCommand),
DyldExportsTrie(LinkeditDataCommand),
DyldChainedFixups(LinkeditDataCommand),
Unimplemented(LoadCommandHeader),
}

Expand Down Expand Up @@ -1540,7 +1558,25 @@ impl<'a> ctx::TryFromCtx<'a, Endian> for CommandVariant {
let comm = bytes.pread_with::<LinkeditDataCommand>(0, le)?;
Ok((LinkerOptimizationHint(comm), size))
}
_ => Ok((Unimplemented(lc), size)),
LC_VERSION_MIN_TVOS => {
let comm = bytes.pread_with::<VersionMinCommand>(0, le)?;
Ok((VersionMinTvos(comm), size))
}
LC_VERSION_MIN_WATCHOS => {
let comm = bytes.pread_with::<VersionMinCommand>(0, le)?;
Ok((VersionMinWatchos(comm), size))
}
LC_DYLD_EXPORTS_TRIE => {
let comm = bytes.pread_with::<LinkeditDataCommand>(0, le)?;
Ok((DyldExportsTrie(comm), size))
}
LC_DYLD_CHAINED_FIXUPS => {
let comm = bytes.pread_with::<LinkeditDataCommand>(0, le)?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and above are both LinkEditDataCommand? Interesting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, they both reside in __linkedit, like a few others.

Ok((DyldChainedFixups(comm), size))
}
// TODO: LC_NOTE (NoteCommand) and LC_BUILD_VERSION (BuildVersionCommand)
// are unimplemented.
LC_NOTE | LC_BUILD_VERSION | _ => Ok((Unimplemented(lc), size)),
}
}
}
Expand Down Expand Up @@ -1596,6 +1632,10 @@ impl CommandVariant {
DylibCodeSignDrs(comm) => comm.cmdsize,
LinkerOption(comm) => comm.cmdsize,
LinkerOptimizationHint(comm) => comm.cmdsize,
VersionMinTvos(comm) => comm.cmdsize,
VersionMinWatchos(comm) => comm.cmdsize,
DyldExportsTrie(comm) => comm.cmdsize,
DyldChainedFixups(comm) => comm.cmdsize,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don’t need to do this now but might be a good idea to add non exhaustive annotations to these enums as much well

Unimplemented(comm) => comm.cmdsize,
};
cmdsize as usize
Expand Down Expand Up @@ -1650,6 +1690,10 @@ impl CommandVariant {
DylibCodeSignDrs(comm) => comm.cmd,
LinkerOption(comm) => comm.cmd,
LinkerOptimizationHint(comm) => comm.cmd,
VersionMinTvos(comm) => comm.cmd,
VersionMinWatchos(comm) => comm.cmd,
DyldExportsTrie(comm) => comm.cmd,
DyldChainedFixups(comm) => comm.cmd,
Unimplemented(comm) => comm.cmd,
}
}
Expand Down