From f4da8145358cccd92018838a6f890f3a229f7df8 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 19 Jan 2024 17:26:47 +0100 Subject: [PATCH] macho: init linkedit segment separately --- src/link/MachO.zig | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 93961c653f..8011786fd7 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -592,6 +592,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node self.allocateAtoms(); self.allocateSyntheticSymbols(); + try self.initLinkeditSegment(); + state_log.debug("{}", .{self.dumpState()}); try self.initDyldInfoSections(); @@ -2167,18 +2169,6 @@ fn initSegments(self: *MachO) !void { }); } - // Add __LINKEDIT - { - const protection = getSegmentProt("__LINKEDIT"); - self.linkedit_seg_index = @intCast(self.segments.items.len); - try self.segments.append(gpa, .{ - .cmdsize = @sizeOf(macho.segment_command_64), - .segname = makeStaticString("__LINKEDIT"), - .maxprot = protection, - .initprot = protection, - }); - } - // __TEXT segment is non-optional if (self.getSegmentByName("__TEXT") == null) { const protection = getSegmentProt("__TEXT"); @@ -2222,7 +2212,6 @@ fn initSegments(self: *MachO) !void { self.pagezero_seg_index = self.getSegmentByName("__PAGEZERO"); self.text_seg_index = self.getSegmentByName("__TEXT").?; - self.linkedit_seg_index = self.getSegmentByName("__LINKEDIT").?; } fn allocateSections(self: *MachO) !void { @@ -2401,6 +2390,23 @@ fn allocateSyntheticSymbols(self: *MachO) void { } } +fn initLinkeditSegment(self: *MachO) !void { + var fileoff: u64 = 0; + var vmaddr: u64 = 0; + + for (self.segments.items) |seg| { + if (fileoff < seg.fileoff + seg.filesize) fileoff = seg.fileoff + seg.filesize; + if (vmaddr < seg.vmaddr + seg.vmsize) vmaddr = seg.vmaddr + seg.vmsize; + } + + const page_size = self.getPageSize(); + self.linkedit_seg_index = try self.addSegment("__LINKEDIT", .{ + .vmaddr = mem.alignForward(u64, vmaddr, page_size), + .fileoff = mem.alignForward(u64, fileoff, page_size), + .prot = getSegmentProt("__LINKEDIT"), + }); +} + fn initDyldInfoSections(self: *MachO) !void { const tracy = trace(@src()); defer tracy.end();