Commit b2773cd712

Jakub Konka <kubkon@jakubkonka.com>
2023-08-26 08:13:41
macho: move initSection into MachO from Zld
1 parent 180979e
Changed files (4)
src/link/MachO/Atom.zig
@@ -106,6 +106,7 @@ pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
 }
 
 pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
+    const gpa = zld.gpa;
     const segname = sect.segName();
     const sectname = sect.sectName();
     const res: ?u8 = blk: {
@@ -126,7 +127,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
 
         if (sect.isCode()) {
             if (zld.text_section_index == null) {
-                zld.text_section_index = try zld.initSection(
+                zld.text_section_index = try MachO.initSection(
+                    gpa,
+                    zld,
                     "__TEXT",
                     "__text",
                     .{
@@ -148,7 +151,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
             macho.S_8BYTE_LITERALS,
             macho.S_16BYTE_LITERALS,
             => {
-                break :blk zld.getSectionByName("__TEXT", "__const") orelse try zld.initSection(
+                break :blk zld.getSectionByName("__TEXT", "__const") orelse try MachO.initSection(
+                    gpa,
+                    zld,
                     "__TEXT",
                     "__const",
                     .{},
@@ -156,13 +161,17 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
             },
             macho.S_CSTRING_LITERALS => {
                 if (mem.startsWith(u8, sectname, "__objc")) {
-                    break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
+                    break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
+                        gpa,
+                        zld,
                         segname,
                         sectname,
                         .{},
                     );
                 }
-                break :blk zld.getSectionByName("__TEXT", "__cstring") orelse try zld.initSection(
+                break :blk zld.getSectionByName("__TEXT", "__cstring") orelse try MachO.initSection(
+                    gpa,
+                    zld,
                     "__TEXT",
                     "__cstring",
                     .{ .flags = macho.S_CSTRING_LITERALS },
@@ -171,7 +180,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
             macho.S_MOD_INIT_FUNC_POINTERS,
             macho.S_MOD_TERM_FUNC_POINTERS,
             => {
-                break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try zld.initSection(
+                break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try MachO.initSection(
+                    gpa,
+                    zld,
                     "__DATA_CONST",
                     sectname,
                     .{ .flags = sect.flags },
@@ -184,14 +195,19 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
             macho.S_THREAD_LOCAL_REGULAR,
             macho.S_THREAD_LOCAL_ZEROFILL,
             => {
-                break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
+                break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
+                    gpa,
+                    zld,
                     segname,
                     sectname,
                     .{ .flags = sect.flags },
                 );
             },
             macho.S_COALESCED => {
-                break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
+                break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
+                    gpa,
+                    zld,
+
                     segname,
                     sectname,
                     .{},
@@ -205,7 +221,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
                         mem.eql(u8, sectname, "__gosymtab") or
                         mem.eql(u8, sectname, "__gopclntab"))
                     {
-                        break :blk zld.getSectionByName("__TEXT", sectname) orelse try zld.initSection(
+                        break :blk zld.getSectionByName("__TEXT", sectname) orelse try MachO.initSection(
+                            gpa,
+                            zld,
                             "__TEXT",
                             sectname,
                             .{},
@@ -218,20 +236,26 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
                         mem.eql(u8, sectname, "__objc_classlist") or
                         mem.eql(u8, sectname, "__objc_imageinfo"))
                     {
-                        break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try zld.initSection(
+                        break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try MachO.initSection(
+                            gpa,
+                            zld,
                             "__DATA_CONST",
                             sectname,
                             .{},
                         );
                     } else if (mem.eql(u8, sectname, "__data")) {
-                        break :blk zld.getSectionByName("__DATA", "__data") orelse try zld.initSection(
+                        break :blk zld.getSectionByName("__DATA", "__data") orelse try MachO.initSection(
+                            gpa,
+                            zld,
                             "__DATA",
                             "__data",
                             .{},
                         );
                     }
                 }
-                break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection(
+                break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection(
+                    gpa,
+                    zld,
                     segname,
                     sectname,
                     .{},
src/link/MachO/Object.zig
@@ -685,11 +685,12 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void {
 
     log.debug("parsing __TEXT,__eh_frame section", .{});
 
+    const gpa = zld.gpa;
+
     if (zld.getSectionByName("__TEXT", "__eh_frame") == null) {
-        _ = try zld.initSection("__TEXT", "__eh_frame", .{});
+        _ = try MachO.initSection(gpa, zld, "__TEXT", "__eh_frame", .{});
     }
 
-    const gpa = zld.gpa;
     const cpu_arch = zld.options.target.cpu.arch;
     try self.parseRelocs(gpa, sect_id);
     const relocs = self.getRelocs(sect_id);
@@ -779,6 +780,8 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void {
 }
 
 fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
+    const gpa = zld.gpa;
+    const cpu_arch = zld.options.target.cpu.arch;
     const sect_id = self.unwind_info_sect_id orelse {
         // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`,
         // we will try fully synthesising unwind info records to somewhat match Apple ld's
@@ -786,7 +789,7 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
         // we still create the output `__TEXT,__unwind_info` section.
         if (self.hasEhFrameRecords()) {
             if (zld.getSectionByName("__TEXT", "__unwind_info") == null) {
-                _ = try zld.initSection("__TEXT", "__unwind_info", .{});
+                _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{});
             }
         }
         return;
@@ -794,11 +797,8 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
 
     log.debug("parsing unwind info in {s}", .{self.name});
 
-    const gpa = zld.gpa;
-    const cpu_arch = zld.options.target.cpu.arch;
-
     if (zld.getSectionByName("__TEXT", "__unwind_info") == null) {
-        _ = try zld.initSection("__TEXT", "__unwind_info", .{});
+        _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{});
     }
 
     const unwind_records = self.getUnwindRecords();
src/link/MachO/zld.zig
@@ -141,7 +141,7 @@ pub const Zld = struct {
         sym.n_type = macho.N_SECT;
 
         const sect_id = self.getSectionByName("__DATA", "__data") orelse
-            try self.initSection("__DATA", "__data", .{});
+            try MachO.initSection(self.gpa, self, "__DATA", "__data", .{});
         sym.n_sect = sect_id + 1;
         self.dyld_private_atom_index = atom_index;
 
@@ -165,7 +165,7 @@ pub const Zld = struct {
             const size = sym.n_value;
             const alignment = (sym.n_desc >> 8) & 0x0f;
             const sect_id = self.getSectionByName("__DATA", "__bss") orelse
-                try self.initSection("__DATA", "__bss", .{ .flags = macho.S_ZEROFILL });
+                try MachO.initSection(gpa, self, "__DATA", "__bss", .{ .flags = macho.S_ZEROFILL });
 
             sym.* = .{
                 .n_strx = sym.n_strx,
@@ -619,7 +619,7 @@ pub const Zld = struct {
         if (self.got_table.lookup.contains(target)) return;
         _ = try self.got_table.allocateEntry(self.gpa, target);
         if (self.got_section_index == null) {
-            self.got_section_index = try self.initSection("__DATA_CONST", "__got", .{
+            self.got_section_index = try MachO.initSection(self.gpa, self, "__DATA_CONST", "__got", .{
                 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
             });
         }
@@ -629,7 +629,7 @@ pub const Zld = struct {
         if (self.tlv_ptr_table.lookup.contains(target)) return;
         _ = try self.tlv_ptr_table.allocateEntry(self.gpa, target);
         if (self.tlv_ptr_section_index == null) {
-            self.tlv_ptr_section_index = try self.initSection("__DATA", "__thread_ptrs", .{
+            self.tlv_ptr_section_index = try MachO.initSection(self.gpa, self, "__DATA", "__thread_ptrs", .{
                 .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS,
             });
         }
@@ -639,18 +639,18 @@ pub const Zld = struct {
         if (self.stubs_table.lookup.contains(target)) return;
         _ = try self.stubs_table.allocateEntry(self.gpa, target);
         if (self.stubs_section_index == null) {
-            self.stubs_section_index = try self.initSection("__TEXT", "__stubs", .{
+            self.stubs_section_index = try MachO.initSection(self.gpa, self, "__TEXT", "__stubs", .{
                 .flags = macho.S_SYMBOL_STUBS |
                     macho.S_ATTR_PURE_INSTRUCTIONS |
                     macho.S_ATTR_SOME_INSTRUCTIONS,
                 .reserved2 = stubs.stubSize(self.options.target.cpu.arch),
             });
-            self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{
+            self.stub_helper_section_index = try MachO.initSection(self.gpa, self, "__TEXT", "__stub_helper", .{
                 .flags = macho.S_REGULAR |
                     macho.S_ATTR_PURE_INSTRUCTIONS |
                     macho.S_ATTR_SOME_INSTRUCTIONS,
             });
-            self.la_symbol_ptr_section_index = try self.initSection("__DATA", "__la_symbol_ptr", .{
+            self.la_symbol_ptr_section_index = try MachO.initSection(self.gpa, self, "__DATA", "__la_symbol_ptr", .{
                 .flags = macho.S_LAZY_SYMBOL_POINTERS,
             });
         }
@@ -1152,34 +1152,6 @@ pub const Zld = struct {
         segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size);
     }
 
-    const InitSectionOpts = struct {
-        flags: u32 = macho.S_REGULAR,
-        reserved1: u32 = 0,
-        reserved2: u32 = 0,
-    };
-
-    pub fn initSection(
-        self: *Zld,
-        segname: []const u8,
-        sectname: []const u8,
-        opts: InitSectionOpts,
-    ) !u8 {
-        const gpa = self.gpa;
-        log.debug("creating section '{s},{s}'", .{ segname, sectname });
-        const index = @as(u8, @intCast(self.sections.slice().len));
-        try self.sections.append(gpa, .{
-            .segment_index = undefined, // Segments will be created automatically later down the pipeline
-            .header = .{
-                .sectname = makeStaticString(sectname),
-                .segname = makeStaticString(segname),
-                .flags = opts.flags,
-                .reserved1 = opts.reserved1,
-                .reserved2 = opts.reserved2,
-            },
-        });
-        return index;
-    }
-
     fn writeSegmentHeaders(self: *Zld, writer: anytype) !void {
         for (self.segments.items, 0..) |seg, i| {
             const indexes = self.getSectionIndexes(@as(u8, @intCast(i)));
src/link/MachO.zig
@@ -2739,6 +2739,34 @@ fn calcPagezeroSize(self: *MachO) u64 {
     return aligned_pagezero_vmsize;
 }
 
+const InitSectionOpts = struct {
+    flags: u32 = macho.S_REGULAR,
+    reserved1: u32 = 0,
+    reserved2: u32 = 0,
+};
+
+pub fn initSection(
+    gpa: Allocator,
+    ctx: anytype,
+    segname: []const u8,
+    sectname: []const u8,
+    opts: InitSectionOpts,
+) !u8 {
+    log.debug("creating section '{s},{s}'", .{ segname, sectname });
+    const index = @as(u8, @intCast(ctx.sections.slice().len));
+    try ctx.sections.append(gpa, .{
+        .segment_index = undefined, // Segments will be created automatically later down the pipeline
+        .header = .{
+            .sectname = makeStaticString(sectname),
+            .segname = makeStaticString(segname),
+            .flags = opts.flags,
+            .reserved1 = opts.reserved1,
+            .reserved2 = opts.reserved2,
+        },
+    });
+    return index;
+}
+
 fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: struct {
     size: u64 = 0,
     alignment: u32 = 0,
@@ -2751,7 +2779,6 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
     // In incremental context, we create one section per segment pairing. This way,
     // we can move the segment in raw file as we please.
     const segment_id = @as(u8, @intCast(self.segments.items.len));
-    const section_id = @as(u8, @intCast(self.sections.slice().len));
     const vmaddr = blk: {
         const prev_segment = self.segments.items[segment_id - 1];
         break :blk mem.alignForward(u64, prev_segment.vmaddr + prev_segment.vmsize, page_size);
@@ -2782,23 +2809,18 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
         .cmdsize = @sizeOf(macho.segment_command_64) + @sizeOf(macho.section_64),
     };
 
-    var section = macho.section_64{
-        .sectname = makeStaticString(sectname),
-        .segname = makeStaticString(segname),
-        .addr = mem.alignForward(u64, vmaddr, opts.alignment),
-        .offset = mem.alignForward(u32, @as(u32, @intCast(off)), opts.alignment),
-        .size = opts.size,
-        .@"align" = math.log2(opts.alignment),
+    const sect_id = try initSection(gpa, self, sectname, segname, .{
         .flags = opts.flags,
         .reserved2 = opts.reserved2,
-    };
+    });
+    const section = &self.sections.items(.header)[sect_id];
+    section.addr = mem.alignForward(u64, vmaddr, opts.alignment);
+    section.offset = mem.alignForward(u32, @as(u32, @intCast(off)), opts.alignment);
+    section.size = opts.size;
+    section.@"align" = math.log2(opts.alignment);
     assert(!section.isZerofill()); // TODO zerofill sections
 
-    try self.sections.append(gpa, .{
-        .segment_index = segment_id,
-        .header = section,
-    });
-    return section_id;
+    return sect_id;
 }
 
 fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {