| ... | @@ -25,10 +25,10 @@ usingnamespace @import("bind.zig"); | ... | @@ -25,10 +25,10 @@ usingnamespace @import("bind.zig"); |
| 25 | | 25 | |
| 26 | allocator: *Allocator, | 26 | allocator: *Allocator, |
| 27 | | 27 | |
| 28 | arch: ?std.Target.Cpu.Arch = null, | 28 | target: ?std.Target = null, |
| 29 | page_size: ?u16 = null, | 29 | page_size: ?u16 = null, |
| 30 | file: ?fs.File = null, | 30 | file: ?fs.File = null, |
| 31 | out_path: ?[]const u8 = null, | 31 | output: ?Output = null, |
| 32 | | 32 | |
| 33 | // TODO these args will become obselete once Zld is coalesced with incremental | 33 | // TODO these args will become obselete once Zld is coalesced with incremental |
| 34 | // linker. | 34 | // linker. |
| ... | @@ -54,6 +54,7 @@ dylinker_cmd_index: ?u16 = null, | ... | @@ -54,6 +54,7 @@ dylinker_cmd_index: ?u16 = null, |
| 54 | data_in_code_cmd_index: ?u16 = null, | 54 | data_in_code_cmd_index: ?u16 = null, |
| 55 | function_starts_cmd_index: ?u16 = null, | 55 | function_starts_cmd_index: ?u16 = null, |
| 56 | main_cmd_index: ?u16 = null, | 56 | main_cmd_index: ?u16 = null, |
| | 57 | dylib_id_cmd_index: ?u16 = null, |
| 57 | version_min_cmd_index: ?u16 = null, | 58 | version_min_cmd_index: ?u16 = null, |
| 58 | source_version_cmd_index: ?u16 = null, | 59 | source_version_cmd_index: ?u16 = null, |
| 59 | uuid_cmd_index: ?u16 = null, | 60 | uuid_cmd_index: ?u16 = null, |
| ... | @@ -118,6 +119,12 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{}, | ... | @@ -118,6 +119,12 @@ got_entries: std.ArrayListUnmanaged(*Symbol) = .{}, |
| 118 | | 119 | |
| 119 | stub_helper_stubs_start_off: ?u64 = null, | 120 | stub_helper_stubs_start_off: ?u64 = null, |
| 120 | | 121 | |
| | 122 | pub const Output = struct { |
| | 123 | tag: enum { exe, dylib }, |
| | 124 | path: []const u8, |
| | 125 | install_name: ?[]const u8 = null, |
| | 126 | }; |
| | 127 | |
| 121 | const TlvOffset = struct { | 128 | const TlvOffset = struct { |
| 122 | source_addr: u64, | 129 | source_addr: u64, |
| 123 | offset: u64, | 130 | offset: u64, |
| ... | @@ -200,36 +207,17 @@ const LinkArgs = struct { | ... | @@ -200,36 +207,17 @@ const LinkArgs = struct { |
| 200 | rpaths: []const []const u8, | 207 | rpaths: []const []const u8, |
| 201 | }; | 208 | }; |
| 202 | | 209 | |
| 203 | pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: LinkArgs) !void { | 210 | pub fn link(self: *Zld, files: []const []const u8, output: Output, args: LinkArgs) !void { |
| 204 | if (files.len == 0) return error.NoInputFiles; | 211 | if (files.len == 0) return error.NoInputFiles; |
| 205 | if (out_path.len == 0) return error.EmptyOutputPath; | 212 | if (output.path.len == 0) return error.EmptyOutputPath; |
| 206 | | | |
| 207 | if (self.arch == null) { | | |
| 208 | // Try inferring the arch from the object files. | | |
| 209 | self.arch = blk: { | | |
| 210 | const file = try fs.cwd().openFile(files[0], .{}); | | |
| 211 | defer file.close(); | | |
| 212 | var reader = file.reader(); | | |
| 213 | const header = try reader.readStruct(macho.mach_header_64); | | |
| 214 | const arch: std.Target.Cpu.Arch = switch (header.cputype) { | | |
| 215 | macho.CPU_TYPE_X86_64 => .x86_64, | | |
| 216 | macho.CPU_TYPE_ARM64 => .aarch64, | | |
| 217 | else => |value| { | | |
| 218 | log.err("unsupported cpu architecture 0x{x}", .{value}); | | |
| 219 | return error.UnsupportedCpuArchitecture; | | |
| 220 | }, | | |
| 221 | }; | | |
| 222 | break :blk arch; | | |
| 223 | }; | | |
| 224 | } | | |
| 225 | | 213 | |
| 226 | self.page_size = switch (self.arch.?) { | 214 | self.page_size = switch (self.target.?.cpu.arch) { |
| 227 | .aarch64 => 0x4000, | 215 | .aarch64 => 0x4000, |
| 228 | .x86_64 => 0x1000, | 216 | .x86_64 => 0x1000, |
| 229 | else => unreachable, | 217 | else => unreachable, |
| 230 | }; | 218 | }; |
| 231 | self.out_path = out_path; | 219 | self.output = output; |
| 232 | self.file = try fs.cwd().createFile(out_path, .{ | 220 | self.file = try fs.cwd().createFile(self.output.?.path, .{ |
| 233 | .truncate = true, | 221 | .truncate = true, |
| 234 | .read = true, | 222 | .read = true, |
| 235 | .mode = if (std.Target.current.os.tag == .windows) 0 else 0o777, | 223 | .mode = if (std.Target.current.os.tag == .windows) 0 else 0o777, |
| ... | @@ -263,19 +251,19 @@ fn parseInputFiles(self: *Zld, files: []const []const u8, syslibroot: ?[]const u | ... | @@ -263,19 +251,19 @@ fn parseInputFiles(self: *Zld, files: []const []const u8, syslibroot: ?[]const u |
| 263 | break :full_path try self.allocator.dupe(u8, path); | 251 | break :full_path try self.allocator.dupe(u8, path); |
| 264 | }; | 252 | }; |
| 265 | | 253 | |
| 266 | if (try Object.createAndParseFromPath(self.allocator, self.arch.?, full_path)) |object| { | 254 | if (try Object.createAndParseFromPath(self.allocator, self.target.?.cpu.arch, full_path)) |object| { |
| 267 | try self.objects.append(self.allocator, object); | 255 | try self.objects.append(self.allocator, object); |
| 268 | continue; | 256 | continue; |
| 269 | } | 257 | } |
| 270 | | 258 | |
| 271 | if (try Archive.createAndParseFromPath(self.allocator, self.arch.?, full_path)) |archive| { | 259 | if (try Archive.createAndParseFromPath(self.allocator, self.target.?.cpu.arch, full_path)) |archive| { |
| 272 | try self.archives.append(self.allocator, archive); | 260 | try self.archives.append(self.allocator, archive); |
| 273 | continue; | 261 | continue; |
| 274 | } | 262 | } |
| 275 | | 263 | |
| 276 | if (try Dylib.createAndParseFromPath( | 264 | if (try Dylib.createAndParseFromPath( |
| 277 | self.allocator, | 265 | self.allocator, |
| 278 | self.arch.?, | 266 | self.target.?.cpu.arch, |
| 279 | full_path, | 267 | full_path, |
| 280 | .{ .syslibroot = syslibroot }, | 268 | .{ .syslibroot = syslibroot }, |
| 281 | )) |dylibs| { | 269 | )) |dylibs| { |
| ... | @@ -292,7 +280,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi | ... | @@ -292,7 +280,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi |
| 292 | for (libs) |lib| { | 280 | for (libs) |lib| { |
| 293 | if (try Dylib.createAndParseFromPath( | 281 | if (try Dylib.createAndParseFromPath( |
| 294 | self.allocator, | 282 | self.allocator, |
| 295 | self.arch.?, | 283 | self.target.?.cpu.arch, |
| 296 | lib, | 284 | lib, |
| 297 | .{ .syslibroot = syslibroot }, | 285 | .{ .syslibroot = syslibroot }, |
| 298 | )) |dylibs| { | 286 | )) |dylibs| { |
| ... | @@ -301,7 +289,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi | ... | @@ -301,7 +289,7 @@ fn parseLibs(self: *Zld, libs: []const []const u8, syslibroot: ?[]const u8) !voi |
| 301 | continue; | 289 | continue; |
| 302 | } | 290 | } |
| 303 | | 291 | |
| 304 | if (try Archive.createAndParseFromPath(self.allocator, self.arch.?, lib)) |archive| { | 292 | if (try Archive.createAndParseFromPath(self.allocator, self.target.?.cpu.arch, lib)) |archive| { |
| 305 | try self.archives.append(self.allocator, archive); | 293 | try self.archives.append(self.allocator, archive); |
| 306 | continue; | 294 | continue; |
| 307 | } | 295 | } |
| ... | @@ -989,7 +977,7 @@ fn allocateTextSegment(self: *Zld) !void { | ... | @@ -989,7 +977,7 @@ fn allocateTextSegment(self: *Zld) !void { |
| 989 | const stub_helper = &seg.sections.items[self.stub_helper_section_index.?]; | 977 | const stub_helper = &seg.sections.items[self.stub_helper_section_index.?]; |
| 990 | stubs.size += nstubs * stubs.reserved2; | 978 | stubs.size += nstubs * stubs.reserved2; |
| 991 | | 979 | |
| 992 | const stub_size: u4 = switch (self.arch.?) { | 980 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 993 | .x86_64 => 10, | 981 | .x86_64 => 10, |
| 994 | .aarch64 => 3 * @sizeOf(u32), | 982 | .aarch64 => 3 * @sizeOf(u32), |
| 995 | else => unreachable, | 983 | else => unreachable, |
| ... | @@ -1226,7 +1214,7 @@ fn writeStubHelperCommon(self: *Zld) !void { | ... | @@ -1226,7 +1214,7 @@ fn writeStubHelperCommon(self: *Zld) !void { |
| 1226 | const data = &data_segment.sections.items[self.data_section_index.?]; | 1214 | const data = &data_segment.sections.items[self.data_section_index.?]; |
| 1227 | | 1215 | |
| 1228 | self.stub_helper_stubs_start_off = blk: { | 1216 | self.stub_helper_stubs_start_off = blk: { |
| 1229 | switch (self.arch.?) { | 1217 | switch (self.target.?.cpu.arch) { |
| 1230 | .x86_64 => { | 1218 | .x86_64 => { |
| 1231 | const code_size = 15; | 1219 | const code_size = 15; |
| 1232 | var code: [code_size]u8 = undefined; | 1220 | var code: [code_size]u8 = undefined; |
| ... | @@ -1358,7 +1346,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { | ... | @@ -1358,7 +1346,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { |
| 1358 | const data_segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 1346 | const data_segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1359 | const la_symbol_ptr = data_segment.sections.items[self.la_symbol_ptr_section_index.?]; | 1347 | const la_symbol_ptr = data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 1360 | | 1348 | |
| 1361 | const stub_size: u4 = switch (self.arch.?) { | 1349 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 1362 | .x86_64 => 10, | 1350 | .x86_64 => 10, |
| 1363 | .aarch64 => 3 * @sizeOf(u32), | 1351 | .aarch64 => 3 * @sizeOf(u32), |
| 1364 | else => unreachable, | 1352 | else => unreachable, |
| ... | @@ -1384,7 +1372,7 @@ fn writeStub(self: *Zld, index: u32) !void { | ... | @@ -1384,7 +1372,7 @@ fn writeStub(self: *Zld, index: u32) !void { |
| 1384 | log.debug("writing stub at 0x{x}", .{stub_off}); | 1372 | log.debug("writing stub at 0x{x}", .{stub_off}); |
| 1385 | var code = try self.allocator.alloc(u8, stubs.reserved2); | 1373 | var code = try self.allocator.alloc(u8, stubs.reserved2); |
| 1386 | defer self.allocator.free(code); | 1374 | defer self.allocator.free(code); |
| 1387 | switch (self.arch.?) { | 1375 | switch (self.target.?.cpu.arch) { |
| 1388 | .x86_64 => { | 1376 | .x86_64 => { |
| 1389 | assert(la_ptr_addr >= stub_addr + stubs.reserved2); | 1377 | assert(la_ptr_addr >= stub_addr + stubs.reserved2); |
| 1390 | const displacement = try math.cast(u32, la_ptr_addr - stub_addr - stubs.reserved2); | 1378 | const displacement = try math.cast(u32, la_ptr_addr - stub_addr - stubs.reserved2); |
| ... | @@ -1447,7 +1435,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { | ... | @@ -1447,7 +1435,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { |
| 1447 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 1435 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1448 | const stub_helper = text_segment.sections.items[self.stub_helper_section_index.?]; | 1436 | const stub_helper = text_segment.sections.items[self.stub_helper_section_index.?]; |
| 1449 | | 1437 | |
| 1450 | const stub_size: u4 = switch (self.arch.?) { | 1438 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 1451 | .x86_64 => 10, | 1439 | .x86_64 => 10, |
| 1452 | .aarch64 => 3 * @sizeOf(u32), | 1440 | .aarch64 => 3 * @sizeOf(u32), |
| 1453 | else => unreachable, | 1441 | else => unreachable, |
| ... | @@ -1455,7 +1443,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { | ... | @@ -1455,7 +1443,7 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { |
| 1455 | const stub_off = self.stub_helper_stubs_start_off.? + index * stub_size; | 1443 | const stub_off = self.stub_helper_stubs_start_off.? + index * stub_size; |
| 1456 | var code = try self.allocator.alloc(u8, stub_size); | 1444 | var code = try self.allocator.alloc(u8, stub_size); |
| 1457 | defer self.allocator.free(code); | 1445 | defer self.allocator.free(code); |
| 1458 | switch (self.arch.?) { | 1446 | switch (self.target.?.cpu.arch) { |
| 1459 | .x86_64 => { | 1447 | .x86_64 => { |
| 1460 | const displacement = try math.cast( | 1448 | const displacement = try math.cast( |
| 1461 | i32, | 1449 | i32, |
| ... | @@ -1999,7 +1987,7 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -1999,7 +1987,7 @@ fn populateMetadata(self: *Zld) !void { |
| 1999 | if (self.text_section_index == null) { | 1987 | if (self.text_section_index == null) { |
| 2000 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 1988 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2001 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); | 1989 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2002 | const alignment: u2 = switch (self.arch.?) { | 1990 | const alignment: u2 = switch (self.target.?.cpu.arch) { |
| 2003 | .x86_64 => 0, | 1991 | .x86_64 => 0, |
| 2004 | .aarch64 => 2, | 1992 | .aarch64 => 2, |
| 2005 | else => unreachable, // unhandled architecture type | 1993 | else => unreachable, // unhandled architecture type |
| ... | @@ -2013,12 +2001,12 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -2013,12 +2001,12 @@ fn populateMetadata(self: *Zld) !void { |
| 2013 | if (self.stubs_section_index == null) { | 2001 | if (self.stubs_section_index == null) { |
| 2014 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 2002 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2015 | self.stubs_section_index = @intCast(u16, text_seg.sections.items.len); | 2003 | self.stubs_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2016 | const alignment: u2 = switch (self.arch.?) { | 2004 | const alignment: u2 = switch (self.target.?.cpu.arch) { |
| 2017 | .x86_64 => 0, | 2005 | .x86_64 => 0, |
| 2018 | .aarch64 => 2, | 2006 | .aarch64 => 2, |
| 2019 | else => unreachable, // unhandled architecture type | 2007 | else => unreachable, // unhandled architecture type |
| 2020 | }; | 2008 | }; |
| 2021 | const stub_size: u4 = switch (self.arch.?) { | 2009 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 2022 | .x86_64 => 6, | 2010 | .x86_64 => 6, |
| 2023 | .aarch64 => 3 * @sizeOf(u32), | 2011 | .aarch64 => 3 * @sizeOf(u32), |
| 2024 | else => unreachable, // unhandled architecture type | 2012 | else => unreachable, // unhandled architecture type |
| ... | @@ -2033,12 +2021,12 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -2033,12 +2021,12 @@ fn populateMetadata(self: *Zld) !void { |
| 2033 | if (self.stub_helper_section_index == null) { | 2021 | if (self.stub_helper_section_index == null) { |
| 2034 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 2022 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2035 | self.stub_helper_section_index = @intCast(u16, text_seg.sections.items.len); | 2023 | self.stub_helper_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2036 | const alignment: u2 = switch (self.arch.?) { | 2024 | const alignment: u2 = switch (self.target.?.cpu.arch) { |
| 2037 | .x86_64 => 0, | 2025 | .x86_64 => 0, |
| 2038 | .aarch64 => 2, | 2026 | .aarch64 => 2, |
| 2039 | else => unreachable, // unhandled architecture type | 2027 | else => unreachable, // unhandled architecture type |
| 2040 | }; | 2028 | }; |
| 2041 | const stub_helper_size: u6 = switch (self.arch.?) { | 2029 | const stub_helper_size: u6 = switch (self.target.?.cpu.arch) { |
| 2042 | .x86_64 => 15, | 2030 | .x86_64 => 15, |
| 2043 | .aarch64 => 6 * @sizeOf(u32), | 2031 | .aarch64 => 6 * @sizeOf(u32), |
| 2044 | else => unreachable, | 2032 | else => unreachable, |
| ... | @@ -2187,7 +2175,7 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -2187,7 +2175,7 @@ fn populateMetadata(self: *Zld) !void { |
| 2187 | try self.load_commands.append(self.allocator, .{ .Dylinker = dylinker_cmd }); | 2175 | try self.load_commands.append(self.allocator, .{ .Dylinker = dylinker_cmd }); |
| 2188 | } | 2176 | } |
| 2189 | | 2177 | |
| 2190 | if (self.main_cmd_index == null) { | 2178 | if (self.main_cmd_index == null and self.output.?.tag == .exe) { |
| 2191 | self.main_cmd_index = @intCast(u16, self.load_commands.items.len); | 2179 | self.main_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2192 | try self.load_commands.append(self.allocator, .{ | 2180 | try self.load_commands.append(self.allocator, .{ |
| 2193 | .Main = .{ | 2181 | .Main = .{ |
| ... | @@ -2199,6 +2187,41 @@ fn populateMetadata(self: *Zld) !void { | ... | @@ -2199,6 +2187,41 @@ fn populateMetadata(self: *Zld) !void { |
| 2199 | }); | 2187 | }); |
| 2200 | } | 2188 | } |
| 2201 | | 2189 | |
| | 2190 | if (self.dylib_id_cmd_index == null and self.output.?.tag == .dylib) { |
| | 2191 | self.dylib_id_cmd_index = @intCast(u16, self.load_commands.items.len); |
| | 2192 | var dylib_cmd = try createLoadDylibCommand( |
| | 2193 | self.allocator, |
| | 2194 | self.output.?.install_name.?, |
| | 2195 | 2, |
| | 2196 | 0x10000, // TODO forward user-provided versions |
| | 2197 | 0x10000, |
| | 2198 | ); |
| | 2199 | errdefer dylib_cmd.deinit(self.allocator); |
| | 2200 | dylib_cmd.inner.cmd = macho.LC_ID_DYLIB; |
| | 2201 | try self.load_commands.append(self.allocator, .{ .Dylib = dylib_cmd }); |
| | 2202 | } |
| | 2203 | |
| | 2204 | if (self.version_min_cmd_index == null) { |
| | 2205 | self.version_min_cmd_index = @intCast(u16, self.load_commands.items.len); |
| | 2206 | const cmd: u32 = switch (self.target.?.os.tag) { |
| | 2207 | .macos => macho.LC_VERSION_MIN_MACOSX, |
| | 2208 | .ios => macho.LC_VERSION_MIN_IPHONEOS, |
| | 2209 | .tvos => macho.LC_VERSION_MIN_TVOS, |
| | 2210 | .watchos => macho.LC_VERSION_MIN_WATCHOS, |
| | 2211 | else => unreachable, // wrong OS |
| | 2212 | }; |
| | 2213 | const ver = self.target.?.os.version_range.semver.min; |
| | 2214 | const version = ver.major << 16 | ver.minor << 8 | ver.patch; |
| | 2215 | try self.load_commands.append(self.allocator, .{ |
| | 2216 | .VersionMin = .{ |
| | 2217 | .cmd = cmd, |
| | 2218 | .cmdsize = @sizeOf(macho.version_min_command), |
| | 2219 | .version = version, |
| | 2220 | .sdk = version, |
| | 2221 | }, |
| | 2222 | }); |
| | 2223 | } |
| | 2224 | |
| 2202 | if (self.source_version_cmd_index == null) { | 2225 | if (self.source_version_cmd_index == null) { |
| 2203 | self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len); | 2226 | self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2204 | try self.load_commands.append(self.allocator, .{ | 2227 | try self.load_commands.append(self.allocator, .{ |
| ... | @@ -2237,7 +2260,7 @@ fn addDataInCodeLC(self: *Zld) !void { | ... | @@ -2237,7 +2260,7 @@ fn addDataInCodeLC(self: *Zld) !void { |
| 2237 | } | 2260 | } |
| 2238 | | 2261 | |
| 2239 | fn addCodeSignatureLC(self: *Zld) !void { | 2262 | fn addCodeSignatureLC(self: *Zld) !void { |
| 2240 | if (self.code_signature_cmd_index == null and self.arch.? == .aarch64) { | 2263 | if (self.code_signature_cmd_index == null and self.target.?.cpu.arch == .aarch64) { |
| 2241 | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); | 2264 | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2242 | try self.load_commands.append(self.allocator, .{ | 2265 | try self.load_commands.append(self.allocator, .{ |
| 2243 | .LinkeditData = .{ | 2266 | .LinkeditData = .{ |
| ... | @@ -2355,19 +2378,20 @@ fn flush(self: *Zld) !void { | ... | @@ -2355,19 +2378,20 @@ fn flush(self: *Zld) !void { |
| 2355 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); | 2378 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); |
| 2356 | } | 2379 | } |
| 2357 | | 2380 | |
| 2358 | if (self.arch.? == .aarch64) { | 2381 | if (self.target.?.cpu.arch == .aarch64) { |
| 2359 | try self.writeCodeSignaturePadding(); | 2382 | try self.writeCodeSignaturePadding(); |
| 2360 | } | 2383 | } |
| 2361 | | 2384 | |
| 2362 | try self.writeLoadCommands(); | 2385 | try self.writeLoadCommands(); |
| 2363 | try self.writeHeader(); | 2386 | try self.writeHeader(); |
| 2364 | | 2387 | |
| 2365 | if (self.arch.? == .aarch64) { | 2388 | if (self.target.?.cpu.arch == .aarch64) { |
| 2366 | try self.writeCodeSignature(); | 2389 | try self.writeCodeSignature(); |
| 2367 | } | 2390 | } |
| 2368 | | 2391 | |
| 2369 | if (comptime std.Target.current.isDarwin() and std.Target.current.cpu.arch == .aarch64) { | 2392 | if (comptime std.Target.current.isDarwin() and std.Target.current.cpu.arch == .aarch64) { |
| 2370 | try fs.cwd().copyFile(self.out_path.?, fs.cwd(), self.out_path.?, .{}); | 2393 | const out_path = self.output.?.path; |
| | 2394 | try fs.cwd().copyFile(out_path, fs.cwd(), out_path, .{}); |
| 2371 | } | 2395 | } |
| 2372 | } | 2396 | } |
| 2373 | | 2397 | |
| ... | @@ -2392,6 +2416,8 @@ fn writeGotEntries(self: *Zld) !void { | ... | @@ -2392,6 +2416,8 @@ fn writeGotEntries(self: *Zld) !void { |
| 2392 | } | 2416 | } |
| 2393 | | 2417 | |
| 2394 | fn setEntryPoint(self: *Zld) !void { | 2418 | fn setEntryPoint(self: *Zld) !void { |
| | 2419 | if (self.output.?.tag != .exe) return; |
| | 2420 | |
| 2395 | // TODO we should respect the -entry flag passed in by the user to set a custom | 2421 | // TODO we should respect the -entry flag passed in by the user to set a custom |
| 2396 | // entrypoint. For now, assume default of `_main`. | 2422 | // entrypoint. For now, assume default of `_main`. |
| 2397 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 2423 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| ... | @@ -2636,12 +2662,12 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void { | ... | @@ -2636,12 +2662,12 @@ fn populateLazyBindOffsetsInStubHelper(self: *Zld, buffer: []const u8) !void { |
| 2636 | } | 2662 | } |
| 2637 | assert(self.stubs.items.len <= offsets.items.len); | 2663 | assert(self.stubs.items.len <= offsets.items.len); |
| 2638 | | 2664 | |
| 2639 | const stub_size: u4 = switch (self.arch.?) { | 2665 | const stub_size: u4 = switch (self.target.?.cpu.arch) { |
| 2640 | .x86_64 => 10, | 2666 | .x86_64 => 10, |
| 2641 | .aarch64 => 3 * @sizeOf(u32), | 2667 | .aarch64 => 3 * @sizeOf(u32), |
| 2642 | else => unreachable, | 2668 | else => unreachable, |
| 2643 | }; | 2669 | }; |
| 2644 | const off: u4 = switch (self.arch.?) { | 2670 | const off: u4 = switch (self.target.?.cpu.arch) { |
| 2645 | .x86_64 => 1, | 2671 | .x86_64 => 1, |
| 2646 | .aarch64 => 2 * @sizeOf(u32), | 2672 | .aarch64 => 2 * @sizeOf(u32), |
| 2647 | else => unreachable, | 2673 | else => unreachable, |
| ... | @@ -2998,7 +3024,7 @@ fn writeStringTable(self: *Zld) !void { | ... | @@ -2998,7 +3024,7 @@ fn writeStringTable(self: *Zld) !void { |
| 2998 | | 3024 | |
| 2999 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); | 3025 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); |
| 3000 | | 3026 | |
| 3001 | if (symtab.strsize > self.strtab.items.len and self.arch.? == .x86_64) { | 3027 | if (symtab.strsize > self.strtab.items.len and self.target.?.cpu.arch == .x86_64) { |
| 3002 | // This is the last section, so we need to pad it out. | 3028 | // This is the last section, so we need to pad it out. |
| 3003 | try self.file.?.pwriteAll(&[_]u8{0}, seg.inner.fileoff + seg.inner.filesize - 1); | 3029 | try self.file.?.pwriteAll(&[_]u8{0}, seg.inner.fileoff + seg.inner.filesize - 1); |
| 3004 | } | 3030 | } |
| ... | @@ -3046,7 +3072,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { | ... | @@ -3046,7 +3072,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { |
| 3046 | const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData; | 3072 | const code_sig_cmd = &self.load_commands.items[self.code_signature_cmd_index.?].LinkeditData; |
| 3047 | const fileoff = seg.inner.fileoff + seg.inner.filesize; | 3073 | const fileoff = seg.inner.fileoff + seg.inner.filesize; |
| 3048 | const needed_size = CodeSignature.calcCodeSignaturePaddingSize( | 3074 | const needed_size = CodeSignature.calcCodeSignaturePaddingSize( |
| 3049 | self.out_path.?, | 3075 | self.output.?.path, |
| 3050 | fileoff, | 3076 | fileoff, |
| 3051 | self.page_size.?, | 3077 | self.page_size.?, |
| 3052 | ); | 3078 | ); |
| ... | @@ -3072,7 +3098,7 @@ fn writeCodeSignature(self: *Zld) !void { | ... | @@ -3072,7 +3098,7 @@ fn writeCodeSignature(self: *Zld) !void { |
| 3072 | defer code_sig.deinit(); | 3098 | defer code_sig.deinit(); |
| 3073 | try code_sig.calcAdhocSignature( | 3099 | try code_sig.calcAdhocSignature( |
| 3074 | self.file.?, | 3100 | self.file.?, |
| 3075 | self.out_path.?, | 3101 | self.output.?.path, |
| 3076 | text_seg.inner, | 3102 | text_seg.inner, |
| 3077 | code_sig_cmd, | 3103 | code_sig_cmd, |
| 3078 | .Exe, | 3104 | .Exe, |
| ... | @@ -3114,7 +3140,7 @@ fn writeHeader(self: *Zld) !void { | ... | @@ -3114,7 +3140,7 @@ fn writeHeader(self: *Zld) !void { |
| 3114 | cpu_subtype: macho.cpu_subtype_t, | 3140 | cpu_subtype: macho.cpu_subtype_t, |
| 3115 | }; | 3141 | }; |
| 3116 | | 3142 | |
| 3117 | const cpu_info: CpuInfo = switch (self.arch.?) { | 3143 | const cpu_info: CpuInfo = switch (self.target.?.cpu.arch) { |
| 3118 | .aarch64 => .{ | 3144 | .aarch64 => .{ |
| 3119 | .cpu_type = macho.CPU_TYPE_ARM64, | 3145 | .cpu_type = macho.CPU_TYPE_ARM64, |
| 3120 | .cpu_subtype = macho.CPU_SUBTYPE_ARM_ALL, | 3146 | .cpu_subtype = macho.CPU_SUBTYPE_ARM_ALL, |
| ... | @@ -3127,8 +3153,22 @@ fn writeHeader(self: *Zld) !void { | ... | @@ -3127,8 +3153,22 @@ fn writeHeader(self: *Zld) !void { |
| 3127 | }; | 3153 | }; |
| 3128 | header.cputype = cpu_info.cpu_type; | 3154 | header.cputype = cpu_info.cpu_type; |
| 3129 | header.cpusubtype = cpu_info.cpu_subtype; | 3155 | header.cpusubtype = cpu_info.cpu_subtype; |
| 3130 | header.filetype = macho.MH_EXECUTE; | 3156 | |
| 3131 | header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; | 3157 | switch (self.output.?.tag) { |
| | 3158 | .exe => { |
| | 3159 | header.filetype = macho.MH_EXECUTE; |
| | 3160 | header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; |
| | 3161 | }, |
| | 3162 | .dylib => { |
| | 3163 | header.filetype = macho.MH_DYLIB; |
| | 3164 | header.flags = macho.MH_NOUNDEFS | |
| | 3165 | macho.MH_DYLDLINK | |
| | 3166 | macho.MH_PIE | |
| | 3167 | macho.MH_TWOLEVEL | |
| | 3168 | macho.MH_NO_REEXPORTED_DYLIBS; |
| | 3169 | }, |
| | 3170 | } |
| | 3171 | |
| 3132 | header.reserved = 0; | 3172 | header.reserved = 0; |
| 3133 | | 3173 | |
| 3134 | if (self.tlv_section_index) |_| | 3174 | if (self.tlv_section_index) |_| |