| ... | @@ -49,6 +49,10 @@ const alloc_den = 3; | ... | @@ -49,6 +49,10 @@ const alloc_den = 3; |
| 49 | /// Default path to dyld | 49 | /// Default path to dyld |
| 50 | const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld"; | 50 | const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld"; |
| 51 | | 51 | |
| | 52 | /// We always have to link against libSystem since macOS Catalina (TODO link) |
| | 53 | const LIB_SYSTEM_NAME: [*:0]const u8 = "System"; |
| | 54 | const LIB_SYSTEM_PATH: [*:0]const u8 = "/usr/lib/libSystem.B.dylib"; |
| | 55 | |
| 52 | pub const TextBlock = struct { | 56 | pub const TextBlock = struct { |
| 53 | pub const empty = TextBlock{}; | 57 | pub const empty = TextBlock{}; |
| 54 | }; | 58 | }; |
| ... | @@ -226,12 +230,41 @@ pub fn flush(self: *MachO, module: *Module) !void { | ... | @@ -226,12 +230,41 @@ pub fn flush(self: *MachO, module: *Module) !void { |
| 226 | | 230 | |
| 227 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(load_dylinker[0..1]), self.command_file_offset.?); | 231 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(load_dylinker[0..1]), self.command_file_offset.?); |
| 228 | | 232 | |
| 229 | const padded_path = try self.base.allocator.alloc(u8, cmdsize - @sizeOf(macho.dylinker_command)); | 233 | const file_offset = self.command_file_offset.? + @sizeOf(macho.dylinker_command); |
| 230 | defer self.base.allocator.free(padded_path); | 234 | try self.addPadding(cmdsize - @sizeOf(macho.dylinker_command), file_offset); |
| 231 | mem.set(u8, padded_path[0..], 0); | | |
| 232 | mem.copy(u8, padded_path[0..], mem.spanZ(DEFAULT_DYLD_PATH)); | | |
| 233 | | 235 | |
| 234 | try self.base.file.?.pwriteAll(padded_path, self.command_file_offset.? + @sizeOf(macho.dylinker_command)); | 236 | try self.base.file.?.pwriteAll(mem.spanZ(DEFAULT_DYLD_PATH), file_offset); |
| | 237 | self.command_file_offset.? += cmdsize; |
| | 238 | } |
| | 239 | |
| | 240 | { |
| | 241 | // Link against libSystem |
| | 242 | const cmdsize = commandSize(@intCast(u32, @sizeOf(macho.dylib_command) + mem.lenZ(LIB_SYSTEM_PATH))); |
| | 243 | const version = std.c.NSVersionOfRunTimeLibrary(LIB_SYSTEM_NAME); |
| | 244 | const dylib = .{ |
| | 245 | .name = @sizeOf(macho.dylib_command), |
| | 246 | .timestamp = 2, // not sure why not simply 0; this is reverse engineered from Mach-O files |
| | 247 | .current_version = version, |
| | 248 | .compatibility_version = 0x10000, // not sure why this either; value from reverse engineering |
| | 249 | }; |
| | 250 | const load_dylib = [1]macho.dylib_command{ |
| | 251 | .{ |
| | 252 | .cmd = macho.LC_LOAD_DYLIB, |
| | 253 | .cmdsize = cmdsize, |
| | 254 | .dylib = dylib, |
| | 255 | }, |
| | 256 | }; |
| | 257 | try self.commands.append(self.base.allocator, .{ |
| | 258 | .cmd = macho.LC_LOAD_DYLIB, |
| | 259 | .cmdsize = cmdsize, |
| | 260 | }); |
| | 261 | |
| | 262 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(load_dylib[0..1]), self.command_file_offset.?); |
| | 263 | |
| | 264 | const file_offset = self.command_file_offset.? + @sizeOf(macho.dylib_command); |
| | 265 | try self.addPadding(cmdsize - @sizeOf(macho.dylib_command), file_offset); |
| | 266 | |
| | 267 | try self.base.file.?.pwriteAll(mem.spanZ(LIB_SYSTEM_PATH), file_offset); |
| 235 | self.command_file_offset.? += cmdsize; | 268 | self.command_file_offset.? += cmdsize; |
| 236 | } | 269 | } |
| 237 | }, | 270 | }, |
| ... | @@ -431,3 +464,14 @@ fn commandSize(min_size: u32) u32 { | ... | @@ -431,3 +464,14 @@ fn commandSize(min_size: u32) u32 { |
| 431 | const div = min_size / @sizeOf(u64); | 464 | const div = min_size / @sizeOf(u64); |
| 432 | return (div + 1) * @sizeOf(u64); | 465 | return (div + 1) * @sizeOf(u64); |
| 433 | } | 466 | } |
| | 467 | |
| | 468 | fn addPadding(self: *MachO, size: u32, file_offset: u64) !void { |
| | 469 | if (size == 0) return; |
| | 470 | |
| | 471 | const buf = try self.base.allocator.alloc(u8, size); |
| | 472 | defer self.base.allocator.free(buf); |
| | 473 | |
| | 474 | mem.set(u8, buf[0..], 0); |
| | 475 | |
| | 476 | try self.base.file.?.pwriteAll(buf, file_offset); |
| | 477 | } |