diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 05f26746f6..d4d684cde6 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -2162,7 +2162,7 @@ fn calcSectionSizes(self: *MachO) !void { const header = &self.sections.items(.header)[idx]; header.size = self.stubs.size(self); header.@"align" = switch (cpu_arch) { - .x86_64 => 0, + .x86_64 => 1, .aarch64 => 2, else => 0, }; @@ -2171,11 +2171,7 @@ fn calcSectionSizes(self: *MachO) !void { if (self.stubs_helper_sect_index) |idx| { const header = &self.sections.items(.header)[idx]; header.size = self.stubs_helper.size(self); - header.@"align" = switch (cpu_arch) { - .x86_64 => 0, - .aarch64 => 2, - else => 0, - }; + header.@"align" = 2; } if (self.la_symbol_ptr_sect_index) |idx| { diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig index dfdb81c605..e8a8a561b7 100644 --- a/src/link/MachO/Symbol.zig +++ b/src/link/MachO/Symbol.zig @@ -223,7 +223,7 @@ pub fn setOutputSym(symbol: Symbol, macho_file: *MachO, out: *macho.nlist_64) vo out.n_type = if (symbol.flags.abs) macho.N_ABS else macho.N_SECT; out.n_sect = if (symbol.flags.abs) 0 else @intCast(symbol.out_n_sect + 1); out.n_desc = 0; - out.n_value = symbol.getAddress(.{}, macho_file); + out.n_value = symbol.getAddress(.{ .stubs = false }, macho_file); switch (symbol.visibility) { .hidden => out.n_type |= macho.N_PEXT, @@ -234,7 +234,7 @@ pub fn setOutputSym(symbol: Symbol, macho_file: *MachO, out: *macho.nlist_64) vo out.n_type = macho.N_EXT; out.n_type |= if (symbol.flags.abs) macho.N_ABS else macho.N_SECT; out.n_sect = if (symbol.flags.abs) 0 else @intCast(symbol.out_n_sect + 1); - out.n_value = symbol.getAddress(.{}, macho_file); + out.n_value = symbol.getAddress(.{ .stubs = false }, macho_file); out.n_desc = 0; if (symbol.flags.weak) { diff --git a/src/link/MachO/dyld_info/Rebase.zig b/src/link/MachO/dyld_info/Rebase.zig index 776d144754..c0cda1584a 100644 --- a/src/link/MachO/dyld_info/Rebase.zig +++ b/src/link/MachO/dyld_info/Rebase.zig @@ -12,7 +12,7 @@ const Allocator = std.mem.Allocator; entries: std.ArrayListUnmanaged(Entry) = .{}, buffer: std.ArrayListUnmanaged(u8) = .{}, -const Entry = struct { +pub const Entry = struct { offset: u64, segment_id: u8, diff --git a/src/link/MachO/synthetic.zig b/src/link/MachO/synthetic.zig index 882db5d414..f8ad741d27 100644 --- a/src/link/MachO/synthetic.zig +++ b/src/link/MachO/synthetic.zig @@ -315,7 +315,7 @@ pub const StubsSection = struct { pub const StubsHelperSection = struct { pub inline fn preambleSize(cpu_arch: std.Target.Cpu.Arch) usize { return switch (cpu_arch) { - .x86_64 => 15, + .x86_64 => 16, .aarch64 => 6 * @sizeOf(u32), else => 0, }; @@ -408,6 +408,7 @@ pub const StubsHelperSection = struct { try writer.writeInt(i32, @intCast(dyld_private_addr - sect.addr - 3 - 4), .little); try writer.writeAll(&.{ 0x41, 0x53, 0xff, 0x25 }); try writer.writeInt(i32, @intCast(dyld_stub_binder_addr - sect.addr - 11 - 4), .little); + try writer.writeByte(0x90); }, .aarch64 => { { @@ -460,7 +461,11 @@ pub const LaSymbolPtrSection = struct { for (macho_file.stubs.symbols.items, 0..) |sym_index, idx| { const sym = macho_file.getSymbol(sym_index); const addr = sect.addr + idx * @sizeOf(u64); - const entry = bind.Entry{ + const rebase_entry = Rebase.Entry{ + .offset = addr - seg.vmaddr, + .segment_id = seg_id, + }; + const bind_entry = bind.Entry{ .target = sym_index, .offset = addr - seg.vmaddr, .segment_id = seg_id, @@ -468,20 +473,19 @@ pub const LaSymbolPtrSection = struct { }; if (sym.flags.import) { if (sym.flags.weak) { - try macho_file.bind.entries.append(gpa, entry); - try macho_file.weak_bind.entries.append(gpa, entry); + try macho_file.bind.entries.append(gpa, bind_entry); + try macho_file.weak_bind.entries.append(gpa, bind_entry); } else { - try macho_file.lazy_bind.entries.append(gpa, entry); + try macho_file.lazy_bind.entries.append(gpa, bind_entry); + try macho_file.rebase.entries.append(gpa, rebase_entry); } } else { if (sym.flags.weak) { - try macho_file.rebase.entries.append(gpa, .{ - .offset = addr - seg.vmaddr, - .segment_id = seg_id, - }); - try macho_file.weak_bind.entries.append(gpa, entry); + try macho_file.rebase.entries.append(gpa, rebase_entry); + try macho_file.weak_bind.entries.append(gpa, bind_entry); } else if (sym.flags.interposable) { - try macho_file.lazy_bind.entries.append(gpa, entry); + try macho_file.lazy_bind.entries.append(gpa, bind_entry); + try macho_file.rebase.entries.append(gpa, rebase_entry); } } } @@ -493,15 +497,19 @@ pub const LaSymbolPtrSection = struct { _ = laptr; const cpu_arch = macho_file.getTarget().cpu.arch; const sect = macho_file.sections.items(.header)[macho_file.stubs_helper_sect_index.?]; - for (macho_file.stubs.symbols.items, 0..) |sym_index, idx| { + var stub_helper_idx: u32 = 0; + for (macho_file.stubs.symbols.items) |sym_index| { const sym = macho_file.getSymbol(sym_index); const value: u64 = if (sym.flags.@"export") sym.getAddress(.{ .stubs = false }, macho_file) else if (sym.flags.weak) @as(u64, 0) - else - sect.addr + StubsHelperSection.preambleSize(cpu_arch) + - StubsHelperSection.entrySize(cpu_arch) * idx; + else value: { + const value = sect.addr + StubsHelperSection.preambleSize(cpu_arch) + + StubsHelperSection.entrySize(cpu_arch) * stub_helper_idx; + stub_helper_idx += 1; + break :value value; + }; try writer.writeInt(u64, @intCast(value), .little); } }