| ... | ... | @@ -808,8 +808,14 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 808 | 808 | sect.size -= atom.size; |
| 809 | 809 | } |
| 810 | 810 | for (self.stubs.items) |_| { |
| 811 | | const atom = try self.createStubHelperAtom(); |
| 812 | | try self.allocateAtomStage1(atom, .{ |
| 811 | const stub_atom = try self.createStubHelperAtom(); |
| 812 | try self.allocateAtomStage1(stub_atom, .{ |
| 813 | .seg = self.text_segment_cmd_index.?, |
| 814 | .sect = self.stub_helper_section_index.?, |
| 815 | }); |
| 816 | |
| 817 | const laptr_atom = try self.createLazyPointerAtom(stub_atom.local_sym_index); |
| 818 | try self.allocateAtomStage1(laptr_atom, .{ |
| 813 | 819 | .seg = self.text_segment_cmd_index.?, |
| 814 | 820 | .sect = self.stub_helper_section_index.?, |
| 815 | 821 | }); |
| ... | ... | @@ -1767,16 +1773,9 @@ fn allocateDataConstSegment(self: *MachO) !void { |
| 1767 | 1773 | |
| 1768 | 1774 | fn allocateDataSegment(self: *MachO) !void { |
| 1769 | 1775 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1770 | | const nstubs = @intCast(u32, self.stubs.items.len); |
| 1771 | | |
| 1772 | 1776 | const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1773 | 1777 | seg.inner.fileoff = data_const_seg.inner.fileoff + data_const_seg.inner.filesize; |
| 1774 | 1778 | seg.inner.vmaddr = data_const_seg.inner.vmaddr + data_const_seg.inner.vmsize; |
| 1775 | | |
| 1776 | | // Set la_symbol_ptr |
| 1777 | | const la_symbol_ptr = &seg.sections.items[self.la_symbol_ptr_section_index.?]; |
| 1778 | | la_symbol_ptr.size += nstubs * @sizeOf(u64); |
| 1779 | | |
| 1780 | 1779 | try self.allocateSegment(self.data_segment_cmd_index.?, 0); |
| 1781 | 1780 | } |
| 1782 | 1781 | |
| ... | ... | @@ -2241,6 +2240,35 @@ fn createStubHelperAtom(self: *MachO) !*TextBlock { |
| 2241 | 2240 | return atom; |
| 2242 | 2241 | } |
| 2243 | 2242 | |
| 2243 | fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32) !*TextBlock { |
| 2244 | const local_sym_index = @intCast(u32, self.locals.items.len); |
| 2245 | try self.locals.append(self.base.allocator, .{ |
| 2246 | .n_strx = try self.makeString("lazy_ptr"), |
| 2247 | .n_type = macho.N_SECT, |
| 2248 | .n_sect = 0, |
| 2249 | .n_desc = 0, |
| 2250 | .n_value = 0, |
| 2251 | }); |
| 2252 | const atom = try self.createEmptyAtom(.{ |
| 2253 | .seg = self.data_segment_cmd_index.?, |
| 2254 | .sect = self.la_symbol_ptr_section_index.?, |
| 2255 | }, local_sym_index, @sizeOf(u64), 3); |
| 2256 | try atom.relocs.append(self.base.allocator, .{ |
| 2257 | .offset = 0, |
| 2258 | .where = .local, |
| 2259 | .where_index = stub_sym_index, |
| 2260 | .payload = .{ |
| 2261 | .unsigned = .{ |
| 2262 | .subtractor = null, |
| 2263 | .addend = 0, |
| 2264 | .is_64bit = true, |
| 2265 | }, |
| 2266 | }, |
| 2267 | }); |
| 2268 | self.lazy_binding_info_dirty = true; |
| 2269 | return atom; |
| 2270 | } |
| 2271 | |
| 2244 | 2272 | fn resolveSymbolsInObject( |
| 2245 | 2273 | self: *MachO, |
| 2246 | 2274 | object_id: u16, |
| ... | ... | @@ -2731,7 +2759,6 @@ fn flushZld(self: *MachO) !void { |
| 2731 | 2759 | for (self.stubs.items) |_, i| { |
| 2732 | 2760 | const index = @intCast(u32, i); |
| 2733 | 2761 | // TODO weak bound pointers |
| 2734 | | try self.writeLazySymbolPointer(index); |
| 2735 | 2762 | try self.writeStub(index); |
| 2736 | 2763 | } |
| 2737 | 2764 | |
| ... | ... | @@ -4633,26 +4660,6 @@ fn writeGotEntry(self: *MachO, index: usize) !void { |
| 4633 | 4660 | try self.base.file.?.pwriteAll(mem.asBytes(&sym.n_value), off); |
| 4634 | 4661 | } |
| 4635 | 4662 | |
| 4636 | | fn writeLazySymbolPointer(self: *MachO, index: u32) !void { |
| 4637 | | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4638 | | const stub_helper = text_segment.sections.items[self.stub_helper_section_index.?]; |
| 4639 | | const data_segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 4640 | | const la_symbol_ptr = data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 4641 | | |
| 4642 | | const stub_size: u4 = switch (self.base.options.target.cpu.arch) { |
| 4643 | | .x86_64 => 10, |
| 4644 | | .aarch64 => 3 * @sizeOf(u32), |
| 4645 | | else => unreachable, |
| 4646 | | }; |
| 4647 | | const stub_off = self.stub_helper_stubs_start_off.? + index * stub_size; |
| 4648 | | const end = stub_helper.addr + stub_off - stub_helper.offset; |
| 4649 | | var buf: [@sizeOf(u64)]u8 = undefined; |
| 4650 | | mem.writeIntLittle(u64, &buf, end); |
| 4651 | | const off = la_symbol_ptr.offset + index * @sizeOf(u64); |
| 4652 | | log.debug("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off }); |
| 4653 | | try self.base.file.?.pwriteAll(&buf, off); |
| 4654 | | } |
| 4655 | | |
| 4656 | 4663 | fn writeStub(self: *MachO, index: u32) !void { |
| 4657 | 4664 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4658 | 4665 | const stubs = text_segment.sections.items[self.stubs_section_index.?]; |