authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-11 22:10:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:19-07:00
log5a6a1f8a8ad1475d328c998824981c7b310987d2
tree757e2d9bbf14e8ee96b8a2911d6a713dc95c3ff9
parent98da660e453789f578c04e641286bdf8ff84bcd4

linker: update target references


19 files changed, 274 insertions(+), 191 deletions(-)

src/arch/wasm/Emit.zig+2-1
...@@ -406,7 +406,8 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -406,7 +406,8 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
406 const extra_index = emit.mir.instructions.items(.data)[inst].payload;406 const extra_index = emit.mir.instructions.items(.data)[inst].payload;
407 const mem = emit.mir.extraData(Mir.Memory, extra_index).data;407 const mem = emit.mir.extraData(Mir.Memory, extra_index).data;
408 const mem_offset = emit.offset() + 1;408 const mem_offset = emit.offset() + 1;
409 const is_wasm32 = emit.bin_file.base.options.target.cpu.arch == .wasm32;409 const target = emit.bin_file.comp.root_mod.resolved_target.result;
410 const is_wasm32 = target.cpu.arch == .wasm32;
410 if (is_wasm32) {411 if (is_wasm32) {
411 try emit.code.append(std.wasm.opcode(.i32_const));412 try emit.code.append(std.wasm.opcode(.i32_const));
412 var buf: [5]u8 = undefined;413 var buf: [5]u8 = undefined;
src/link/Coff.zig+7-4
...@@ -1467,6 +1467,7 @@ pub fn updateExports(...@@ -1467,6 +1467,7 @@ pub fn updateExports(
1467 }1467 }
14681468
1469 const ip = &mod.intern_pool;1469 const ip = &mod.intern_pool;
1470 const target = self.base.comp.root_mod.resolved_target.result;
14701471
1471 if (self.base.options.use_llvm) {1472 if (self.base.options.use_llvm) {
1472 // Even in the case of LLVM, we need to notice certain exported symbols in order to1473 // Even in the case of LLVM, we need to notice certain exported symbols in order to
...@@ -1478,7 +1479,7 @@ pub fn updateExports(...@@ -1478,7 +1479,7 @@ pub fn updateExports(
1478 };1479 };
1479 const exported_decl = mod.declPtr(exported_decl_index);1480 const exported_decl = mod.declPtr(exported_decl_index);
1480 if (exported_decl.getOwnedFunction(mod) == null) continue;1481 if (exported_decl.getOwnedFunction(mod) == null) continue;
1481 const winapi_cc = switch (self.base.options.target.cpu.arch) {1482 const winapi_cc = switch (target.cpu.arch) {
1482 .x86 => std.builtin.CallingConvention.Stdcall,1483 .x86 => std.builtin.CallingConvention.Stdcall,
1483 else => std.builtin.CallingConvention.C,1484 else => std.builtin.CallingConvention.C,
1484 };1485 };
...@@ -1487,7 +1488,7 @@ pub fn updateExports(...@@ -1487,7 +1488,7 @@ pub fn updateExports(
1487 self.base.options.link_libc)1488 self.base.options.link_libc)
1488 {1489 {
1489 mod.stage1_flags.have_c_main = true;1490 mod.stage1_flags.have_c_main = true;
1490 } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {1491 } else if (decl_cc == winapi_cc and target.os.tag == .windows) {
1491 if (ip.stringEqlSlice(exp.opts.name, "WinMain")) {1492 if (ip.stringEqlSlice(exp.opts.name, "WinMain")) {
1492 mod.stage1_flags.have_winmain = true;1493 mod.stage1_flags.have_winmain = true;
1493 } else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) {1494 } else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) {
...@@ -2200,6 +2201,7 @@ fn writeDataDirectoriesHeaders(self: *Coff) !void {...@@ -2200,6 +2201,7 @@ fn writeDataDirectoriesHeaders(self: *Coff) !void {
2200}2201}
22012202
2202fn writeHeader(self: *Coff) !void {2203fn writeHeader(self: *Coff) !void {
2204 const target = self.base.comp.root_mod.resolved_target.result;
2203 const gpa = self.base.comp.gpa;2205 const gpa = self.base.comp.gpa;
2204 var buffer = std.ArrayList(u8).init(gpa);2206 var buffer = std.ArrayList(u8).init(gpa);
2205 defer buffer.deinit();2207 defer buffer.deinit();
...@@ -2225,7 +2227,7 @@ fn writeHeader(self: *Coff) !void {...@@ -2225,7 +2227,7 @@ fn writeHeader(self: *Coff) !void {
2225 const timestamp = std.time.timestamp();2227 const timestamp = std.time.timestamp();
2226 const size_of_optional_header = @as(u16, @intCast(self.getOptionalHeaderSize() + self.getDataDirectoryHeadersSize()));2228 const size_of_optional_header = @as(u16, @intCast(self.getOptionalHeaderSize() + self.getDataDirectoryHeadersSize()));
2227 var coff_header = coff.CoffHeader{2229 var coff_header = coff.CoffHeader{
2228 .machine = coff.MachineType.fromTargetCpuArch(self.base.options.target.cpu.arch),2230 .machine = coff.MachineType.fromTargetCpuArch(target.cpu.arch),
2229 .number_of_sections = @as(u16, @intCast(self.sections.slice().len)), // TODO what if we prune a section2231 .number_of_sections = @as(u16, @intCast(self.sections.slice().len)), // TODO what if we prune a section
2230 .time_date_stamp = @as(u32, @truncate(@as(u64, @bitCast(timestamp)))),2232 .time_date_stamp = @as(u32, @truncate(@as(u64, @bitCast(timestamp)))),
2231 .pointer_to_symbol_table = self.strtab_offset orelse 0,2233 .pointer_to_symbol_table = self.strtab_offset orelse 0,
...@@ -2451,8 +2453,9 @@ pub fn getEntryPoint(self: Coff) ?SymbolWithLoc {...@@ -2451,8 +2453,9 @@ pub fn getEntryPoint(self: Coff) ?SymbolWithLoc {
2451}2453}
24522454
2453pub fn getImageBase(self: Coff) u64 {2455pub fn getImageBase(self: Coff) u64 {
2456 const target = self.base.comp.root_mod.resolved_target.result;
2454 const image_base: u64 = self.base.options.image_base_override orelse switch (self.base.comp.config.output_mode) {2457 const image_base: u64 = self.base.options.image_base_override orelse switch (self.base.comp.config.output_mode) {
2455 .Exe => switch (self.base.options.target.cpu.arch) {2458 .Exe => switch (target.cpu.arch) {
2456 .aarch64 => @as(u64, 0x140000000),2459 .aarch64 => @as(u64, 0x140000000),
2457 .x86_64, .x86 => 0x400000,2460 .x86_64, .x86 => 0x400000,
2458 else => unreachable, // unsupported target architecture2461 else => unreachable, // unsupported target architecture
src/link/Coff/Relocation.zig+2-1
...@@ -107,7 +107,8 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base:...@@ -107,7 +107,8 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base:
107 .ptr_width = coff_file.ptr_width,107 .ptr_width = coff_file.ptr_width,
108 };108 };
109109
110 switch (coff_file.base.options.target.cpu.arch) {110 const target = coff_file.base.comp.root_mod.resolved_target.result;
111 switch (target.cpu.arch) {
111 .aarch64 => self.resolveAarch64(ctx),112 .aarch64 => self.resolveAarch64(ctx),
112 .x86, .x86_64 => self.resolveX86(ctx),113 .x86, .x86_64 => self.resolveX86(ctx),
113 else => unreachable, // unhandled target architecture114 else => unreachable, // unhandled target architecture
src/link/Coff/lld.zig+1-1
...@@ -49,7 +49,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -49,7 +49,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
49 const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib;49 const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib;
50 const is_exe_or_dyn_lib = is_dyn_lib or self.base.comp.config.output_mode == .Exe;50 const is_exe_or_dyn_lib = is_dyn_lib or self.base.comp.config.output_mode == .Exe;
51 const link_in_crt = self.base.options.link_libc and is_exe_or_dyn_lib;51 const link_in_crt = self.base.options.link_libc and is_exe_or_dyn_lib;
52 const target = self.base.options.target;52 const target = self.base.comp.root_mod.resolved_target.result;
53 const optimize_mode = self.base.comp.root_mod.optimize_mode;53 const optimize_mode = self.base.comp.root_mod.optimize_mode;
5454
55 // See link/Elf.zig for comments on how this mechanism works.55 // See link/Elf.zig for comments on how this mechanism works.
src/link/Elf/Object.zig+2-1
...@@ -54,7 +54,8 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {...@@ -54,7 +54,8 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
5454
55 self.header = try reader.readStruct(elf.Elf64_Ehdr);55 self.header = try reader.readStruct(elf.Elf64_Ehdr);
5656
57 if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {57 const target = elf_file.base.comp.root_mod.resolved_target.result;
58 if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
58 try elf_file.reportParseError2(59 try elf_file.reportParseError2(
59 self.index,60 self.index,
60 "invalid cpu architecture: {s}",61 "invalid cpu architecture: {s}",
src/link/Elf/SharedObject.zig+2-1
...@@ -53,7 +53,8 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {...@@ -53,7 +53,8 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {
5353
54 self.header = try reader.readStruct(elf.Elf64_Ehdr);54 self.header = try reader.readStruct(elf.Elf64_Ehdr);
5555
56 if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {56 const target = elf_file.base.comp.root_mod.resolved_target.result;
57 if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
57 try elf_file.reportParseError2(58 try elf_file.reportParseError2(
58 self.index,59 self.index,
59 "invalid cpu architecture: {s}",60 "invalid cpu architecture: {s}",
src/link/Elf/synthetic_sections.zig+4-2
...@@ -287,7 +287,8 @@ pub const ZigGotSection = struct {...@@ -287,7 +287,8 @@ pub const ZigGotSection = struct {
287 zig_got.flags.dirty = false;287 zig_got.flags.dirty = false;
288 }288 }
289 const entry_size: u16 = elf_file.archPtrWidthBytes();289 const entry_size: u16 = elf_file.archPtrWidthBytes();
290 const endian = elf_file.base.options.target.cpu.arch.endian();290 const target = elf_file.base.comp.root_mod.resolved_target.result;
291 const endian = target.cpu.arch.endian();
291 const off = zig_got.entryOffset(index, elf_file);292 const off = zig_got.entryOffset(index, elf_file);
292 const vaddr = zig_got.entryAddress(index, elf_file);293 const vaddr = zig_got.entryAddress(index, elf_file);
293 const entry = zig_got.entries.items[index];294 const entry = zig_got.entries.items[index];
...@@ -1575,7 +1576,8 @@ pub const ComdatGroupSection = struct {...@@ -1575,7 +1576,8 @@ pub const ComdatGroupSection = struct {
15751576
1576fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {1577fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {
1577 const entry_size = elf_file.archPtrWidthBytes();1578 const entry_size = elf_file.archPtrWidthBytes();
1578 const endian = elf_file.base.options.target.cpu.arch.endian();1579 const target = elf_file.base.comp.root_mod.resolved_target.result;
1580 const endian = target.cpu.arch.endian();
1579 switch (entry_size) {1581 switch (entry_size) {
1580 2 => try writer.writeInt(u16, @intCast(value), endian),1582 2 => try writer.writeInt(u16, @intCast(value), endian),
1581 4 => try writer.writeInt(u32, @intCast(value), endian),1583 4 => try writer.writeInt(u32, @intCast(value), endian),
src/link/MachO.zig+78-48
...@@ -143,7 +143,7 @@ tlv_table: TlvSymbolTable = .{},...@@ -143,7 +143,7 @@ tlv_table: TlvSymbolTable = .{},
143/// Hot-code swapping state.143/// Hot-code swapping state.
144hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},144hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},
145145
146darwin_sdk_layout: ?SdkLayout,146sdk_layout: ?SdkLayout,
147/// Size of the __PAGEZERO segment.147/// Size of the __PAGEZERO segment.
148pagezero_vmsize: u64,148pagezero_vmsize: u64,
149/// Minimum space for future expansion of the load commands.149/// Minimum space for future expansion of the load commands.
...@@ -184,20 +184,21 @@ pub const SdkLayout = enum {...@@ -184,20 +184,21 @@ pub const SdkLayout = enum {
184184
185pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {185pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {
186 if (build_options.only_c) unreachable;186 if (build_options.only_c) unreachable;
187 const target = options.comp.root_mod.resolved_target.result;187 const comp = options.comp;
188 const use_lld = build_options.have_llvm and options.comp.config.use_lld;188 const target = comp.root_mod.resolved_target.result;
189 const use_llvm = options.comp.config.use_llvm;189 const use_lld = build_options.have_llvm and comp.config.use_lld;
190 const use_llvm = comp.config.use_llvm;
190 assert(target.ofmt == .macho);191 assert(target.ofmt == .macho);
191192
192 const gpa = options.comp.gpa;193 const gpa = comp.gpa;
193 const emit = options.emit;194 const emit = options.emit;
194 const mode: Mode = mode: {195 const mode: Mode = mode: {
195 if (use_llvm or options.module == null or options.cache_mode == .whole)196 if (use_llvm or comp.module == null or comp.cache_mode == .whole)
196 break :mode .zld;197 break :mode .zld;
197 break :mode .incremental;198 break :mode .incremental;
198 };199 };
199 const sub_path = if (mode == .zld) blk: {200 const sub_path = if (mode == .zld) blk: {
200 if (options.module == null) {201 if (comp.module == null) {
201 // No point in opening a file, we would not write anything to it.202 // No point in opening a file, we would not write anything to it.
202 // Initialize with empty.203 // Initialize with empty.
203 return createEmpty(arena, options);204 return createEmpty(arena, options);
...@@ -225,13 +226,13 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {...@@ -225,13 +226,13 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {
225 .read = true,226 .read = true,
226 .mode = link.File.determineMode(227 .mode = link.File.determineMode(
227 use_lld,228 use_lld,
228 options.comp.config.output_mode,229 comp.config.output_mode,
229 options.comp.config.link_mode,230 comp.config.link_mode,
230 ),231 ),
231 });232 });
232 self.base.file = file;233 self.base.file = file;
233234
234 if (!options.strip and options.module != null) {235 if (self.base.debug_format != .strip and comp.module != null) {
235 // Create dSYM bundle.236 // Create dSYM bundle.
236 log.debug("creating {s}.dSYM bundle", .{sub_path});237 log.debug("creating {s}.dSYM bundle", .{sub_path});
237238
...@@ -276,14 +277,15 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {...@@ -276,14 +277,15 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {
276}277}
277278
278pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {279pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {
279 const self = try arena.create(MachO);280 const comp = options.comp;
280 const optimize_mode = options.comp.root_mod.optimize_mode;281 const optimize_mode = comp.root_mod.optimize_mode;
281 const use_llvm = options.comp.config.use_llvm;282 const use_llvm = comp.config.use_llvm;
282283
284 const self = try arena.create(MachO);
283 self.* = .{285 self.* = .{
284 .base = .{286 .base = .{
285 .tag = .macho,287 .tag = .macho,
286 .comp = options.comp,288 .comp = comp,
287 .emit = options.emit,289 .emit = options.emit,
288 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),290 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
289 .stack_size = options.stack_size orelse 16777216,291 .stack_size = options.stack_size orelse 16777216,
...@@ -297,7 +299,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {...@@ -297,7 +299,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {
297 .function_sections = options.function_sections,299 .function_sections = options.function_sections,
298 .data_sections = options.data_sections,300 .data_sections = options.data_sections,
299 },301 },
300 .mode = if (use_llvm or options.module == null or options.cache_mode == .whole)302 .mode = if (use_llvm or comp.module == null or comp.cache_mode == .whole)
301 .zld303 .zld
302 else304 else
303 .incremental,305 .incremental,
...@@ -305,9 +307,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {...@@ -305,9 +307,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {
305 .headerpad_size = options.headerpad_size orelse default_headerpad_size,307 .headerpad_size = options.headerpad_size orelse default_headerpad_size,
306 .headerpad_max_install_names = options.headerpad_max_install_names,308 .headerpad_max_install_names = options.headerpad_max_install_names,
307 .dead_strip_dylibs = options.dead_strip_dylibs,309 .dead_strip_dylibs = options.dead_strip_dylibs,
310 .sdk_layout = options.darwin_sdk_layout,
311 .frameworks = options.frameworks,
312 .install_name = options.install_name,
313 .entitlements = options.entitlements,
308 };314 };
309315
310 if (use_llvm and options.module != null) {316 if (use_llvm and comp.module != null) {
311 self.llvm_object = try LlvmObject.create(arena, options);317 self.llvm_object = try LlvmObject.create(arena, options);
312 }318 }
313319
...@@ -357,6 +363,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -357,6 +363,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
357363
358 const output_mode = self.base.comp.config.output_mode;364 const output_mode = self.base.comp.config.output_mode;
359 const module = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;365 const module = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
366 const target = self.base.comp.root_mod.resolved_target.result;
360367
361 if (self.lazy_syms.getPtr(.none)) |metadata| {368 if (self.lazy_syms.getPtr(.none)) |metadata| {
362 // Most lazy symbols can be updated on first use, but369 // Most lazy symbols can be updated on first use, but
...@@ -569,7 +576,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -569,7 +576,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
569 // written out to the file.576 // written out to the file.
570 // The most important here is to have the correct vm and filesize of the __LINKEDIT segment577 // The most important here is to have the correct vm and filesize of the __LINKEDIT segment
571 // where the code signature goes into.578 // where the code signature goes into.
572 var codesig = CodeSignature.init(getPageSize(self.base.options.target.cpu.arch));579 var codesig = CodeSignature.init(getPageSize(target.cpu.arch));
573 codesig.code_directory.ident = self.base.emit.sub_path;580 codesig.code_directory.ident = self.base.emit.sub_path;
574 if (self.entitlements) |path| {581 if (self.entitlements) |path| {
575 try codesig.addEntitlements(gpa, path);582 try codesig.addEntitlements(gpa, path);
...@@ -619,7 +626,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -619,7 +626,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
619 .version = 0,626 .version = 0,
620 });627 });
621 {628 {
622 const platform = Platform.fromTarget(self.base.options.target);629 const platform = Platform.fromTarget(target);
623 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);630 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
624 if (platform.isBuildVersionCompatible()) {631 if (platform.isBuildVersionCompatible()) {
625 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);632 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
...@@ -701,7 +708,7 @@ pub fn resolveLibSystem(...@@ -701,7 +708,7 @@ pub fn resolveLibSystem(
701 var checked_paths = std.ArrayList([]const u8).init(arena);708 var checked_paths = std.ArrayList([]const u8).init(arena);
702709
703 success: {710 success: {
704 if (self.base.options.darwin_sdk_layout) |sdk_layout| switch (sdk_layout) {711 if (self.sdk_layout) |sdk_layout| switch (sdk_layout) {
705 .sdk => {712 .sdk => {
706 const dir = try fs.path.join(arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" });713 const dir = try fs.path.join(arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" });
707 if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success;714 if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
...@@ -817,6 +824,7 @@ fn parseObject(...@@ -817,6 +824,7 @@ fn parseObject(
817 defer tracy.end();824 defer tracy.end();
818825
819 const gpa = self.base.comp.gpa;826 const gpa = self.base.comp.gpa;
827 const target = self.base.comp.root_mod.resolved_target.result;
820 const mtime: u64 = mtime: {828 const mtime: u64 = mtime: {
821 const stat = file.stat() catch break :mtime 0;829 const stat = file.stat() catch break :mtime 0;
822 break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000)));830 break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000)));
...@@ -839,8 +847,8 @@ fn parseObject(...@@ -839,8 +847,8 @@ fn parseObject(
839 else => unreachable,847 else => unreachable,
840 };848 };
841 const detected_platform = object.getPlatform();849 const detected_platform = object.getPlatform();
842 const this_cpu_arch = self.base.options.target.cpu.arch;850 const this_cpu_arch = target.cpu.arch;
843 const this_platform = Platform.fromTarget(self.base.options.target);851 const this_platform = Platform.fromTarget(target);
844852
845 if (this_cpu_arch != detected_cpu_arch or853 if (this_cpu_arch != detected_cpu_arch or
846 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))854 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
...@@ -867,8 +875,10 @@ pub fn parseLibrary(...@@ -867,8 +875,10 @@ pub fn parseLibrary(
867 const tracy = trace(@src());875 const tracy = trace(@src());
868 defer tracy.end();876 defer tracy.end();
869877
878 const target = self.base.comp.root_mod.resolved_target.result;
879
870 if (fat.isFatLibrary(file)) {880 if (fat.isFatLibrary(file)) {
871 const offset = try self.parseFatLibrary(file, self.base.options.target.cpu.arch, ctx);881 const offset = try self.parseFatLibrary(file, target.cpu.arch, ctx);
872 try file.seekTo(offset);882 try file.seekTo(offset);
873883
874 if (Archive.isArchive(file, offset)) {884 if (Archive.isArchive(file, offset)) {
...@@ -934,6 +944,7 @@ fn parseArchive(...@@ -934,6 +944,7 @@ fn parseArchive(
934 ctx: *ParseErrorCtx,944 ctx: *ParseErrorCtx,
935) ParseError!void {945) ParseError!void {
936 const gpa = self.base.comp.gpa;946 const gpa = self.base.comp.gpa;
947 const target = self.base.comp.root_mod.resolved_target.result;
937948
938 // We take ownership of the file so that we can store it for the duration of symbol resolution.949 // We take ownership of the file so that we can store it for the duration of symbol resolution.
939 // TODO we shouldn't need to do that and could pre-parse the archive like we do for zld/ELF?950 // TODO we shouldn't need to do that and could pre-parse the archive like we do for zld/ELF?
...@@ -963,8 +974,8 @@ fn parseArchive(...@@ -963,8 +974,8 @@ fn parseArchive(
963 else => unreachable,974 else => unreachable,
964 };975 };
965 const detected_platform = object.getPlatform();976 const detected_platform = object.getPlatform();
966 const this_cpu_arch = self.base.options.target.cpu.arch;977 const this_cpu_arch = target.cpu.arch;
967 const this_platform = Platform.fromTarget(self.base.options.target);978 const this_platform = Platform.fromTarget(target);
968979
969 if (this_cpu_arch != detected_cpu_arch or980 if (this_cpu_arch != detected_cpu_arch or
970 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))981 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
...@@ -1015,6 +1026,7 @@ fn parseDylib(...@@ -1015,6 +1026,7 @@ fn parseDylib(
1015 ctx: *ParseErrorCtx,1026 ctx: *ParseErrorCtx,
1016) ParseError!void {1027) ParseError!void {
1017 const gpa = self.base.comp.gpa;1028 const gpa = self.base.comp.gpa;
1029 const target = self.base.comp.root_mod.resolved_target.result;
1018 const file_stat = try file.stat();1030 const file_stat = try file.stat();
1019 const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow;1031 const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow;
10201032
...@@ -1038,8 +1050,8 @@ fn parseDylib(...@@ -1038,8 +1050,8 @@ fn parseDylib(
1038 else => unreachable,1050 else => unreachable,
1039 };1051 };
1040 const detected_platform = dylib.getPlatform(contents);1052 const detected_platform = dylib.getPlatform(contents);
1041 const this_cpu_arch = self.base.options.target.cpu.arch;1053 const this_cpu_arch = target.cpu.arch;
1042 const this_platform = Platform.fromTarget(self.base.options.target);1054 const this_platform = Platform.fromTarget(target);
10431055
1044 if (this_cpu_arch != detected_cpu_arch or1056 if (this_cpu_arch != detected_cpu_arch or
1045 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))1057 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
...@@ -1061,6 +1073,8 @@ fn parseLibStub(...@@ -1061,6 +1073,8 @@ fn parseLibStub(
1061 ctx: *ParseErrorCtx,1073 ctx: *ParseErrorCtx,
1062) ParseError!void {1074) ParseError!void {
1063 const gpa = self.base.comp.gpa;1075 const gpa = self.base.comp.gpa;
1076 const target = self.base.comp.root_mod.resolved_target.result;
1077
1064 var lib_stub = try LibStub.loadFromFile(gpa, file);1078 var lib_stub = try LibStub.loadFromFile(gpa, file);
1065 defer lib_stub.deinit();1079 defer lib_stub.deinit();
10661080
...@@ -1068,7 +1082,7 @@ fn parseLibStub(...@@ -1068,7 +1082,7 @@ fn parseLibStub(
10681082
1069 // Verify target1083 // Verify target
1070 {1084 {
1071 var matcher = try Dylib.TargetMatcher.init(gpa, self.base.options.target);1085 var matcher = try Dylib.TargetMatcher.init(gpa, target);
1072 defer matcher.deinit();1086 defer matcher.deinit();
10731087
1074 const first_tbd = lib_stub.inner[0];1088 const first_tbd = lib_stub.inner[0];
...@@ -1091,7 +1105,7 @@ fn parseLibStub(...@@ -1091,7 +1105,7 @@ fn parseLibStub(
10911105
1092 try dylib.parseFromStub(1106 try dylib.parseFromStub(
1093 gpa,1107 gpa,
1094 self.base.options.target,1108 target,
1095 lib_stub,1109 lib_stub,
1096 @intCast(self.dylibs.items.len), // TODO defer it till later1110 @intCast(self.dylibs.items.len), // TODO defer it till later
1097 dependent_libs,1111 dependent_libs,
...@@ -1236,7 +1250,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void {...@@ -1236,7 +1250,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void {
12361250
1237fn writeToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void {1251fn writeToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void {
1238 const segment = self.segments.items[segment_index];1252 const segment = self.segments.items[segment_index];
1239 const cpu_arch = self.base.options.target.cpu.arch;1253 const target = self.base.comp.root_mod.resolved_target.result;
1254 const cpu_arch = target.cpu.arch;
1240 const nwritten = if (!segment.isWriteable())1255 const nwritten = if (!segment.isWriteable())
1241 try task.writeMemProtected(addr, code, cpu_arch)1256 try task.writeMemProtected(addr, code, cpu_arch)
1242 else1257 else
...@@ -1280,7 +1295,8 @@ fn writeStubHelperPreamble(self: *MachO) !void {...@@ -1280,7 +1295,8 @@ fn writeStubHelperPreamble(self: *MachO) !void {
1280 if (self.stub_helper_preamble_allocated) return;1295 if (self.stub_helper_preamble_allocated) return;
12811296
1282 const gpa = self.base.comp.gpa;1297 const gpa = self.base.comp.gpa;
1283 const cpu_arch = self.base.options.target.cpu.arch;1298 const target = self.base.comp.root_mod.resolved_target.result;
1299 const cpu_arch = target.cpu.arch;
1284 const size = stubs.stubHelperPreambleSize(cpu_arch);1300 const size = stubs.stubHelperPreambleSize(cpu_arch);
12851301
1286 var buf = try std.ArrayList(u8).initCapacity(gpa, size);1302 var buf = try std.ArrayList(u8).initCapacity(gpa, size);
...@@ -1306,11 +1322,12 @@ fn writeStubHelperPreamble(self: *MachO) !void {...@@ -1306,11 +1322,12 @@ fn writeStubHelperPreamble(self: *MachO) !void {
1306}1322}
13071323
1308fn writeStubTableEntry(self: *MachO, index: usize) !void {1324fn writeStubTableEntry(self: *MachO, index: usize) !void {
1325 const target = self.base.comp.root_mod.resolved_target.result;
1309 const stubs_sect_id = self.stubs_section_index.?;1326 const stubs_sect_id = self.stubs_section_index.?;
1310 const stub_helper_sect_id = self.stub_helper_section_index.?;1327 const stub_helper_sect_id = self.stub_helper_section_index.?;
1311 const laptr_sect_id = self.la_symbol_ptr_section_index.?;1328 const laptr_sect_id = self.la_symbol_ptr_section_index.?;
13121329
1313 const cpu_arch = self.base.options.target.cpu.arch;1330 const cpu_arch = target.cpu.arch;
1314 const stub_entry_size = stubs.stubSize(cpu_arch);1331 const stub_entry_size = stubs.stubSize(cpu_arch);
1315 const stub_helper_entry_size = stubs.stubHelperSize(cpu_arch);1332 const stub_helper_entry_size = stubs.stubHelperSize(cpu_arch);
1316 const stub_helper_preamble_size = stubs.stubHelperPreambleSize(cpu_arch);1333 const stub_helper_preamble_size = stubs.stubHelperPreambleSize(cpu_arch);
...@@ -2243,7 +2260,7 @@ pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {...@@ -2243,7 +2260,7 @@ pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
2243 .flags = macho.S_SYMBOL_STUBS |2260 .flags = macho.S_SYMBOL_STUBS |
2244 macho.S_ATTR_PURE_INSTRUCTIONS |2261 macho.S_ATTR_PURE_INSTRUCTIONS |
2245 macho.S_ATTR_SOME_INSTRUCTIONS,2262 macho.S_ATTR_SOME_INSTRUCTIONS,
2246 .reserved2 = stubs.stubSize(self.base.options.target.cpu.arch),2263 .reserved2 = stubs.stubSize(target.cpu.arch),
2247 });2264 });
2248 self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{2265 self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{
2249 .flags = macho.S_REGULAR |2266 .flags = macho.S_REGULAR |
...@@ -3116,7 +3133,8 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -3116,7 +3133,8 @@ fn populateMissingMetadata(self: *MachO) !void {
3116 assert(self.mode == .incremental);3133 assert(self.mode == .incremental);
31173134
3118 const gpa = self.base.comp.gpa;3135 const gpa = self.base.comp.gpa;
3119 const cpu_arch = self.base.options.target.cpu.arch;3136 const target = self.base.comp.root_mod.resolved_target.result;
3137 const cpu_arch = target.cpu.arch;
3120 const pagezero_vmsize = self.calcPagezeroSize();3138 const pagezero_vmsize = self.calcPagezeroSize();
31213139
3122 if (self.pagezero_segment_cmd_index == null) {3140 if (self.pagezero_segment_cmd_index == null) {
...@@ -3263,7 +3281,8 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -3263,7 +3281,8 @@ fn populateMissingMetadata(self: *MachO) !void {
32633281
3264fn calcPagezeroSize(self: *MachO) u64 {3282fn calcPagezeroSize(self: *MachO) u64 {
3265 const output_mode = self.base.comp.config.output_mode;3283 const output_mode = self.base.comp.config.output_mode;
3266 const page_size = getPageSize(self.base.options.target.cpu.arch);3284 const target = self.base.comp.root_mod.resolved_target.result;
3285 const page_size = getPageSize(target.cpu.arch);
3267 const aligned_pagezero_vmsize = mem.alignBackward(u64, self.pagezero_vmsize, page_size);3286 const aligned_pagezero_vmsize = mem.alignBackward(u64, self.pagezero_vmsize, page_size);
3268 if (output_mode == .Lib) return 0;3287 if (output_mode == .Lib) return 0;
3269 if (aligned_pagezero_vmsize == 0) return 0;3288 if (aligned_pagezero_vmsize == 0) return 0;
...@@ -3305,7 +3324,8 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts...@@ -3305,7 +3324,8 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
3305 reserved2: u32 = 0,3324 reserved2: u32 = 0,
3306}) !u8 {3325}) !u8 {
3307 const gpa = self.base.comp.gpa;3326 const gpa = self.base.comp.gpa;
3308 const page_size = getPageSize(self.base.options.target.cpu.arch);3327 const target = self.base.comp.root_mod.resolved_target.result;
3328 const page_size = getPageSize(target.cpu.arch);
3309 // In incremental context, we create one section per segment pairing. This way,3329 // In incremental context, we create one section per segment pairing. This way,
3310 // we can move the segment in raw file as we please.3330 // we can move the segment in raw file as we please.
3311 const segment_id = @as(u8, @intCast(self.segments.items.len));3331 const segment_id = @as(u8, @intCast(self.segments.items.len));
...@@ -3360,7 +3380,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {...@@ -3360,7 +3380,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
3360 const segment = &self.segments.items[segment_index];3380 const segment = &self.segments.items[segment_index];
3361 const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id];3381 const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id];
3362 const sect_capacity = self.allocatedSize(header.offset);3382 const sect_capacity = self.allocatedSize(header.offset);
3363 const page_size = getPageSize(self.base.options.target.cpu.arch);3383 const target = self.base.comp.root_mod.resolved_target.result;
3384 const page_size = getPageSize(target.cpu.arch);
33643385
3365 if (needed_size > sect_capacity) {3386 if (needed_size > sect_capacity) {
3366 const new_offset = self.findFreeSpace(needed_size, page_size);3387 const new_offset = self.findFreeSpace(needed_size, page_size);
...@@ -3400,7 +3421,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {...@@ -3400,7 +3421,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
3400}3421}
34013422
3402fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void {3423fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void {
3403 const page_size = getPageSize(self.base.options.target.cpu.arch);3424 const target = self.base.comp.root_mod.resolved_target.result;
3425 const page_size = getPageSize(target.cpu.arch);
3404 const header = &self.sections.items(.header)[sect_id];3426 const header = &self.sections.items(.header)[sect_id];
3405 const segment = self.getSegmentPtr(sect_id);3427 const segment = self.getSegmentPtr(sect_id);
3406 const increased_size = padToIdeal(needed_size);3428 const increased_size = padToIdeal(needed_size);
...@@ -3611,7 +3633,8 @@ pub fn writeSegmentHeaders(self: *MachO, writer: anytype) !void {...@@ -3611,7 +3633,8 @@ pub fn writeSegmentHeaders(self: *MachO, writer: anytype) !void {
3611}3633}
36123634
3613pub fn writeLinkeditSegmentData(self: *MachO) !void {3635pub fn writeLinkeditSegmentData(self: *MachO) !void {
3614 const page_size = getPageSize(self.base.options.target.cpu.arch);3636 const target = self.base.comp.root_mod.resolved_target.result;
3637 const page_size = getPageSize(target.cpu.arch);
3615 const seg = self.getLinkeditSegmentPtr();3638 const seg = self.getLinkeditSegmentPtr();
3616 seg.filesize = 0;3639 seg.filesize = 0;
3617 seg.vmsize = 0;3640 seg.vmsize = 0;
...@@ -3698,7 +3721,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {...@@ -3698,7 +3721,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
3698 }3721 }
36993722
3700 // Finally, unpack the rest.3723 // Finally, unpack the rest.
3701 const cpu_arch = self.base.options.target.cpu.arch;3724 const target = self.base.comp.root_mod.resolved_target.result;
3725 const cpu_arch = target.cpu.arch;
3702 for (self.objects.items) |*object| {3726 for (self.objects.items) |*object| {
3703 for (object.atoms.items) |atom_index| {3727 for (object.atoms.items) |atom_index| {
3704 const atom = self.getAtom(atom_index);3728 const atom = self.getAtom(atom_index);
...@@ -3744,14 +3768,14 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {...@@ -3744,14 +3768,14 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
3744 },3768 },
3745 else => unreachable,3769 else => unreachable,
3746 }3770 }
3747 const target = Atom.parseRelocTarget(self, .{3771 const reloc_target = Atom.parseRelocTarget(self, .{
3748 .object_id = atom.getFile().?,3772 .object_id = atom.getFile().?,
3749 .rel = rel,3773 .rel = rel,
3750 .code = code,3774 .code = code,
3751 .base_offset = ctx.base_offset,3775 .base_offset = ctx.base_offset,
3752 .base_addr = ctx.base_addr,3776 .base_addr = ctx.base_addr,
3753 });3777 });
3754 const target_sym = self.getSymbol(target);3778 const target_sym = self.getSymbol(reloc_target);
3755 if (target_sym.undf()) continue;3779 if (target_sym.undf()) continue;
37563780
3757 const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr));3781 const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr));
...@@ -3853,7 +3877,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {...@@ -3853,7 +3877,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
3853 }3877 }
38543878
3855 // Finally, unpack the rest.3879 // Finally, unpack the rest.
3856 const cpu_arch = self.base.options.target.cpu.arch;3880 const target = self.base.comp.root_mod.resolved_target.result;
3881 const cpu_arch = target.cpu.arch;
3857 for (self.objects.items) |*object| {3882 for (self.objects.items) |*object| {
3858 for (object.atoms.items) |atom_index| {3883 for (object.atoms.items) |atom_index| {
3859 const atom = self.getAtom(atom_index);3884 const atom = self.getAtom(atom_index);
...@@ -4072,7 +4097,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: anytype) !void {...@@ -4072,7 +4097,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: anytype) !void {
40724097
4073 const header = self.sections.items(.header)[stub_helper_section_index];4098 const header = self.sections.items(.header)[stub_helper_section_index];
40744099
4075 const cpu_arch = self.base.options.target.cpu.arch;4100 const target = self.base.comp.root_mod.resolved_target.result;
4101 const cpu_arch = target.cpu.arch;
4076 const preamble_size = stubs.stubHelperPreambleSize(cpu_arch);4102 const preamble_size = stubs.stubHelperPreambleSize(cpu_arch);
4077 const stub_size = stubs.stubHelperSize(cpu_arch);4103 const stub_size = stubs.stubHelperSize(cpu_arch);
4078 const stub_offset = stubs.stubOffsetInStubHelper(cpu_arch);4104 const stub_offset = stubs.stubOffsetInStubHelper(cpu_arch);
...@@ -4708,13 +4734,14 @@ pub fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32, h...@@ -4708,13 +4734,14 @@ pub fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32, h
4708}4734}
47094735
4710pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void {4736pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void {
4737 const target = self.base.comp.root_mod.resolved_target.result;
4711 const seg = self.getLinkeditSegmentPtr();4738 const seg = self.getLinkeditSegmentPtr();
4712 // Code signature data has to be 16-bytes aligned for Apple tools to recognize the file4739 // Code signature data has to be 16-bytes aligned for Apple tools to recognize the file
4713 // https://github.com/opensource-apple/cctools/blob/fdb4825f303fd5c0751be524babd32958181b3ed/libstuff/checkout.c#L2714740 // https://github.com/opensource-apple/cctools/blob/fdb4825f303fd5c0751be524babd32958181b3ed/libstuff/checkout.c#L271
4714 const offset = mem.alignForward(u64, seg.fileoff + seg.filesize, 16);4741 const offset = mem.alignForward(u64, seg.fileoff + seg.filesize, 16);
4715 const needed_size = code_sig.estimateSize(offset);4742 const needed_size = code_sig.estimateSize(offset);
4716 seg.filesize = offset + needed_size - seg.fileoff;4743 seg.filesize = offset + needed_size - seg.fileoff;
4717 seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(self.base.options.target.cpu.arch));4744 seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(target.cpu.arch));
4718 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ offset, offset + needed_size });4745 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ offset, offset + needed_size });
4719 // Pad out the space. We need to do this to calculate valid hashes for everything in the file4746 // Pad out the space. We need to do this to calculate valid hashes for everything in the file
4720 // except for code signature data.4747 // except for code signature data.
...@@ -4758,7 +4785,8 @@ pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {...@@ -4758,7 +4785,8 @@ pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {
4758 var header: macho.mach_header_64 = .{};4785 var header: macho.mach_header_64 = .{};
4759 header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL;4786 header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL;
47604787
4761 switch (self.base.options.target.cpu.arch) {4788 const target = self.base.comp.root_mod.resolved_target.result;
4789 switch (target.cpu.arch) {
4762 .aarch64 => {4790 .aarch64 => {
4763 header.cputype = macho.CPU_TYPE_ARM64;4791 header.cputype = macho.CPU_TYPE_ARM64;
4764 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;4792 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
...@@ -5123,9 +5151,10 @@ pub fn getTlvPtrEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {...@@ -5123,9 +5151,10 @@ pub fn getTlvPtrEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {
5123}5151}
51245152
5125pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {5153pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {
5154 const target = self.base.comp.root_mod.resolved_target.result;
5126 const index = self.stub_table.lookup.get(sym_with_loc) orelse return null;5155 const index = self.stub_table.lookup.get(sym_with_loc) orelse return null;
5127 const header = self.sections.items(.header)[self.stubs_section_index.?];5156 const header = self.sections.items(.header)[self.stubs_section_index.?];
5128 return header.addr + stubs.stubSize(self.base.options.target.cpu.arch) * index;5157 return header.addr + stubs.stubSize(target.cpu.arch) * index;
5129}5158}
51305159
5131/// Returns symbol location corresponding to the set entrypoint if any.5160/// Returns symbol location corresponding to the set entrypoint if any.
...@@ -5234,8 +5263,9 @@ pub fn handleAndReportParseError(...@@ -5234,8 +5263,9 @@ pub fn handleAndReportParseError(
5234 err: ParseError,5263 err: ParseError,
5235 ctx: *const ParseErrorCtx,5264 ctx: *const ParseErrorCtx,
5236) error{OutOfMemory}!void {5265) error{OutOfMemory}!void {
5266 const target = self.base.comp.root_mod.resolved_target.result;
5237 const gpa = self.base.comp.gpa;5267 const gpa = self.base.comp.gpa;
5238 const cpu_arch = self.base.options.target.cpu.arch;5268 const cpu_arch = target.cpu.arch;
5239 switch (err) {5269 switch (err) {
5240 error.DylibAlreadyExists => {},5270 error.DylibAlreadyExists => {},
5241 error.IncompatibleDylibVersion => {5271 error.IncompatibleDylibVersion => {
...@@ -5270,7 +5300,7 @@ pub fn handleAndReportParseError(...@@ -5270,7 +5300,7 @@ pub fn handleAndReportParseError(
5270 error.InvalidTarget => try self.reportParseError(5300 error.InvalidTarget => try self.reportParseError(
5271 path,5301 path,
5272 "invalid target: expected '{}', but found '{s}'",5302 "invalid target: expected '{}', but found '{s}'",
5273 .{ Platform.fromTarget(self.base.options.target).fmtTarget(cpu_arch), targets_string.items },5303 .{ Platform.fromTarget(target).fmtTarget(cpu_arch), targets_string.items },
5274 ),5304 ),
5275 error.InvalidTargetFatLibrary => try self.reportParseError(5305 error.InvalidTargetFatLibrary => try self.reportParseError(
5276 path,5306 path,
src/link/MachO/Atom.zig+17-11
...@@ -387,7 +387,8 @@ pub fn calcInnerSymbolOffset(macho_file: *MachO, atom_index: Index, sym_index: u...@@ -387,7 +387,8 @@ pub fn calcInnerSymbolOffset(macho_file: *MachO, atom_index: Index, sym_index: u
387}387}
388388
389pub fn scanAtomRelocs(macho_file: *MachO, atom_index: Index, relocs: []align(1) const macho.relocation_info) !void {389pub fn scanAtomRelocs(macho_file: *MachO, atom_index: Index, relocs: []align(1) const macho.relocation_info) !void {
390 const arch = macho_file.base.options.target.cpu.arch;390 const target = macho_file.base.comp.root_mod.resolved_target.result;
391 const arch = target.cpu.arch;
391 const atom = macho_file.getAtom(atom_index);392 const atom = macho_file.getAtom(atom_index);
392 assert(atom.getFile() != null); // synthetic atoms do not have relocs393 assert(atom.getFile() != null); // synthetic atoms do not have relocs
393394
...@@ -434,6 +435,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {...@@ -434,6 +435,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
434 const tracy = trace(@src());435 const tracy = trace(@src());
435 defer tracy.end();436 defer tracy.end();
436437
438 const target = macho_file.base.comp.root_mod.resolved_target.result;
437 const object = &macho_file.objects.items[ctx.object_id];439 const object = &macho_file.objects.items[ctx.object_id];
438 log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name });440 log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name });
439441
...@@ -447,7 +449,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {...@@ -447,7 +449,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
447 else449 else
448 mem.readInt(u32, ctx.code[rel_offset..][0..4], .little);450 mem.readInt(u32, ctx.code[rel_offset..][0..4], .little);
449 } else blk: {451 } else blk: {
450 assert(macho_file.base.options.target.cpu.arch == .x86_64);452 assert(target.cpu.arch == .x86_64);
451 const correction: u3 = switch (@as(macho.reloc_type_x86_64, @enumFromInt(ctx.rel.r_type))) {453 const correction: u3 = switch (@as(macho.reloc_type_x86_64, @enumFromInt(ctx.rel.r_type))) {
452 .X86_64_RELOC_SIGNED => 0,454 .X86_64_RELOC_SIGNED => 0,
453 .X86_64_RELOC_SIGNED_1 => 1,455 .X86_64_RELOC_SIGNED_1 => 1,
...@@ -467,18 +469,18 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {...@@ -467,18 +469,18 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
467469
468 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 };470 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 };
469 const sym = macho_file.getSymbol(sym_loc);471 const sym = macho_file.getSymbol(sym_loc);
470 const target = if (sym.sect() and !sym.ext())472 const reloc_target = if (sym.sect() and !sym.ext())
471 sym_loc473 sym_loc
472 else if (object.getGlobal(sym_index)) |global_index|474 else if (object.getGlobal(sym_index)) |global_index|
473 macho_file.globals.items[global_index]475 macho_file.globals.items[global_index]
474 else476 else
475 sym_loc;477 sym_loc;
476 log.debug(" | target %{d} ('{s}') in object({?d})", .{478 log.debug(" | target %{d} ('{s}') in object({?d})", .{
477 target.sym_index,479 reloc_target.sym_index,
478 macho_file.getSymbolName(target),480 macho_file.getSymbolName(reloc_target),
479 target.getFile(),481 reloc_target.getFile(),
480 });482 });
481 return target;483 return reloc_target;
482}484}
483485
484pub fn getRelocTargetAtomIndex(macho_file: *MachO, target: SymbolWithLoc) ?Index {486pub fn getRelocTargetAtomIndex(macho_file: *MachO, target: SymbolWithLoc) ?Index {
...@@ -599,7 +601,8 @@ pub fn resolveRelocs(...@@ -599,7 +601,8 @@ pub fn resolveRelocs(
599 atom_code: []u8,601 atom_code: []u8,
600 atom_relocs: []align(1) const macho.relocation_info,602 atom_relocs: []align(1) const macho.relocation_info,
601) !void {603) !void {
602 const arch = macho_file.base.options.target.cpu.arch;604 const target = macho_file.base.comp.root_mod.resolved_target.result;
605 const arch = target.cpu.arch;
603 const atom = macho_file.getAtom(atom_index);606 const atom = macho_file.getAtom(atom_index);
604 assert(atom.getFile() != null); // synthetic atoms do not have relocs607 assert(atom.getFile() != null); // synthetic atoms do not have relocs
605608
...@@ -1192,7 +1195,8 @@ pub fn getAtomRelocs(macho_file: *MachO, atom_index: Index) []const macho.reloca...@@ -1192,7 +1195,8 @@ pub fn getAtomRelocs(macho_file: *MachO, atom_index: Index) []const macho.reloca
1192}1195}
11931196
1194pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {1197pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {
1195 switch (macho_file.base.options.target.cpu.arch) {1198 const target = macho_file.base.comp.root_mod.resolved_target.result;
1199 switch (target.cpu.arch) {
1196 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {1200 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
1197 .ARM64_RELOC_GOT_LOAD_PAGE21,1201 .ARM64_RELOC_GOT_LOAD_PAGE21,
1198 .ARM64_RELOC_GOT_LOAD_PAGEOFF12,1202 .ARM64_RELOC_GOT_LOAD_PAGEOFF12,
...@@ -1211,7 +1215,8 @@ pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {...@@ -1211,7 +1215,8 @@ pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {
1211}1215}
12121216
1213pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {1217pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {
1214 switch (macho_file.base.options.target.cpu.arch) {1218 const target = macho_file.base.comp.root_mod.resolved_target.result;
1219 switch (target.cpu.arch) {
1215 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {1220 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
1216 .ARM64_RELOC_TLVP_LOAD_PAGE21,1221 .ARM64_RELOC_TLVP_LOAD_PAGE21,
1217 .ARM64_RELOC_TLVP_LOAD_PAGEOFF12,1222 .ARM64_RELOC_TLVP_LOAD_PAGEOFF12,
...@@ -1227,7 +1232,8 @@ pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {...@@ -1227,7 +1232,8 @@ pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {
1227}1232}
12281233
1229pub fn relocIsStub(macho_file: *MachO, rel: macho.relocation_info) bool {1234pub fn relocIsStub(macho_file: *MachO, rel: macho.relocation_info) bool {
1230 switch (macho_file.base.options.target.cpu.arch) {1235 const target = macho_file.base.comp.root_mod.resolved_target.result;
1236 switch (target.cpu.arch) {
1231 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {1237 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
1232 .ARM64_RELOC_BRANCH26 => return true,1238 .ARM64_RELOC_BRANCH26 => return true,
1233 else => return false,1239 else => return false,
src/link/MachO/DebugSymbols.zig+10-4
...@@ -39,10 +39,12 @@ pub const Reloc = struct {...@@ -39,10 +39,12 @@ pub const Reloc = struct {
39/// You must call this function *after* `MachO.populateMissingMetadata()`39/// You must call this function *after* `MachO.populateMissingMetadata()`
40/// has been called to get a viable debug symbols output.40/// has been called to get a viable debug symbols output.
41pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void {41pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void {
42 const target = macho_file.base.comp.root_mod.resolved_target.result;
43
42 if (self.dwarf_segment_cmd_index == null) {44 if (self.dwarf_segment_cmd_index == null) {
43 self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len));45 self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len));
4446
45 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);47 const page_size = MachO.getPageSize(target.cpu.arch);
46 const off = @as(u64, @intCast(page_size));48 const off = @as(u64, @intCast(page_size));
47 const ideal_size: u16 = 200 + 128 + 160 + 250;49 const ideal_size: u16 = 200 + 128 + 160 + 250;
48 const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size);50 const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size);
...@@ -332,7 +334,8 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {...@@ -332,7 +334,8 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
332 file_size = @max(file_size, header.offset + header.size);334 file_size = @max(file_size, header.offset + header.size);
333 }335 }
334336
335 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);337 const target = macho_file.base.comp.root_mod.resolved_target.result;
338 const page_size = MachO.getPageSize(target.cpu.arch);
336 const aligned_size = mem.alignForward(u64, file_size, page_size);339 const aligned_size = mem.alignForward(u64, file_size, page_size);
337 dwarf_segment.vmaddr = base_vmaddr;340 dwarf_segment.vmaddr = base_vmaddr;
338 dwarf_segment.filesize = aligned_size;341 dwarf_segment.filesize = aligned_size;
...@@ -394,10 +397,12 @@ fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype)...@@ -394,10 +397,12 @@ fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype)
394}397}
395398
396fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void {399fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void {
400 const target = macho_file.base.comp.root_mod.resolved_target.result;
401
397 var header: macho.mach_header_64 = .{};402 var header: macho.mach_header_64 = .{};
398 header.filetype = macho.MH_DSYM;403 header.filetype = macho.MH_DSYM;
399404
400 switch (macho_file.base.options.target.cpu.arch) {405 switch (target.cpu.arch) {
401 .aarch64 => {406 .aarch64 => {
402 header.cputype = macho.CPU_TYPE_ARM64;407 header.cputype = macho.CPU_TYPE_ARM64;
403 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;408 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
...@@ -435,7 +440,8 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void {...@@ -435,7 +440,8 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void {
435 try self.writeSymtab(macho_file);440 try self.writeSymtab(macho_file);
436 try self.writeStrtab();441 try self.writeStrtab();
437442
438 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);443 const target = macho_file.base.comp.root_mod.resolved_target.result;
444 const page_size = MachO.getPageSize(target.cpu.arch);
439 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];445 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];
440 const aligned_size = mem.alignForward(u64, seg.filesize, page_size);446 const aligned_size = mem.alignForward(u64, seg.filesize, page_size);
441 seg.vmsize = aligned_size;447 seg.vmsize = aligned_size;
src/link/MachO/Object.zig+18-15
...@@ -355,6 +355,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) SplitIn...@@ -355,6 +355,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) SplitIn
355/// into subsections where each subsection then represents an Atom.355/// into subsections where each subsection then represents an Atom.
356pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !void {356pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !void {
357 const gpa = macho_file.base.allocator;357 const gpa = macho_file.base.allocator;
358 const target = macho_file.base.comp.root_mod.resolved_target.result;
358359
359 const sections = self.getSourceSections();360 const sections = self.getSourceSections();
360 for (sections, 0..) |sect, id| {361 for (sections, 0..) |sect, id| {
...@@ -448,7 +449,7 @@ pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !...@@ -448,7 +449,7 @@ pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !
448449
449 try self.parseRelocs(gpa, section.id);450 try self.parseRelocs(gpa, section.id);
450451
451 const cpu_arch = macho_file.base.options.target.cpu.arch;452 const cpu_arch = target.cpu.arch;
452 const sect_loc = filterSymbolsBySection(symtab[sect_sym_index..], sect_id + 1);453 const sect_loc = filterSymbolsBySection(symtab[sect_sym_index..], sect_id + 1);
453 const sect_start_index = sect_sym_index + sect_loc.index;454 const sect_start_index = sect_sym_index + sect_loc.index;
454455
...@@ -676,7 +677,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void...@@ -676,7 +677,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
676 macho_file.eh_frame_section_index = try macho_file.initSection("__TEXT", "__eh_frame", .{});677 macho_file.eh_frame_section_index = try macho_file.initSection("__TEXT", "__eh_frame", .{});
677 }678 }
678679
679 const cpu_arch = macho_file.base.options.target.cpu.arch;680 const target = macho_file.base.comp.root_mod.resolved_target.result;
681 const cpu_arch = target.cpu.arch;
680 try self.parseRelocs(gpa, sect_id);682 try self.parseRelocs(gpa, sect_id);
681 const relocs = self.getRelocs(sect_id);683 const relocs = self.getRelocs(sect_id);
682684
...@@ -704,7 +706,7 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void...@@ -704,7 +706,7 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
704 });706 });
705707
706 if (record.tag == .fde) {708 if (record.tag == .fde) {
707 const target = blk: {709 const reloc_target = blk: {
708 switch (cpu_arch) {710 switch (cpu_arch) {
709 .aarch64 => {711 .aarch64 => {
710 assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed712 assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed
...@@ -714,13 +716,13 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void...@@ -714,13 +716,13 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
714 @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)) == .ARM64_RELOC_UNSIGNED)716 @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)) == .ARM64_RELOC_UNSIGNED)
715 break rel;717 break rel;
716 } else unreachable;718 } else unreachable;
717 const target = Atom.parseRelocTarget(macho_file, .{719 const reloc_target = Atom.parseRelocTarget(macho_file, .{
718 .object_id = object_id,720 .object_id = object_id,
719 .rel = rel,721 .rel = rel,
720 .code = it.data[offset..],722 .code = it.data[offset..],
721 .base_offset = @as(i32, @intCast(offset)),723 .base_offset = @as(i32, @intCast(offset)),
722 });724 });
723 break :blk target;725 break :blk reloc_target;
724 },726 },
725 .x86_64 => {727 .x86_64 => {
726 const target_address = record.getTargetSymbolAddress(.{728 const target_address = record.getTargetSymbolAddress(.{
...@@ -728,16 +730,16 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void...@@ -728,16 +730,16 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
728 .base_offset = offset,730 .base_offset = offset,
729 });731 });
730 const target_sym_index = self.getSymbolByAddress(target_address, null);732 const target_sym_index = self.getSymbolByAddress(target_address, null);
731 const target = if (self.getGlobal(target_sym_index)) |global_index|733 const reloc_target = if (self.getGlobal(target_sym_index)) |global_index|
732 macho_file.globals.items[global_index]734 macho_file.globals.items[global_index]
733 else735 else
734 SymbolWithLoc{ .sym_index = target_sym_index, .file = object_id + 1 };736 SymbolWithLoc{ .sym_index = target_sym_index, .file = object_id + 1 };
735 break :blk target;737 break :blk reloc_target;
736 },738 },
737 else => unreachable,739 else => unreachable,
738 }740 }
739 };741 };
740 if (target.getFile() != object_id) {742 if (reloc_target.getFile() != object_id) {
741 log.debug("FDE at offset {x} marked DEAD", .{offset});743 log.debug("FDE at offset {x} marked DEAD", .{offset});
742 self.eh_frame_relocs_lookup.getPtr(offset).?.dead = true;744 self.eh_frame_relocs_lookup.getPtr(offset).?.dead = true;
743 } else {745 } else {
...@@ -746,12 +748,12 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void...@@ -746,12 +748,12 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
746 // very problematic when using Zig's @export feature to re-export symbols under748 // very problematic when using Zig's @export feature to re-export symbols under
747 // additional names. For that reason, we need to ensure we record aliases here749 // additional names. For that reason, we need to ensure we record aliases here
748 // too so that we can tie them with their matching unwind records and vice versa.750 // too so that we can tie them with their matching unwind records and vice versa.
749 const aliases = self.getSymbolAliases(target.sym_index);751 const aliases = self.getSymbolAliases(reloc_target.sym_index);
750 var i: u32 = 0;752 var i: u32 = 0;
751 while (i < aliases.len) : (i += 1) {753 while (i < aliases.len) : (i += 1) {
752 const actual_target = SymbolWithLoc{754 const actual_target = SymbolWithLoc{
753 .sym_index = i + aliases.start,755 .sym_index = i + aliases.start,
754 .file = target.file,756 .file = reloc_target.file,
755 };757 };
756 log.debug("FDE at offset {x} tracks {s}", .{758 log.debug("FDE at offset {x} tracks {s}", .{
757 offset,759 offset,
...@@ -766,7 +768,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void...@@ -766,7 +768,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
766768
767fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {769fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
768 const gpa = macho_file.base.allocator;770 const gpa = macho_file.base.allocator;
769 const cpu_arch = macho_file.base.options.target.cpu.arch;771 const target = macho_file.base.comp.root_mod.resolved_target.result;
772 const cpu_arch = target.cpu.arch;
770 const sect_id = self.unwind_info_sect_id orelse {773 const sect_id = self.unwind_info_sect_id orelse {
771 // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`,774 // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`,
772 // we will try fully synthesising unwind info records to somewhat match Apple ld's775 // we will try fully synthesising unwind info records to somewhat match Apple ld's
...@@ -818,13 +821,13 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {...@@ -818,13 +821,13 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
818821
819 // Find function symbol that this record describes822 // Find function symbol that this record describes
820 const rel = relocs[rel_pos.start..][rel_pos.len - 1];823 const rel = relocs[rel_pos.start..][rel_pos.len - 1];
821 const target = Atom.parseRelocTarget(macho_file, .{824 const reloc_target = Atom.parseRelocTarget(macho_file, .{
822 .object_id = object_id,825 .object_id = object_id,
823 .rel = rel,826 .rel = rel,
824 .code = mem.asBytes(&record),827 .code = mem.asBytes(&record),
825 .base_offset = @as(i32, @intCast(offset)),828 .base_offset = @as(i32, @intCast(offset)),
826 });829 });
827 if (target.getFile() != object_id) {830 if (reloc_target.getFile() != object_id) {
828 log.debug("unwind record {d} marked DEAD", .{record_id});831 log.debug("unwind record {d} marked DEAD", .{record_id});
829 self.unwind_relocs_lookup[record_id].dead = true;832 self.unwind_relocs_lookup[record_id].dead = true;
830 } else {833 } else {
...@@ -833,12 +836,12 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {...@@ -833,12 +836,12 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
833 // very problematic when using Zig's @export feature to re-export symbols under836 // very problematic when using Zig's @export feature to re-export symbols under
834 // additional names. For that reason, we need to ensure we record aliases here837 // additional names. For that reason, we need to ensure we record aliases here
835 // too so that we can tie them with their matching unwind records and vice versa.838 // too so that we can tie them with their matching unwind records and vice versa.
836 const aliases = self.getSymbolAliases(target.sym_index);839 const aliases = self.getSymbolAliases(reloc_target.sym_index);
837 var i: u32 = 0;840 var i: u32 = 0;
838 while (i < aliases.len) : (i += 1) {841 while (i < aliases.len) : (i += 1) {
839 const actual_target = SymbolWithLoc{842 const actual_target = SymbolWithLoc{
840 .sym_index = i + aliases.start,843 .sym_index = i + aliases.start,
841 .file = target.file,844 .file = reloc_target.file,
842 };845 };
843 log.debug("unwind record {d} tracks {s}", .{846 log.debug("unwind record {d} tracks {s}", .{
844 record_id,847 record_id,
src/link/MachO/Relocation.zig+4-2
...@@ -58,11 +58,12 @@ pub fn isStubTrampoline(self: Relocation, macho_file: *MachO) bool {...@@ -58,11 +58,12 @@ pub fn isStubTrampoline(self: Relocation, macho_file: *MachO) bool {
58}58}
5959
60pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {60pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {
61 const target = macho_file.base.comp.root_mod.resolved_target.result;
61 if (self.isStubTrampoline(macho_file)) {62 if (self.isStubTrampoline(macho_file)) {
62 const index = macho_file.stub_table.lookup.get(self.target) orelse return null;63 const index = macho_file.stub_table.lookup.get(self.target) orelse return null;
63 const header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];64 const header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];
64 return header.addr +65 return header.addr +
65 index * @import("stubs.zig").stubSize(macho_file.base.options.target.cpu.arch);66 index * @import("stubs.zig").stubSize(target.cpu.arch);
66 }67 }
67 switch (self.type) {68 switch (self.type) {
68 .got, .got_page, .got_pageoff => {69 .got, .got_page, .got_pageoff => {
...@@ -84,7 +85,8 @@ pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {...@@ -84,7 +85,8 @@ pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {
84}85}
8586
86pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {87pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {
87 const arch = macho_file.base.options.target.cpu.arch;88 const target = macho_file.base.comp.root_mod.resolved_target.result;
89 const arch = target.cpu.arch;
88 const atom = macho_file.getAtom(atom_index);90 const atom = macho_file.getAtom(atom_index);
89 const source_sym = atom.getSymbol(macho_file);91 const source_sym = atom.getSymbol(macho_file);
90 const source_addr = source_sym.n_value + self.offset;92 const source_addr = source_sym.n_value + self.offset;
src/link/MachO/UnwindInfo.zig+16-13
...@@ -184,7 +184,8 @@ pub fn deinit(info: *UnwindInfo) void {...@@ -184,7 +184,8 @@ pub fn deinit(info: *UnwindInfo) void {
184pub fn scanRelocs(macho_file: *MachO) !void {184pub fn scanRelocs(macho_file: *MachO) !void {
185 if (macho_file.unwind_info_section_index == null) return;185 if (macho_file.unwind_info_section_index == null) return;
186186
187 const cpu_arch = macho_file.base.options.target.cpu.arch;187 const target = macho_file.base.comp.root_mod.resolved_target.result;
188 const cpu_arch = target.cpu.arch;
188 for (macho_file.objects.items, 0..) |*object, object_id| {189 for (macho_file.objects.items, 0..) |*object, object_id| {
189 const unwind_records = object.getUnwindRecords();190 const unwind_records = object.getUnwindRecords();
190 for (object.exec_atoms.items) |atom_index| {191 for (object.exec_atoms.items) |atom_index| {
...@@ -196,13 +197,13 @@ pub fn scanRelocs(macho_file: *MachO) !void {...@@ -196,13 +197,13 @@ pub fn scanRelocs(macho_file: *MachO) !void {
196 if (!UnwindEncoding.isDwarf(record.compactUnwindEncoding, cpu_arch)) {197 if (!UnwindEncoding.isDwarf(record.compactUnwindEncoding, cpu_arch)) {
197 if (getPersonalityFunctionReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {198 if (getPersonalityFunctionReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {
198 // Personality function; add GOT pointer.199 // Personality function; add GOT pointer.
199 const target = Atom.parseRelocTarget(macho_file, .{200 const reloc_target = Atom.parseRelocTarget(macho_file, .{
200 .object_id = @as(u32, @intCast(object_id)),201 .object_id = @as(u32, @intCast(object_id)),
201 .rel = rel,202 .rel = rel,
202 .code = mem.asBytes(&record),203 .code = mem.asBytes(&record),
203 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),204 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
204 });205 });
205 try macho_file.addGotEntry(target);206 try macho_file.addGotEntry(reloc_target);
206 }207 }
207 }208 }
208 }209 }
...@@ -213,7 +214,8 @@ pub fn scanRelocs(macho_file: *MachO) !void {...@@ -213,7 +214,8 @@ pub fn scanRelocs(macho_file: *MachO) !void {
213pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {214pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
214 if (macho_file.unwind_info_section_index == null) return;215 if (macho_file.unwind_info_section_index == null) return;
215216
216 const cpu_arch = macho_file.base.options.target.cpu.arch;217 const target = macho_file.base.comp.root_mod.resolved_target.result;
218 const cpu_arch = target.cpu.arch;
217219
218 var records = std.ArrayList(macho.compact_unwind_entry).init(info.gpa);220 var records = std.ArrayList(macho.compact_unwind_entry).init(info.gpa);
219 defer records.deinit();221 defer records.deinit();
...@@ -247,15 +249,15 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {...@@ -247,15 +249,15 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
247 @as(u32, @intCast(object_id)),249 @as(u32, @intCast(object_id)),
248 record_id,250 record_id,
249 )) |rel| {251 )) |rel| {
250 const target = Atom.parseRelocTarget(macho_file, .{252 const reloc_target = Atom.parseRelocTarget(macho_file, .{
251 .object_id = @as(u32, @intCast(object_id)),253 .object_id = @as(u32, @intCast(object_id)),
252 .rel = rel,254 .rel = rel,
253 .code = mem.asBytes(&record),255 .code = mem.asBytes(&record),
254 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),256 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
255 });257 });
256 const personality_index = info.getPersonalityFunction(target) orelse inner: {258 const personality_index = info.getPersonalityFunction(reloc_target) orelse inner: {
257 const personality_index = info.personalities_count;259 const personality_index = info.personalities_count;
258 info.personalities[personality_index] = target;260 info.personalities[personality_index] = reloc_target;
259 info.personalities_count += 1;261 info.personalities_count += 1;
260 break :inner personality_index;262 break :inner personality_index;
261 };263 };
...@@ -265,13 +267,13 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {...@@ -265,13 +267,13 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
265 }267 }
266268
267 if (getLsdaReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {269 if (getLsdaReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {
268 const target = Atom.parseRelocTarget(macho_file, .{270 const reloc_target = Atom.parseRelocTarget(macho_file, .{
269 .object_id = @as(u32, @intCast(object_id)),271 .object_id = @as(u32, @intCast(object_id)),
270 .rel = rel,272 .rel = rel,
271 .code = mem.asBytes(&record),273 .code = mem.asBytes(&record),
272 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),274 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
273 });275 });
274 record.lsda = @as(u64, @bitCast(target));276 record.lsda = @as(u64, @bitCast(reloc_target));
275 }277 }
276 }278 }
277 break :blk record;279 break :blk record;
...@@ -557,13 +559,14 @@ pub fn write(info: *UnwindInfo, macho_file: *MachO) !void {...@@ -557,13 +559,14 @@ pub fn write(info: *UnwindInfo, macho_file: *MachO) !void {
557 const text_sect = macho_file.sections.items(.header)[text_sect_id];559 const text_sect = macho_file.sections.items(.header)[text_sect_id];
558560
559 var personalities: [max_personalities]u32 = undefined;561 var personalities: [max_personalities]u32 = undefined;
560 const cpu_arch = macho_file.base.options.target.cpu.arch;562 const target = macho_file.base.comp.root_mod.resolved_target.result;
563 const cpu_arch = target.cpu.arch;
561564
562 log.debug("Personalities:", .{});565 log.debug("Personalities:", .{});
563 for (info.personalities[0..info.personalities_count], 0..) |target, i| {566 for (info.personalities[0..info.personalities_count], 0..) |reloc_target, i| {
564 const addr = macho_file.getGotEntryAddress(target).?;567 const addr = macho_file.getGotEntryAddress(reloc_target).?;
565 personalities[i] = @as(u32, @intCast(addr - seg.vmaddr));568 personalities[i] = @as(u32, @intCast(addr - seg.vmaddr));
566 log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(target) });569 log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(reloc_target) });
567 }570 }
568571
569 for (info.records.items) |*rec| {572 for (info.records.items) |*rec| {
src/link/MachO/dead_strip.zig+33-29
...@@ -118,7 +118,8 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void...@@ -118,7 +118,8 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
118118
119 alive.putAssumeCapacityNoClobber(atom_index, {});119 alive.putAssumeCapacityNoClobber(atom_index, {});
120120
121 const cpu_arch = macho_file.base.options.target.cpu.arch;121 const target = macho_file.base.comp.root_mod.resolved_target.result;
122 const cpu_arch = target.cpu.arch;
122123
123 const sym = macho_file.getSymbol(atom.getSymbolWithLoc());124 const sym = macho_file.getSymbol(atom.getSymbolWithLoc());
124 const header = macho_file.sections.items(.header)[sym.n_sect - 1];125 const header = macho_file.sections.items(.header)[sym.n_sect - 1];
...@@ -129,7 +130,7 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void...@@ -129,7 +130,7 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
129 const ctx = Atom.getRelocContext(macho_file, atom_index);130 const ctx = Atom.getRelocContext(macho_file, atom_index);
130131
131 for (relocs) |rel| {132 for (relocs) |rel| {
132 const target = switch (cpu_arch) {133 const reloc_target = switch (cpu_arch) {
133 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {134 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
134 .ARM64_RELOC_ADDEND => continue,135 .ARM64_RELOC_ADDEND => continue,
135 else => Atom.parseRelocTarget(macho_file, .{136 else => Atom.parseRelocTarget(macho_file, .{
...@@ -149,19 +150,19 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void...@@ -149,19 +150,19 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
149 }),150 }),
150 else => unreachable,151 else => unreachable,
151 };152 };
152 const target_sym = macho_file.getSymbol(target);153 const target_sym = macho_file.getSymbol(reloc_target);
153154
154 if (target_sym.undf()) continue;155 if (target_sym.undf()) continue;
155 if (target.getFile() == null) {156 if (reloc_target.getFile() == null) {
156 const target_sym_name = macho_file.getSymbolName(target);157 const target_sym_name = macho_file.getSymbolName(reloc_target);
157 if (mem.eql(u8, "__mh_execute_header", target_sym_name)) continue;158 if (mem.eql(u8, "__mh_execute_header", target_sym_name)) continue;
158 if (mem.eql(u8, "___dso_handle", target_sym_name)) continue;159 if (mem.eql(u8, "___dso_handle", target_sym_name)) continue;
159160
160 unreachable; // referenced symbol not found161 unreachable; // referenced symbol not found
161 }162 }
162163
163 const object = macho_file.objects.items[target.getFile().?];164 const object = macho_file.objects.items[reloc_target.getFile().?];
164 const target_atom_index = object.getAtomIndexForSymbol(target.sym_index).?;165 const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index).?;
165 log.debug(" following ATOM({d}, %{d}, {?d})", .{166 log.debug(" following ATOM({d}, %{d}, {?d})", .{
166 target_atom_index,167 target_atom_index,
167 macho_file.getAtom(target_atom_index).sym_index,168 macho_file.getAtom(target_atom_index).sym_index,
...@@ -178,7 +179,8 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool...@@ -178,7 +179,8 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
178179
179 log.debug("refersLive(ATOM({d}, %{d}, {?d}))", .{ atom_index, sym_loc.sym_index, sym_loc.getFile() });180 log.debug("refersLive(ATOM({d}, %{d}, {?d}))", .{ atom_index, sym_loc.sym_index, sym_loc.getFile() });
180181
181 const cpu_arch = macho_file.base.options.target.cpu.arch;182 const target = macho_file.base.comp.root_mod.resolved_target.result;
183 const cpu_arch = target.cpu.arch;
182184
183 const sym = macho_file.getSymbol(sym_loc);185 const sym = macho_file.getSymbol(sym_loc);
184 const header = macho_file.sections.items(.header)[sym.n_sect - 1];186 const header = macho_file.sections.items(.header)[sym.n_sect - 1];
...@@ -189,7 +191,7 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool...@@ -189,7 +191,7 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
189 const ctx = Atom.getRelocContext(macho_file, atom_index);191 const ctx = Atom.getRelocContext(macho_file, atom_index);
190192
191 for (relocs) |rel| {193 for (relocs) |rel| {
192 const target = switch (cpu_arch) {194 const reloc_target = switch (cpu_arch) {
193 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {195 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
194 .ARM64_RELOC_ADDEND => continue,196 .ARM64_RELOC_ADDEND => continue,
195 else => Atom.parseRelocTarget(macho_file, .{197 else => Atom.parseRelocTarget(macho_file, .{
...@@ -210,9 +212,9 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool...@@ -210,9 +212,9 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
210 else => unreachable,212 else => unreachable,
211 };213 };
212214
213 const object = macho_file.objects.items[target.getFile().?];215 const object = macho_file.objects.items[reloc_target.getFile().?];
214 const target_atom_index = object.getAtomIndexForSymbol(target.sym_index) orelse {216 const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index) orelse {
215 log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(target)});217 log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(reloc_target)});
216 continue;218 continue;
217 };219 };
218 if (alive.contains(target_atom_index)) {220 if (alive.contains(target_atom_index)) {
...@@ -271,7 +273,8 @@ fn mark(macho_file: *MachO, roots: AtomTable, alive: *AtomTable) void {...@@ -271,7 +273,8 @@ fn mark(macho_file: *MachO, roots: AtomTable, alive: *AtomTable) void {
271273
272fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void {274fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void {
273 const object = &macho_file.objects.items[object_id];275 const object = &macho_file.objects.items[object_id];
274 const cpu_arch = macho_file.base.options.target.cpu.arch;276 const target = macho_file.base.comp.root_mod.resolved_target.result;
277 const cpu_arch = target.cpu.arch;
275278
276 const unwind_records = object.getUnwindRecords();279 const unwind_records = object.getUnwindRecords();
277280
...@@ -310,29 +313,29 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void...@@ -310,29 +313,29 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void
310 markEhFrameRecords(macho_file, object_id, atom_index, alive);313 markEhFrameRecords(macho_file, object_id, atom_index, alive);
311 } else {314 } else {
312 if (UnwindInfo.getPersonalityFunctionReloc(macho_file, object_id, record_id)) |rel| {315 if (UnwindInfo.getPersonalityFunctionReloc(macho_file, object_id, record_id)) |rel| {
313 const target = Atom.parseRelocTarget(macho_file, .{316 const reloc_target = Atom.parseRelocTarget(macho_file, .{
314 .object_id = object_id,317 .object_id = object_id,
315 .rel = rel,318 .rel = rel,
316 .code = mem.asBytes(&record),319 .code = mem.asBytes(&record),
317 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),320 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
318 });321 });
319 const target_sym = macho_file.getSymbol(target);322 const target_sym = macho_file.getSymbol(reloc_target);
320 if (!target_sym.undf()) {323 if (!target_sym.undf()) {
321 const target_object = macho_file.objects.items[target.getFile().?];324 const target_object = macho_file.objects.items[reloc_target.getFile().?];
322 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;325 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
323 markLive(macho_file, target_atom_index, alive);326 markLive(macho_file, target_atom_index, alive);
324 }327 }
325 }328 }
326329
327 if (UnwindInfo.getLsdaReloc(macho_file, object_id, record_id)) |rel| {330 if (UnwindInfo.getLsdaReloc(macho_file, object_id, record_id)) |rel| {
328 const target = Atom.parseRelocTarget(macho_file, .{331 const reloc_target = Atom.parseRelocTarget(macho_file, .{
329 .object_id = object_id,332 .object_id = object_id,
330 .rel = rel,333 .rel = rel,
331 .code = mem.asBytes(&record),334 .code = mem.asBytes(&record),
332 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),335 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
333 });336 });
334 const target_object = macho_file.objects.items[target.getFile().?];337 const target_object = macho_file.objects.items[reloc_target.getFile().?];
335 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;338 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
336 markLive(macho_file, target_atom_index, alive);339 markLive(macho_file, target_atom_index, alive);
337 }340 }
338 }341 }
...@@ -341,7 +344,8 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void...@@ -341,7 +344,8 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void
341}344}
342345
343fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index, alive: *AtomTable) void {346fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index, alive: *AtomTable) void {
344 const cpu_arch = macho_file.base.options.target.cpu.arch;347 const target = macho_file.base.comp.root_mod.resolved_target.result;
348 const cpu_arch = target.cpu.arch;
345 const object = &macho_file.objects.items[object_id];349 const object = &macho_file.objects.items[object_id];
346 var it = object.getEhFrameRecordsIterator();350 var it = object.getEhFrameRecordsIterator();
347 var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);351 var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);
...@@ -361,16 +365,16 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index...@@ -361,16 +365,16 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index
361 // Mark FDE references which should include any referenced LSDA record365 // Mark FDE references which should include any referenced LSDA record
362 const relocs = eh_frame.getRelocs(macho_file, object_id, fde_offset);366 const relocs = eh_frame.getRelocs(macho_file, object_id, fde_offset);
363 for (relocs) |rel| {367 for (relocs) |rel| {
364 const target = Atom.parseRelocTarget(macho_file, .{368 const reloc_target = Atom.parseRelocTarget(macho_file, .{
365 .object_id = object_id,369 .object_id = object_id,
366 .rel = rel,370 .rel = rel,
367 .code = fde.data,371 .code = fde.data,
368 .base_offset = @as(i32, @intCast(fde_offset)) + 4,372 .base_offset = @as(i32, @intCast(fde_offset)) + 4,
369 });373 });
370 const target_sym = macho_file.getSymbol(target);374 const target_sym = macho_file.getSymbol(reloc_target);
371 if (!target_sym.undf()) blk: {375 if (!target_sym.undf()) blk: {
372 const target_object = macho_file.objects.items[target.getFile().?];376 const target_object = macho_file.objects.items[reloc_target.getFile().?];
373 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index) orelse377 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index) orelse
374 break :blk;378 break :blk;
375 markLive(macho_file, target_atom_index, alive);379 markLive(macho_file, target_atom_index, alive);
376 }380 }
...@@ -394,11 +398,11 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index...@@ -394,11 +398,11 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index
394398
395 // Mark CIE references which should include any referenced personalities399 // Mark CIE references which should include any referenced personalities
396 // that are defined locally.400 // that are defined locally.
397 if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |target| {401 if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |reloc_target| {
398 const target_sym = macho_file.getSymbol(target);402 const target_sym = macho_file.getSymbol(reloc_target);
399 if (!target_sym.undf()) {403 if (!target_sym.undf()) {
400 const target_object = macho_file.objects.items[target.getFile().?];404 const target_object = macho_file.objects.items[reloc_target.getFile().?];
401 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;405 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
402 markLive(macho_file, target_atom_index, alive);406 markLive(macho_file, target_atom_index, alive);
403 }407 }
404 }408 }
src/link/MachO/eh_frame.zig+20-15
...@@ -35,7 +35,8 @@ pub fn calcSectionSize(macho_file: *MachO, unwind_info: *const UnwindInfo) error...@@ -35,7 +35,8 @@ pub fn calcSectionSize(macho_file: *MachO, unwind_info: *const UnwindInfo) error
35 sect.@"align" = 3;35 sect.@"align" = 3;
36 sect.size = 0;36 sect.size = 0;
3737
38 const cpu_arch = macho_file.base.options.target.cpu.arch;38 const target = macho_file.base.comp.root_mod.resolved_target.result;
39 const cpu_arch = target.cpu.arch;
39 const gpa = macho_file.base.allocator;40 const gpa = macho_file.base.allocator;
40 var size: u32 = 0;41 var size: u32 = 0;
4142
...@@ -86,7 +87,8 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {...@@ -86,7 +87,8 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
86 const seg_id = macho_file.sections.items(.segment_index)[sect_id];87 const seg_id = macho_file.sections.items(.segment_index)[sect_id];
87 const seg = macho_file.segments.items[seg_id];88 const seg = macho_file.segments.items[seg_id];
8889
89 const cpu_arch = macho_file.base.options.target.cpu.arch;90 const target = macho_file.base.comp.root_mod.resolved_target.result;
91 const cpu_arch = target.cpu.arch;
90 const gpa = macho_file.base.allocator;92 const gpa = macho_file.base.allocator;
9193
92 var eh_records = std.AutoArrayHashMap(u32, EhFrameRecord(true)).init(gpa);94 var eh_records = std.AutoArrayHashMap(u32, EhFrameRecord(true)).init(gpa);
...@@ -109,11 +111,11 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {...@@ -109,11 +111,11 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
109111
110 for (object.exec_atoms.items) |atom_index| {112 for (object.exec_atoms.items) |atom_index| {
111 var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);113 var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);
112 while (inner_syms_it.next()) |target| {114 while (inner_syms_it.next()) |reloc_target| {
113 const fde_record_offset = object.eh_frame_records_lookup.get(target) orelse continue;115 const fde_record_offset = object.eh_frame_records_lookup.get(reloc_target) orelse continue;
114 if (object.eh_frame_relocs_lookup.get(fde_record_offset).?.dead) continue;116 if (object.eh_frame_relocs_lookup.get(fde_record_offset).?.dead) continue;
115117
116 const record_id = unwind_info.records_lookup.get(target) orelse continue;118 const record_id = unwind_info.records_lookup.get(reloc_target) orelse continue;
117 const record = &unwind_info.records.items[record_id];119 const record = &unwind_info.records.items[record_id];
118120
119 // TODO skip this check if no __compact_unwind is present121 // TODO skip this check if no __compact_unwind is present
...@@ -153,7 +155,7 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {...@@ -153,7 +155,7 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
153 .aarch64 => {}, // relocs take care of LSDA pointers155 .aarch64 => {}, // relocs take care of LSDA pointers
154 .x86_64 => {156 .x86_64 => {
155 // We need to relocate target symbol address ourselves.157 // We need to relocate target symbol address ourselves.
156 const atom_sym = macho_file.getSymbol(target);158 const atom_sym = macho_file.getSymbol(reloc_target);
157 try fde_record.setTargetSymbolAddress(atom_sym.n_value, .{159 try fde_record.setTargetSymbolAddress(atom_sym.n_value, .{
158 .base_addr = sect.addr,160 .base_addr = sect.addr,
159 .base_offset = eh_frame_offset,161 .base_offset = eh_frame_offset,
...@@ -278,7 +280,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {...@@ -278,7 +280,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
278 object_id: u32,280 object_id: u32,
279 source_offset: u32,281 source_offset: u32,
280 ) ?SymbolWithLoc {282 ) ?SymbolWithLoc {
281 const cpu_arch = macho_file.base.options.target.cpu.arch;283 const target = macho_file.base.comp.root_mod.resolved_target.result;
284 const cpu_arch = target.cpu.arch;
282 const relocs = getRelocs(macho_file, object_id, source_offset);285 const relocs = getRelocs(macho_file, object_id, source_offset);
283 for (relocs) |rel| {286 for (relocs) |rel| {
284 switch (cpu_arch) {287 switch (cpu_arch) {
...@@ -301,13 +304,13 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {...@@ -301,13 +304,13 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
301 },304 },
302 else => unreachable,305 else => unreachable,
303 }306 }
304 const target = Atom.parseRelocTarget(macho_file, .{307 const reloc_target = Atom.parseRelocTarget(macho_file, .{
305 .object_id = object_id,308 .object_id = object_id,
306 .rel = rel,309 .rel = rel,
307 .code = rec.data,310 .code = rec.data,
308 .base_offset = @as(i32, @intCast(source_offset)) + 4,311 .base_offset = @as(i32, @intCast(source_offset)) + 4,
309 });312 });
310 return target;313 return reloc_target;
311 }314 }
312 return null;315 return null;
313 }316 }
...@@ -319,11 +322,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {...@@ -319,11 +322,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
319 }) !void {322 }) !void {
320 comptime assert(is_mutable);323 comptime assert(is_mutable);
321324
322 const cpu_arch = macho_file.base.options.target.cpu.arch;325 const target = macho_file.base.comp.root_mod.resolved_target.result;
326 const cpu_arch = target.cpu.arch;
323 const relocs = getRelocs(macho_file, object_id, ctx.source_offset);327 const relocs = getRelocs(macho_file, object_id, ctx.source_offset);
324328
325 for (relocs) |rel| {329 for (relocs) |rel| {
326 const target = Atom.parseRelocTarget(macho_file, .{330 const reloc_target = Atom.parseRelocTarget(macho_file, .{
327 .object_id = object_id,331 .object_id = object_id,
328 .rel = rel,332 .rel = rel,
329 .code = rec.data,333 .code = rec.data,
...@@ -340,14 +344,14 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {...@@ -340,14 +344,14 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
340 // Address of the __eh_frame in the source object file344 // Address of the __eh_frame in the source object file
341 },345 },
342 .ARM64_RELOC_POINTER_TO_GOT => {346 .ARM64_RELOC_POINTER_TO_GOT => {
343 const target_addr = macho_file.getGotEntryAddress(target).?;347 const target_addr = macho_file.getGotEntryAddress(reloc_target).?;
344 const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse348 const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse
345 return error.Overflow;349 return error.Overflow;
346 mem.writeInt(i32, rec.data[rel_offset..][0..4], result, .little);350 mem.writeInt(i32, rec.data[rel_offset..][0..4], result, .little);
347 },351 },
348 .ARM64_RELOC_UNSIGNED => {352 .ARM64_RELOC_UNSIGNED => {
349 assert(rel.r_extern == 1);353 assert(rel.r_extern == 1);
350 const target_addr = Atom.getRelocTargetAddress(macho_file, target, false);354 const target_addr = Atom.getRelocTargetAddress(macho_file, reloc_target, false);
351 const result = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr));355 const result = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr));
352 mem.writeInt(i64, rec.data[rel_offset..][0..8], @as(i64, @intCast(result)), .little);356 mem.writeInt(i64, rec.data[rel_offset..][0..8], @as(i64, @intCast(result)), .little);
353 },357 },
...@@ -358,7 +362,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {...@@ -358,7 +362,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
358 const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type));362 const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type));
359 switch (rel_type) {363 switch (rel_type) {
360 .X86_64_RELOC_GOT => {364 .X86_64_RELOC_GOT => {
361 const target_addr = macho_file.getGotEntryAddress(target).?;365 const target_addr = macho_file.getGotEntryAddress(reloc_target).?;
362 const addend = mem.readInt(i32, rec.data[rel_offset..][0..4], .little);366 const addend = mem.readInt(i32, rec.data[rel_offset..][0..4], .little);
363 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));367 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
364 const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);368 const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);
...@@ -374,7 +378,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {...@@ -374,7 +378,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
374378
375 pub fn getCiePointerSource(rec: Record, object_id: u32, macho_file: *MachO, offset: u32) u32 {379 pub fn getCiePointerSource(rec: Record, object_id: u32, macho_file: *MachO, offset: u32) u32 {
376 assert(rec.tag == .fde);380 assert(rec.tag == .fde);
377 const cpu_arch = macho_file.base.options.target.cpu.arch;381 const target = macho_file.base.comp.root_mod.resolved_target.result;
382 const cpu_arch = target.cpu.arch;
378 const addend = mem.readInt(u32, rec.data[0..4], .little);383 const addend = mem.readInt(u32, rec.data[0..4], .little);
379 switch (cpu_arch) {384 switch (cpu_arch) {
380 .aarch64 => {385 .aarch64 => {
src/link/MachO/load_commands.zig+3-3
...@@ -472,11 +472,11 @@ pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVe...@@ -472,11 +472,11 @@ pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVe
472 defer arena_allocator.deinit();472 defer arena_allocator.deinit();
473 const arena = arena_allocator.allocator();473 const arena = arena_allocator.allocator();
474474
475 const options = comp.bin_file.options;475 const macho_file = comp.bin_file.cast(MachO).?;
476476
477 const sdk_layout = options.darwin_sdk_layout orelse return null;477 const sdk_layout = macho_file.sdk_layout orelse return null;
478 const sdk_dir = switch (sdk_layout) {478 const sdk_dir = switch (sdk_layout) {
479 .sdk => options.sysroot.?,479 .sdk => macho_file.sysroot.?,
480 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,480 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
481 };481 };
482 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {482 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
src/link/MachO/zld.zig+18-11
...@@ -458,7 +458,7 @@ pub fn linkWithZld(...@@ -458,7 +458,7 @@ pub fn linkWithZld(
458 }458 }
459459
460 try writeAtoms(macho_file);460 try writeAtoms(macho_file);
461 if (macho_file.base.options.target.cpu.arch == .aarch64) try writeThunks(macho_file);461 if (target.cpu.arch == .aarch64) try writeThunks(macho_file);
462 try writeDyldPrivateAtom(macho_file);462 try writeDyldPrivateAtom(macho_file);
463463
464 if (macho_file.stubs_section_index) |_| {464 if (macho_file.stubs_section_index) |_| {
...@@ -557,7 +557,7 @@ pub fn linkWithZld(...@@ -557,7 +557,7 @@ pub fn linkWithZld(
557 .version = 0,557 .version = 0,
558 });558 });
559 {559 {
560 const platform = Platform.fromTarget(macho_file.base.options.target);560 const platform = Platform.fromTarget(target);
561 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);561 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
562 if (platform.isBuildVersionCompatible()) {562 if (platform.isBuildVersionCompatible()) {
563 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);563 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
...@@ -610,7 +610,8 @@ pub fn linkWithZld(...@@ -610,7 +610,8 @@ pub fn linkWithZld(
610610
611fn createSegments(macho_file: *MachO) !void {611fn createSegments(macho_file: *MachO) !void {
612 const gpa = macho_file.base.allocator;612 const gpa = macho_file.base.allocator;
613 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);613 const target = macho_file.base.comp.root_mod.resolved_target.result;
614 const page_size = MachO.getPageSize(target.cpu.arch);
614 const aligned_pagezero_vmsize = mem.alignBackward(u64, macho_file.pagezero_vmsize, page_size);615 const aligned_pagezero_vmsize = mem.alignBackward(u64, macho_file.pagezero_vmsize, page_size);
615 if (macho_file.base.comp.config.output_mode != .Lib and aligned_pagezero_vmsize > 0) {616 if (macho_file.base.comp.config.output_mode != .Lib and aligned_pagezero_vmsize > 0) {
616 if (aligned_pagezero_vmsize != macho_file.pagezero_vmsize) {617 if (aligned_pagezero_vmsize != macho_file.pagezero_vmsize) {
...@@ -755,7 +756,8 @@ fn writeDyldPrivateAtom(macho_file: *MachO) !void {...@@ -755,7 +756,8 @@ fn writeDyldPrivateAtom(macho_file: *MachO) !void {
755}756}
756757
757fn writeThunks(macho_file: *MachO) !void {758fn writeThunks(macho_file: *MachO) !void {
758 assert(macho_file.base.options.target.cpu.arch == .aarch64);759 const target = macho_file.base.comp.root_mod.resolved_target.result;
760 assert(target.cpu.arch == .aarch64);
759 const gpa = macho_file.base.allocator;761 const gpa = macho_file.base.allocator;
760762
761 const sect_id = macho_file.text_section_index orelse return;763 const sect_id = macho_file.text_section_index orelse return;
...@@ -791,7 +793,8 @@ fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void {...@@ -791,7 +793,8 @@ fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void {
791793
792fn writeStubs(macho_file: *MachO) !void {794fn writeStubs(macho_file: *MachO) !void {
793 const gpa = macho_file.base.allocator;795 const gpa = macho_file.base.allocator;
794 const cpu_arch = macho_file.base.options.target.cpu.arch;796 const target = macho_file.base.comp.root_mod.resolved_target.result;
797 const cpu_arch = target.cpu.arch;
795 const stubs_header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];798 const stubs_header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];
796 const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];799 const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];
797800
...@@ -813,7 +816,8 @@ fn writeStubs(macho_file: *MachO) !void {...@@ -813,7 +816,8 @@ fn writeStubs(macho_file: *MachO) !void {
813816
814fn writeStubHelpers(macho_file: *MachO) !void {817fn writeStubHelpers(macho_file: *MachO) !void {
815 const gpa = macho_file.base.allocator;818 const gpa = macho_file.base.allocator;
816 const cpu_arch = macho_file.base.options.target.cpu.arch;819 const target = macho_file.base.comp.root_mod.resolved_target.result;
820 const cpu_arch = target.cpu.arch;
817 const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];821 const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];
818822
819 const capacity = math.cast(usize, stub_helper_header.size) orelse return error.Overflow;823 const capacity = math.cast(usize, stub_helper_header.size) orelse return error.Overflow;
...@@ -856,7 +860,8 @@ fn writeStubHelpers(macho_file: *MachO) !void {...@@ -856,7 +860,8 @@ fn writeStubHelpers(macho_file: *MachO) !void {
856860
857fn writeLaSymbolPtrs(macho_file: *MachO) !void {861fn writeLaSymbolPtrs(macho_file: *MachO) !void {
858 const gpa = macho_file.base.allocator;862 const gpa = macho_file.base.allocator;
859 const cpu_arch = macho_file.base.options.target.cpu.arch;863 const target = macho_file.base.comp.root_mod.resolved_target.result;
864 const cpu_arch = target.cpu.arch;
860 const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];865 const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];
861 const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];866 const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];
862867
...@@ -964,11 +969,12 @@ fn pruneAndSortSections(macho_file: *MachO) !void {...@@ -964,11 +969,12 @@ fn pruneAndSortSections(macho_file: *MachO) !void {
964}969}
965970
966fn calcSectionSizes(macho_file: *MachO) !void {971fn calcSectionSizes(macho_file: *MachO) !void {
972 const target = macho_file.base.comp.root_mod.resolved_target.result;
967 const slice = macho_file.sections.slice();973 const slice = macho_file.sections.slice();
968 for (slice.items(.header), 0..) |*header, sect_id| {974 for (slice.items(.header), 0..) |*header, sect_id| {
969 if (header.size == 0) continue;975 if (header.size == 0) continue;
970 if (macho_file.text_section_index) |txt| {976 if (macho_file.text_section_index) |txt| {
971 if (txt == sect_id and macho_file.base.options.target.cpu.arch == .aarch64) continue;977 if (txt == sect_id and target.cpu.arch == .aarch64) continue;
972 }978 }
973979
974 var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;980 var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
...@@ -991,7 +997,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {...@@ -991,7 +997,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
991 }997 }
992 }998 }
993999
994 if (macho_file.text_section_index != null and macho_file.base.options.target.cpu.arch == .aarch64) {1000 if (macho_file.text_section_index != null and target.cpu.arch == .aarch64) {
995 // Create jump/branch range extenders if needed.1001 // Create jump/branch range extenders if needed.
996 try thunks.createThunks(macho_file, macho_file.text_section_index.?);1002 try thunks.createThunks(macho_file, macho_file.text_section_index.?);
997 }1003 }
...@@ -1043,7 +1049,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {...@@ -1043,7 +1049,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
1043 header.@"align" = 3;1049 header.@"align" = 3;
1044 }1050 }
10451051
1046 const cpu_arch = macho_file.base.options.target.cpu.arch;1052 const cpu_arch = target.cpu.arch;
10471053
1048 if (macho_file.stubs_section_index) |sect_id| {1054 if (macho_file.stubs_section_index) |sect_id| {
1049 const header = &macho_file.sections.items(.header)[sect_id];1055 const header = &macho_file.sections.items(.header)[sect_id];
...@@ -1093,6 +1099,7 @@ fn getSegmentAllocBase(macho_file: *MachO, segment_index: u8) struct { vmaddr: u...@@ -1093,6 +1099,7 @@ fn getSegmentAllocBase(macho_file: *MachO, segment_index: u8) struct { vmaddr: u
1093}1099}
10941100
1095fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void {1101fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void {
1102 const target = macho_file.base.comp.root_mod.resolved_target.result;
1096 const segment = &macho_file.segments.items[segment_index];1103 const segment = &macho_file.segments.items[segment_index];
10971104
1098 if (mem.eql(u8, segment.segName(), "__PAGEZERO")) return; // allocated upon creation1105 if (mem.eql(u8, segment.segName(), "__PAGEZERO")) return; // allocated upon creation
...@@ -1175,7 +1182,7 @@ fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void...@@ -1175,7 +1182,7 @@ fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void
1175 segment.vmsize = start;1182 segment.vmsize = start;
1176 }1183 }
11771184
1178 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);1185 const page_size = MachO.getPageSize(target.cpu.arch);
1179 segment.filesize = mem.alignForward(u64, segment.filesize, page_size);1186 segment.filesize = mem.alignForward(u64, segment.filesize, page_size);
1180 segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size);1187 segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size);
1181}1188}
src/link/Plan9.zig+30-25
...@@ -206,7 +206,8 @@ pub const Atom = struct {...@@ -206,7 +206,8 @@ pub const Atom = struct {
206206
207 // asserts that self.got_index != null207 // asserts that self.got_index != null
208 pub fn getOffsetTableAddress(self: Atom, plan9: *Plan9) u64 {208 pub fn getOffsetTableAddress(self: Atom, plan9: *Plan9) u64 {
209 const ptr_bytes = @divExact(plan9.base.options.target.ptrBitWidth(), 8);209 const target = plan9.base.comp.root_mod.resolved_target.result;
210 const ptr_bytes = @divExact(target.ptrBitWidth(), 8);
210 const got_addr = plan9.bases.data;211 const got_addr = plan9.bases.data;
211 const got_index = self.got_index.?;212 const got_index = self.got_index.?;
212 return got_addr + got_index * ptr_bytes;213 return got_addr + got_index * ptr_bytes;
...@@ -293,9 +294,11 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {...@@ -293,9 +294,11 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {
293 };294 };
294}295}
295296
296pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {297pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Plan9 {
297 if (options.use_llvm)298 _ = arena;
298 return error.LLVMBackendDoesNotSupportPlan9;299 const target = options.comp.root_mod.resolved_target.result;
300 const gpa = options.comp.gpa;
301
299 const sixtyfour_bit: bool = switch (options.target.ptrBitWidth()) {302 const sixtyfour_bit: bool = switch (options.target.ptrBitWidth()) {
300 0...32 => false,303 0...32 => false,
301 33...64 => true,304 33...64 => true,
...@@ -315,7 +318,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {...@@ -315,7 +318,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {
315 },318 },
316 .sixtyfour_bit = sixtyfour_bit,319 .sixtyfour_bit = sixtyfour_bit,
317 .bases = undefined,320 .bases = undefined,
318 .magic = try aout.magicFromArch(self.base.options.target.cpu.arch),321 .magic = try aout.magicFromArch(target.cpu.arch),
319 };322 };
320 // a / will always be in a file path323 // a / will always be in a file path
321 try self.file_segments.put(gpa, "/", 1);324 try self.file_segments.put(gpa, "/", 1);
...@@ -399,6 +402,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:...@@ -399,6 +402,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
399 }402 }
400403
401 const gpa = self.base.comp.gpa;404 const gpa = self.base.comp.gpa;
405 const target = self.base.comp.root_mod.resolved_target.result;
402 const func = mod.funcInfo(func_index);406 const func = mod.funcInfo(func_index);
403 const decl_index = func.owner_decl;407 const decl_index = func.owner_decl;
404 const decl = mod.declPtr(decl_index);408 const decl = mod.declPtr(decl_index);
...@@ -414,7 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:...@@ -414,7 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
414 .end_line = undefined,418 .end_line = undefined,
415 .pcop_change_index = null,419 .pcop_change_index = null,
416 // we have already checked the target in the linker to make sure it is compatable420 // we have already checked the target in the linker to make sure it is compatable
417 .pc_quanta = aout.getPCQuant(self.base.options.target.cpu.arch) catch unreachable,421 .pc_quanta = aout.getPCQuant(target.cpu.arch) catch unreachable,
418 };422 };
419 defer dbg_info_output.dbg_line.deinit();423 defer dbg_info_output.dbg_line.deinit();
420424
...@@ -658,6 +662,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -658,6 +662,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
658 }662 }
659663
660 const gpa = comp.gpa;664 const gpa = comp.gpa;
665 const target = comp.root_mod.resolved_target.result;
661666
662 const tracy = trace(@src());667 const tracy = trace(@src());
663 defer tracy.end();668 defer tracy.end();
...@@ -749,9 +754,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -749,9 +754,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
749 atom.offset = off;754 atom.offset = off;
750 log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });755 log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
751 if (!self.sixtyfour_bit) {756 if (!self.sixtyfour_bit) {
752 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());757 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
753 } else {758 } else {
754 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());759 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
755 }760 }
756 self.syms.items[atom.sym_index.?].value = off;761 self.syms.items[atom.sym_index.?].value = off;
757 if (mod.decl_exports.get(decl_index)) |exports| {762 if (mod.decl_exports.get(decl_index)) |exports| {
...@@ -778,9 +783,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -778,9 +783,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
778 text_i += code.len;783 text_i += code.len;
779 text_atom.offset = off;784 text_atom.offset = off;
780 if (!self.sixtyfour_bit) {785 if (!self.sixtyfour_bit) {
781 mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());786 mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
782 } else {787 } else {
783 mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());788 mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
784 }789 }
785 self.syms.items[text_atom.sym_index.?].value = off;790 self.syms.items[text_atom.sym_index.?].value = off;
786 }791 }
...@@ -791,9 +796,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -791,9 +796,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
791 const val = self.getAddr(text_i, .t);796 const val = self.getAddr(text_i, .t);
792 self.syms.items[etext_atom.sym_index.?].value = val;797 self.syms.items[etext_atom.sym_index.?].value = val;
793 if (!self.sixtyfour_bit) {798 if (!self.sixtyfour_bit) {
794 mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());799 mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
795 } else {800 } else {
796 mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());801 mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
797 }802 }
798 }803 }
799 // global offset table is in data804 // global offset table is in data
...@@ -815,9 +820,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -815,9 +820,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
815 data_i += code.len;820 data_i += code.len;
816 atom.offset = off;821 atom.offset = off;
817 if (!self.sixtyfour_bit) {822 if (!self.sixtyfour_bit) {
818 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());823 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
819 } else {824 } else {
820 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());825 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
821 }826 }
822 self.syms.items[atom.sym_index.?].value = off;827 self.syms.items[atom.sym_index.?].value = off;
823 if (mod.decl_exports.get(decl_index)) |exports| {828 if (mod.decl_exports.get(decl_index)) |exports| {
...@@ -838,9 +843,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -838,9 +843,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
838 data_i += code.len;843 data_i += code.len;
839 atom.offset = off;844 atom.offset = off;
840 if (!self.sixtyfour_bit) {845 if (!self.sixtyfour_bit) {
841 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());846 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
842 } else {847 } else {
843 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());848 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
844 }849 }
845 self.syms.items[atom.sym_index.?].value = off;850 self.syms.items[atom.sym_index.?].value = off;
846 }851 }
...@@ -859,9 +864,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -859,9 +864,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
859 data_i += code.len;864 data_i += code.len;
860 atom.offset = off;865 atom.offset = off;
861 if (!self.sixtyfour_bit) {866 if (!self.sixtyfour_bit) {
862 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());867 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
863 } else {868 } else {
864 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());869 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
865 }870 }
866 self.syms.items[atom.sym_index.?].value = off;871 self.syms.items[atom.sym_index.?].value = off;
867 }872 }
...@@ -879,9 +884,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -879,9 +884,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
879 data_i += code.len;884 data_i += code.len;
880 data_atom.offset = off;885 data_atom.offset = off;
881 if (!self.sixtyfour_bit) {886 if (!self.sixtyfour_bit) {
882 mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());887 mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
883 } else {888 } else {
884 mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());889 mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
885 }890 }
886 self.syms.items[data_atom.sym_index.?].value = off;891 self.syms.items[data_atom.sym_index.?].value = off;
887 }892 }
...@@ -891,9 +896,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -891,9 +896,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
891 const val = self.getAddr(data_i, .b);896 const val = self.getAddr(data_i, .b);
892 self.syms.items[edata_atom.sym_index.?].value = val;897 self.syms.items[edata_atom.sym_index.?].value = val;
893 if (!self.sixtyfour_bit) {898 if (!self.sixtyfour_bit) {
894 mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());899 mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
895 } else {900 } else {
896 mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());901 mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
897 }902 }
898 }903 }
899 // end symbol (same as edata because native backends don't do .bss yet)904 // end symbol (same as edata because native backends don't do .bss yet)
...@@ -902,10 +907,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -902,10 +907,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
902 const val = self.getAddr(data_i, .b);907 const val = self.getAddr(data_i, .b);
903 self.syms.items[end_atom.sym_index.?].value = val;908 self.syms.items[end_atom.sym_index.?].value = val;
904 if (!self.sixtyfour_bit) {909 if (!self.sixtyfour_bit) {
905 mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());910 mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
906 } else {911 } else {
907 log.debug("write end (got_table[0x{x}] = 0x{x})", .{ end_atom.got_index.? * 8, val });912 log.debug("write end (got_table[0x{x}] = 0x{x})", .{ end_atom.got_index.? * 8, val });
908 mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());913 mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
909 }914 }
910 }915 }
911 }916 }
...@@ -942,7 +947,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -942,7 +947,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
942 const source_atom = self.getAtom(source_atom_index);947 const source_atom = self.getAtom(source_atom_index);
943 const source_atom_symbol = self.syms.items[source_atom.sym_index.?];948 const source_atom_symbol = self.syms.items[source_atom.sym_index.?];
944 const code = source_atom.code.getCode(self);949 const code = source_atom.code.getCode(self);
945 const endian = self.base.options.target.cpu.arch.endian();950 const endian = target.cpu.arch.endian();
946 for (kv.value_ptr.items) |reloc| {951 for (kv.value_ptr.items) |reloc| {
947 const offset = reloc.offset;952 const offset = reloc.offset;
948 const addend = reloc.addend;953 const addend = reloc.addend;
src/link/Wasm.zig+7-4
...@@ -1119,7 +1119,8 @@ fn validateFeatures(...@@ -1119,7 +1119,8 @@ fn validateFeatures(
1119 to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool,1119 to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool,
1120 emit_features_count: *u32,1120 emit_features_count: *u32,
1121) !void {1121) !void {
1122 const cpu_features = wasm.base.options.target.cpu.features;1122 const target = wasm.base.comp.root_mod.resolved_target.result;
1123 const cpu_features = target.cpu.features;
1123 const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects.1124 const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects.
1124 const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len;1125 const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len;
11251126
...@@ -1752,6 +1753,7 @@ pub fn getDeclVAddr(...@@ -1752,6 +1753,7 @@ pub fn getDeclVAddr(
1752 decl_index: InternPool.DeclIndex,1753 decl_index: InternPool.DeclIndex,
1753 reloc_info: link.File.RelocInfo,1754 reloc_info: link.File.RelocInfo,
1754) !u64 {1755) !u64 {
1756 const target = wasm.base.comp.root_mod.resolved_target.result;
1755 const gpa = wasm.base.comp.gpa;1757 const gpa = wasm.base.comp.gpa;
1756 const mod = wasm.base.comp.module.?;1758 const mod = wasm.base.comp.module.?;
1757 const decl = mod.declPtr(decl_index);1759 const decl = mod.declPtr(decl_index);
...@@ -1762,7 +1764,7 @@ pub fn getDeclVAddr(...@@ -1762,7 +1764,7 @@ pub fn getDeclVAddr(
1762 assert(reloc_info.parent_atom_index != 0);1764 assert(reloc_info.parent_atom_index != 0);
1763 const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;1765 const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
1764 const atom = wasm.getAtomPtr(atom_index);1766 const atom = wasm.getAtomPtr(atom_index);
1765 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;1767 const is_wasm32 = target.cpu.arch == .wasm32;
1766 if (decl.ty.zigTypeTag(mod) == .Fn) {1768 if (decl.ty.zigTypeTag(mod) == .Fn) {
1767 assert(reloc_info.addend == 0); // addend not allowed for function relocations1769 assert(reloc_info.addend == 0); // addend not allowed for function relocations
1768 // We found a function pointer, so add it to our table,1770 // We found a function pointer, so add it to our table,
...@@ -1825,12 +1827,13 @@ pub fn lowerAnonDecl(...@@ -1825,12 +1827,13 @@ pub fn lowerAnonDecl(
18251827
1826pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1828pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1827 const gpa = wasm.base.comp.gpa;1829 const gpa = wasm.base.comp.gpa;
1830 const target = wasm.base.comp.root_mod.resolved_target.result;
1828 const atom_index = wasm.anon_decls.get(decl_val).?;1831 const atom_index = wasm.anon_decls.get(decl_val).?;
1829 const target_symbol_index = wasm.getAtom(atom_index).getSymbolIndex().?;1832 const target_symbol_index = wasm.getAtom(atom_index).getSymbolIndex().?;
18301833
1831 const parent_atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;1834 const parent_atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
1832 const parent_atom = wasm.getAtomPtr(parent_atom_index);1835 const parent_atom = wasm.getAtomPtr(parent_atom_index);
1833 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;1836 const is_wasm32 = target.cpu.arch == .wasm32;
1834 const mod = wasm.base.comp.module.?;1837 const mod = wasm.base.comp.module.?;
1835 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));1838 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
1836 if (ty.zigTypeTag(mod) == .Fn) {1839 if (ty.zigTypeTag(mod) == .Fn) {
...@@ -4557,7 +4560,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !...@@ -4557,7 +4560,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
4557 break :blk null;4560 break :blk null;
4558 };4561 };
45594562
4560 const target = wasm.base.options.target;4563 const target = wasm.base.comp.root_mod.resolved_target.result;
45614564
4562 const id_symlink_basename = "lld.id";4565 const id_symlink_basename = "lld.id";
45634566