stage2 MachO: add min OS version load cmd
parent
58365c4e79
commit
72310db1da
|
@ -705,6 +705,23 @@ pub const relocation_info = packed struct {
|
|||
r_type: u4,
|
||||
};
|
||||
|
||||
/// The version_min_command contains the min OS version on which this
|
||||
/// binary was built to run.
|
||||
pub const version_min_command = extern struct {
|
||||
/// LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS or LC_VERSION_MIN_WATCHOS
|
||||
/// or LC_VERSION_MIN_TVOS
|
||||
cmd: u32,
|
||||
|
||||
/// sizeof(struct min_version_command)
|
||||
cmdsize: u32,
|
||||
|
||||
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
|
||||
version: u32,
|
||||
|
||||
/// X.Y.Z is encoded in nibbles xxxx.yy.zz
|
||||
sdk: u32,
|
||||
};
|
||||
|
||||
/// After MacOS X 10.1 when a new load command is added that is required to be
|
||||
/// understood by the dynamic linker for the image to execute properly the
|
||||
/// LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic
|
||||
|
|
|
@ -33,6 +33,7 @@ const LoadCommand = union(enum) {
|
|||
Dylinker: macho.dylinker_command,
|
||||
Dylib: macho.dylib_command,
|
||||
EntryPoint: macho.entry_point_command,
|
||||
MinVersion: macho.version_min_command,
|
||||
|
||||
pub fn cmdsize(self: LoadCommand) u32 {
|
||||
return switch (self) {
|
||||
|
@ -44,6 +45,7 @@ const LoadCommand = union(enum) {
|
|||
.Dylinker => |x| x.cmdsize,
|
||||
.Dylib => |x| x.cmdsize,
|
||||
.EntryPoint => |x| x.cmdsize,
|
||||
.MinVersion => |x| x.cmdsize,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -57,6 +59,7 @@ const LoadCommand = union(enum) {
|
|||
.Dylinker => |cmd| writeGeneric(cmd, file, offset),
|
||||
.Dylib => |cmd| writeGeneric(cmd, file, offset),
|
||||
.EntryPoint => |cmd| writeGeneric(cmd, file, offset),
|
||||
.MinVersion => |cmd| writeGeneric(cmd, file, offset),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -96,6 +99,8 @@ function_starts_cmd_index: ?u16 = null,
|
|||
/// Specifies offset wrt __TEXT segment start address to the main entry point
|
||||
/// of the binary.
|
||||
main_cmd_index: ?u16 = null,
|
||||
/// Minimum OS version
|
||||
version_min_cmd_index: ?u16 = null,
|
||||
|
||||
/// Table of all sections
|
||||
sections: std.ArrayListUnmanaged(macho.section_64) = .{},
|
||||
|
@ -317,8 +322,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
|||
try self.writeAllGlobalSymbols();
|
||||
try self.writeAllUndefSymbols();
|
||||
|
||||
try self.writeStringTable();
|
||||
|
||||
switch (self.base.options.output_mode) {
|
||||
.Exe => {
|
||||
// Write export trie.
|
||||
|
@ -379,8 +382,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
|||
const nundefs = @intCast(u32, self.undef_symbols.items.len);
|
||||
const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
|
||||
symtab.nsyms = nlocals + nglobals + nundefs;
|
||||
symtab.stroff = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64);
|
||||
}
|
||||
|
||||
try self.writeStringTable();
|
||||
|
||||
if (self.cmd_table_dirty) {
|
||||
try self.writeCmdHeaders();
|
||||
try self.writeMachOHeader();
|
||||
|
@ -1329,8 +1335,8 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
|||
self.libsystem_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
const cmdsize = mem.alignForwardGeneric(u64, @sizeOf(macho.dylib_command) + mem.lenZ(LIB_SYSTEM_PATH), @sizeOf(u64));
|
||||
// TODO Find a way to work out runtime version from the OS version triple stored in std.Target.
|
||||
// In the meantime, we're gonna hardcode to the minimum compatibility version of 1.0.0.
|
||||
const min_version = 0x10000;
|
||||
// In the meantime, we're gonna hardcode to the minimum compatibility version of 0.0.0.
|
||||
const min_version = 0x0;
|
||||
const dylib = .{
|
||||
.name = @sizeOf(macho.dylib_command),
|
||||
.timestamp = 2, // not sure why not simply 0; this is reverse engineered from Mach-O files
|
||||
|
@ -1359,6 +1365,18 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
|||
});
|
||||
self.cmd_table_dirty = true;
|
||||
}
|
||||
if (self.version_min_cmd_index == null) {
|
||||
self.version_min_cmd_index = @intCast(u16, self.load_commands.items.len);
|
||||
try self.load_commands.append(self.base.allocator, .{
|
||||
// TODO allow for different targets and different versions
|
||||
.MinVersion = .{
|
||||
.cmd = macho.LC_VERSION_MIN_MACOSX,
|
||||
.cmdsize = @sizeOf(macho.version_min_command),
|
||||
.version = 0xB0001, // 11.0.1 BigSur
|
||||
.sdk = 0xB0001, // 11.0.1 BigSur
|
||||
},
|
||||
});
|
||||
}
|
||||
{
|
||||
const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
|
||||
const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo;
|
||||
|
|
Loading…
Reference in New Issue