authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-23 23:01:14+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-23 23:01:14+02:00
log9e7b2fb894cf4021ec188fbb64b11d750f4354fa
tree8afb2d2f03fab15b629af9b55e4c9167ebf62735
parent799c5bb9551dafd76f9d1fce7d3f5a01ac55da83

macho: add routine for creating lazy pointer for stub


1 files changed, 37 insertions(+), 30 deletions(-)

src/link/MachO.zig+37-30
...@@ -808,8 +808,14 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {...@@ -808,8 +808,14 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {
808 sect.size -= atom.size;808 sect.size -= atom.size;
809 }809 }
810 for (self.stubs.items) |_| {810 for (self.stubs.items) |_| {
811 const atom = try self.createStubHelperAtom();811 const stub_atom = try self.createStubHelperAtom();
812 try self.allocateAtomStage1(atom, .{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 .seg = self.text_segment_cmd_index.?,819 .seg = self.text_segment_cmd_index.?,
814 .sect = self.stub_helper_section_index.?,820 .sect = self.stub_helper_section_index.?,
815 });821 });
...@@ -1767,16 +1773,9 @@ fn allocateDataConstSegment(self: *MachO) !void {...@@ -1767,16 +1773,9 @@ fn allocateDataConstSegment(self: *MachO) !void {
17671773
1768fn allocateDataSegment(self: *MachO) !void {1774fn allocateDataSegment(self: *MachO) !void {
1769 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;1775 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1770 const nstubs = @intCast(u32, self.stubs.items.len);
1771
1772 const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;1776 const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
1773 seg.inner.fileoff = data_const_seg.inner.fileoff + data_const_seg.inner.filesize;1777 seg.inner.fileoff = data_const_seg.inner.fileoff + data_const_seg.inner.filesize;
1774 seg.inner.vmaddr = data_const_seg.inner.vmaddr + data_const_seg.inner.vmsize;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 try self.allocateSegment(self.data_segment_cmd_index.?, 0);1779 try self.allocateSegment(self.data_segment_cmd_index.?, 0);
1781}1780}
17821781
...@@ -2241,6 +2240,35 @@ fn createStubHelperAtom(self: *MachO) !*TextBlock {...@@ -2241,6 +2240,35 @@ fn createStubHelperAtom(self: *MachO) !*TextBlock {
2241 return atom;2240 return atom;
2242}2241}
22432242
2243fn 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
2244fn resolveSymbolsInObject(2272fn resolveSymbolsInObject(
2245 self: *MachO,2273 self: *MachO,
2246 object_id: u16,2274 object_id: u16,
...@@ -2731,7 +2759,6 @@ fn flushZld(self: *MachO) !void {...@@ -2731,7 +2759,6 @@ fn flushZld(self: *MachO) !void {
2731 for (self.stubs.items) |_, i| {2759 for (self.stubs.items) |_, i| {
2732 const index = @intCast(u32, i);2760 const index = @intCast(u32, i);
2733 // TODO weak bound pointers2761 // TODO weak bound pointers
2734 try self.writeLazySymbolPointer(index);
2735 try self.writeStub(index);2762 try self.writeStub(index);
2736 }2763 }
27372764
...@@ -4633,26 +4660,6 @@ fn writeGotEntry(self: *MachO, index: usize) !void {...@@ -4633,26 +4660,6 @@ fn writeGotEntry(self: *MachO, index: usize) !void {
4633 try self.base.file.?.pwriteAll(mem.asBytes(&sym.n_value), off);4660 try self.base.file.?.pwriteAll(mem.asBytes(&sym.n_value), off);
4634}4661}
46354662
4636fn 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
4656fn writeStub(self: *MachO, index: u32) !void {4663fn writeStub(self: *MachO, index: u32) !void {
4657 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;4664 const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
4658 const stubs = text_segment.sections.items[self.stubs_section_index.?];4665 const stubs = text_segment.sections.items[self.stubs_section_index.?];