| ... | @@ -16,8 +16,6 @@ const Module = @import("../Module.zig"); | ... | @@ -16,8 +16,6 @@ const Module = @import("../Module.zig"); |
| 16 | const link = @import("../link.zig"); | 16 | const link = @import("../link.zig"); |
| 17 | const File = link.File; | 17 | const File = link.File; |
| 18 | | 18 | |
| 19 | const is_darwin = std.Target.current.os.tag.isDarwin(); | | |
| 20 | | | |
| 21 | pub const base_tag: File.Tag = File.Tag.macho; | 19 | pub const base_tag: File.Tag = File.Tag.macho; |
| 22 | | 20 | |
| 23 | base: File, | 21 | base: File, |
| ... | @@ -227,63 +225,61 @@ pub fn flush(self: *MachO, module: *Module) !void { | ... | @@ -227,63 +225,61 @@ pub fn flush(self: *MachO, module: *Module) !void { |
| 227 | | 225 | |
| 228 | switch (self.base.options.output_mode) { | 226 | switch (self.base.options.output_mode) { |
| 229 | .Exe => { | 227 | .Exe => { |
| 230 | if (is_darwin) { | 228 | { |
| 231 | { | 229 | // Specify path to dynamic linker dyld |
| 232 | // Specify path to dynamic linker dyld | 230 | const cmdsize = commandSize(@sizeOf(macho.dylinker_command) + mem.lenZ(DEFAULT_DYLD_PATH)); |
| 233 | const cmdsize = commandSize(@sizeOf(macho.dylinker_command) + mem.lenZ(DEFAULT_DYLD_PATH)); | 231 | const load_dylinker = [1]macho.dylinker_command{ |
| 234 | const load_dylinker = [1]macho.dylinker_command{ | 232 | .{ |
| 235 | .{ | | |
| 236 | .cmd = macho.LC_LOAD_DYLINKER, | | |
| 237 | .cmdsize = cmdsize, | | |
| 238 | .name = @sizeOf(macho.dylinker_command), | | |
| 239 | }, | | |
| 240 | }; | | |
| 241 | try self.commands.append(self.base.allocator, .{ | | |
| 242 | .cmd = macho.LC_LOAD_DYLINKER, | 233 | .cmd = macho.LC_LOAD_DYLINKER, |
| 243 | .cmdsize = cmdsize, | 234 | .cmdsize = cmdsize, |
| 244 | }); | 235 | .name = @sizeOf(macho.dylinker_command), |
| 245 | | 236 | }, |
| 246 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(load_dylinker[0..1]), self.command_file_offset.?); | 237 | }; |
| 247 | | 238 | try self.commands.append(self.base.allocator, .{ |
| 248 | const file_offset = self.command_file_offset.? + @sizeOf(macho.dylinker_command); | 239 | .cmd = macho.LC_LOAD_DYLINKER, |
| 249 | try self.addPadding(cmdsize - @sizeOf(macho.dylinker_command), file_offset); | 240 | .cmdsize = cmdsize, |
| 250 | | 241 | }); |
| 251 | try self.base.file.?.pwriteAll(mem.spanZ(DEFAULT_DYLD_PATH), file_offset); | 242 | |
| 252 | self.command_file_offset.? += cmdsize; | 243 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(load_dylinker[0..1]), self.command_file_offset.?); |
| 253 | } | 244 | |
| 254 | | 245 | const file_offset = self.command_file_offset.? + @sizeOf(macho.dylinker_command); |
| 255 | { | 246 | try self.addPadding(cmdsize - @sizeOf(macho.dylinker_command), file_offset); |
| 256 | // Link against libSystem | 247 | |
| 257 | const cmdsize = commandSize(@sizeOf(macho.dylib_command) + mem.lenZ(LIB_SYSTEM_PATH)); | 248 | try self.base.file.?.pwriteAll(mem.spanZ(DEFAULT_DYLD_PATH), file_offset); |
| 258 | // According to Apple's manual, we should obtain current libSystem version using libc call | 249 | self.command_file_offset.? += cmdsize; |
| 259 | // NSVersionOfRunTimeLibrary. | 250 | } |
| 260 | const version = std.c.NSVersionOfRunTimeLibrary(LIB_SYSTEM_NAME); | 251 | |
| 261 | const dylib = .{ | 252 | { |
| 262 | .name = @sizeOf(macho.dylib_command), | 253 | // Link against libSystem |
| 263 | .timestamp = 2, // not sure why not simply 0; this is reverse engineered from Mach-O files | 254 | const cmdsize = commandSize(@sizeOf(macho.dylib_command) + mem.lenZ(LIB_SYSTEM_PATH)); |
| 264 | .current_version = version, | 255 | // TODO Find a way to work out runtime version from the OS version triple stored in std.Target. |
| 265 | .compatibility_version = 0x10000, // not sure why this either; value from reverse engineering | 256 | // In the meantime, we're gonna hardcode to the minimum compatibility version of 1.0.0. |
| 266 | }; | 257 | const min_version = 0x10000; |
| 267 | const load_dylib = [1]macho.dylib_command{ | 258 | const dylib = .{ |
| 268 | .{ | 259 | .name = @sizeOf(macho.dylib_command), |
| 269 | .cmd = macho.LC_LOAD_DYLIB, | 260 | .timestamp = 2, // not sure why not simply 0; this is reverse engineered from Mach-O files |
| 270 | .cmdsize = cmdsize, | 261 | .current_version = min_version, |
| 271 | .dylib = dylib, | 262 | .compatibility_version = min_version, |
| 272 | }, | 263 | }; |
| 273 | }; | 264 | const load_dylib = [1]macho.dylib_command{ |
| 274 | try self.commands.append(self.base.allocator, .{ | 265 | .{ |
| 275 | .cmd = macho.LC_LOAD_DYLIB, | 266 | .cmd = macho.LC_LOAD_DYLIB, |
| 276 | .cmdsize = cmdsize, | 267 | .cmdsize = cmdsize, |
| 277 | }); | 268 | .dylib = dylib, |
| | 269 | }, |
| | 270 | }; |
| | 271 | try self.commands.append(self.base.allocator, .{ |
| | 272 | .cmd = macho.LC_LOAD_DYLIB, |
| | 273 | .cmdsize = cmdsize, |
| | 274 | }); |
| 278 | | 275 | |
| 279 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(load_dylib[0..1]), self.command_file_offset.?); | 276 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(load_dylib[0..1]), self.command_file_offset.?); |
| 280 | | 277 | |
| 281 | const file_offset = self.command_file_offset.? + @sizeOf(macho.dylib_command); | 278 | const file_offset = self.command_file_offset.? + @sizeOf(macho.dylib_command); |
| 282 | try self.addPadding(cmdsize - @sizeOf(macho.dylib_command), file_offset); | 279 | try self.addPadding(cmdsize - @sizeOf(macho.dylib_command), file_offset); |
| 283 | | 280 | |
| 284 | try self.base.file.?.pwriteAll(mem.spanZ(LIB_SYSTEM_PATH), file_offset); | 281 | try self.base.file.?.pwriteAll(mem.spanZ(LIB_SYSTEM_PATH), file_offset); |
| 285 | self.command_file_offset.? += cmdsize; | 282 | self.command_file_offset.? += cmdsize; |
| 286 | } | | |
| 287 | } | 283 | } |
| 288 | }, | 284 | }, |
| 289 | .Obj => return error.TODOImplementWritingObjFiles, | 285 | .Obj => return error.TODOImplementWritingObjFiles, |