Commit 7bba3d330a

Jakub Konka <kubkon@jakubkonka.com>
2022-08-01 18:42:18
macho: cleanup output section selection logic
Cache only section indexes used by the linker for synthetic sections and/or incremental codepath.
1 parent bb53258
Changed files (2)
src
src/link/MachO/Atom.zig
@@ -529,6 +529,7 @@ fn addStub(target: MachO.SymbolWithLoc, context: RelocContext) !void {
     if (context.macho_file.stubs_table.contains(target)) return;
 
     const stub_index = try context.macho_file.allocateStubEntry(target);
+
     const stub_helper_atom = try context.macho_file.createStubHelperAtom();
     const laptr_atom = try context.macho_file.createLazyPointerAtom(stub_helper_atom.sym_index, target);
     const stub_atom = try context.macho_file.createStubAtom(laptr_atom.sym_index);
@@ -601,9 +602,9 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
                 // * wrt to __thread_data if defined, then
                 // * wrt to __thread_bss
                 const sect_id: u16 = sect_id: {
-                    if (macho_file.tlv_data_section_index) |i| {
+                    if (macho_file.getSectionByName("__DATA", "__thread_data")) |i| {
                         break :sect_id i;
-                    } else if (macho_file.tlv_bss_section_index) |i| {
+                    } else if (macho_file.getSectionByName("__DATA", "__thread_bss")) |i| {
                         break :sect_id i;
                     } else {
                         log.err("threadlocal variables present but no initializer sections found", .{});
src/link/MachO.zig
@@ -121,48 +121,12 @@ data_const_segment_cmd_index: ?u8 = null,
 data_segment_cmd_index: ?u8 = null,
 linkedit_segment_cmd_index: ?u8 = null,
 
-// __TEXT segment sections
 text_section_index: ?u8 = null,
 stubs_section_index: ?u8 = null,
 stub_helper_section_index: ?u8 = null,
-text_const_section_index: ?u8 = null,
-cstring_section_index: ?u8 = null,
-ustring_section_index: ?u8 = null,
-gcc_except_tab_section_index: ?u8 = null,
-unwind_info_section_index: ?u8 = null,
-eh_frame_section_index: ?u8 = null,
-
-objc_methlist_section_index: ?u8 = null,
-objc_methname_section_index: ?u8 = null,
-objc_methtype_section_index: ?u8 = null,
-objc_classname_section_index: ?u8 = null,
-
-// __DATA_CONST segment sections
 got_section_index: ?u8 = null,
-mod_init_func_section_index: ?u8 = null,
-mod_term_func_section_index: ?u8 = null,
-data_const_section_index: ?u8 = null,
-
-objc_cfstring_section_index: ?u8 = null,
-objc_classlist_section_index: ?u8 = null,
-objc_imageinfo_section_index: ?u8 = null,
-
-// __DATA segment sections
-tlv_section_index: ?u8 = null,
-tlv_data_section_index: ?u8 = null,
-tlv_bss_section_index: ?u8 = null,
-tlv_ptrs_section_index: ?u8 = null,
 la_symbol_ptr_section_index: ?u8 = null,
 data_section_index: ?u8 = null,
-bss_section_index: ?u8 = null,
-
-objc_const_section_index: ?u8 = null,
-objc_selrefs_section_index: ?u8 = null,
-objc_classrefs_section_index: ?u8 = null,
-objc_data_section_index: ?u8 = null,
-
-rustc_section_index: ?u8 = null,
-rustc_section_size: u64 = 0,
 
 locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
 globals: std.StringArrayHashMapUnmanaged(SymbolWithLoc) = .{},
@@ -547,14 +511,15 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
 
     try self.createMhExecuteHeaderSymbol();
     try self.resolveDyldStubBinder();
-    try self.createDyldPrivateAtom();
-    try self.createStubHelperPreambleAtom();
     try self.resolveSymbolsInDylibs();
 
     if (self.unresolved.count() > 0) {
         return error.UndefinedSymbolReference;
     }
 
+    try self.createDyldPrivateAtom();
+    try self.createStubHelperPreambleAtom();
+
     try self.allocateSpecialSymbols();
 
     if (build_options.enable_logging) {
@@ -1140,7 +1105,6 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node)
 
         try self.resolveSymbolsInArchives();
         try self.resolveDyldStubBinder();
-        try self.createDyldPrivateAtom();
         try self.resolveSymbolsInDylibs();
         try self.createMhExecuteHeaderSymbol();
         try self.createDsoHandleSymbol();
@@ -1160,8 +1124,9 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node)
             try object.scanInputSections(self);
         }
 
-        try self.createStubHelperPreambleAtom();
+        try self.createDyldPrivateAtom();
         try self.createTentativeDefAtoms();
+        try self.createStubHelperPreambleAtom();
 
         for (self.objects.items) |*object, object_id| {
             try object.splitIntoAtomsOneShot(self, @intCast(u32, object_id));
@@ -1184,11 +1149,6 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node)
 
         try self.writeAtomsOneShot();
 
-        if (self.rustc_section_index) |id| {
-            const header = &self.sections.items(.header)[id];
-            header.size = self.rustc_section_size;
-        }
-
         var lc_buffer = std.ArrayList(u8).init(arena);
         const lc_writer = lc_buffer.writer();
         var ncmds: u32 = 0;
@@ -1696,417 +1656,142 @@ pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 {
     const segname = sect.segName();
     const sectname = sect.sectName();
     const res: ?u8 = blk: {
+        if (mem.eql(u8, "__LLVM", segname)) {
+            log.debug("TODO LLVM section: type 0x{x}, name '{s},{s}'", .{
+                sect.flags, segname, sectname,
+            });
+            break :blk null;
+        }
+
+        if (sect.isCode()) {
+            if (self.text_section_index == null) {
+                self.text_section_index = try self.initSection(
+                    "__TEXT",
+                    "__text",
+                    sect.size,
+                    sect.@"align",
+                    .{
+                        .flags = macho.S_REGULAR |
+                            macho.S_ATTR_PURE_INSTRUCTIONS |
+                            macho.S_ATTR_SOME_INSTRUCTIONS,
+                    },
+                );
+            }
+            break :blk self.text_section_index.?;
+        }
+
+        if (sect.isDebug()) {
+            // TODO debug attributes
+            if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) {
+                log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{
+                    sect.flags, segname, sectname,
+                });
+            }
+            break :blk null;
+        }
+
         switch (sect.@"type"()) {
-            macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => {
-                if (self.text_const_section_index == null) {
-                    self.text_const_section_index = try self.initSection(
-                        self.text_segment_cmd_index.?,
-                        "__const",
-                        sect.size,
-                        sect.@"align",
-                        .{},
-                    );
-                }
-                break :blk self.text_const_section_index.?;
+            macho.S_4BYTE_LITERALS,
+            macho.S_8BYTE_LITERALS,
+            macho.S_16BYTE_LITERALS,
+            => {
+                break :blk self.getSectionByName("__TEXT", "__const") orelse try self.initSection(
+                    "__TEXT",
+                    "__const",
+                    sect.size,
+                    sect.@"align",
+                    .{},
+                );
             },
             macho.S_CSTRING_LITERALS => {
-                if (mem.eql(u8, sectname, "__objc_methname")) {
-                    // TODO it seems the common values within the sections in objects are deduplicated/merged
-                    // on merging the sections' contents.
-                    if (self.objc_methname_section_index == null) {
-                        self.objc_methname_section_index = try self.initSection(
-                            self.text_segment_cmd_index.?,
-                            "__objc_methname",
-                            sect.size,
-                            sect.@"align",
-                            .{},
-                        );
-                    }
-                    break :blk self.objc_methname_section_index.?;
-                } else if (mem.eql(u8, sectname, "__objc_methtype")) {
-                    if (self.objc_methtype_section_index == null) {
-                        self.objc_methtype_section_index = try self.initSection(
-                            self.text_segment_cmd_index.?,
-                            "__objc_methtype",
-                            sect.size,
-                            sect.@"align",
-                            .{},
-                        );
-                    }
-                    break :blk self.objc_methtype_section_index.?;
-                } else if (mem.eql(u8, sectname, "__objc_classname")) {
-                    if (self.objc_classname_section_index == null) {
-                        self.objc_classname_section_index = try self.initSection(
-                            self.text_segment_cmd_index.?,
-                            "__objc_classname",
-                            sect.size,
-                            sect.@"align",
-                            .{},
-                        );
-                    }
-                    break :blk self.objc_classname_section_index.?;
-                }
-
-                if (self.cstring_section_index == null) {
-                    self.cstring_section_index = try self.initSection(
-                        self.text_segment_cmd_index.?,
-                        "__cstring",
+                if (mem.startsWith(u8, sectname, "__objc")) {
+                    break :blk self.getSectionByName(segname, sectname) orelse try self.initSection(
+                        segname,
+                        sectname,
                         sect.size,
                         sect.@"align",
-                        .{
-                            .flags = macho.S_CSTRING_LITERALS,
-                        },
-                    );
-                }
-                break :blk self.cstring_section_index.?;
-            },
-            macho.S_LITERAL_POINTERS => {
-                if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__objc_selrefs")) {
-                    if (self.objc_selrefs_section_index == null) {
-                        self.objc_selrefs_section_index = try self.initSection(
-                            self.data_segment_cmd_index.?,
-                            "__objc_selrefs",
-                            sect.size,
-                            sect.@"align",
-                            .{
-                                .flags = macho.S_LITERAL_POINTERS,
-                            },
-                        );
-                    }
-                    break :blk self.objc_selrefs_section_index.?;
-                } else {
-                    // TODO investigate
-                    break :blk null;
-                }
-            },
-            macho.S_MOD_INIT_FUNC_POINTERS => {
-                if (self.mod_init_func_section_index == null) {
-                    self.mod_init_func_section_index = try self.initSection(
-                        self.data_const_segment_cmd_index.?,
-                        "__mod_init_func",
-                        sect.size,
-                        sect.@"align",
-                        .{
-                            .flags = macho.S_MOD_INIT_FUNC_POINTERS,
-                        },
-                    );
-                }
-                break :blk self.mod_init_func_section_index.?;
-            },
-            macho.S_MOD_TERM_FUNC_POINTERS => {
-                if (self.mod_term_func_section_index == null) {
-                    self.mod_term_func_section_index = try self.initSection(
-                        self.data_const_segment_cmd_index.?,
-                        "__mod_term_func",
-                        sect.size,
-                        sect.@"align",
-                        .{
-                            .flags = macho.S_MOD_TERM_FUNC_POINTERS,
-                        },
-                    );
-                }
-                break :blk self.mod_term_func_section_index.?;
-            },
-            macho.S_ZEROFILL => {
-                if (self.bss_section_index == null) {
-                    self.bss_section_index = try self.initSection(
-                        self.data_segment_cmd_index.?,
-                        "__bss",
-                        sect.size,
-                        sect.@"align",
-                        .{
-                            .flags = macho.S_ZEROFILL,
-                        },
-                    );
-                }
-                break :blk self.bss_section_index.?;
-            },
-            macho.S_THREAD_LOCAL_VARIABLES => {
-                if (self.tlv_section_index == null) {
-                    self.tlv_section_index = try self.initSection(
-                        self.data_segment_cmd_index.?,
-                        "__thread_vars",
-                        sect.size,
-                        sect.@"align",
-                        .{
-                            .flags = macho.S_THREAD_LOCAL_VARIABLES,
-                        },
-                    );
-                }
-                break :blk self.tlv_section_index.?;
-            },
-            macho.S_THREAD_LOCAL_VARIABLE_POINTERS => {
-                if (self.tlv_ptrs_section_index == null) {
-                    self.tlv_ptrs_section_index = try self.initSection(
-                        self.data_segment_cmd_index.?,
-                        "__thread_ptrs",
-                        sect.size,
-                        sect.@"align",
-                        .{
-                            .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS,
-                        },
+                        .{},
                     );
                 }
-                break :blk self.tlv_ptrs_section_index.?;
+                break :blk self.getSectionByName("__TEXT", "__cstring") orelse try self.initSection(
+                    "__TEXT",
+                    "__cstring",
+                    sect.size,
+                    sect.@"align",
+                    .{ .flags = macho.S_CSTRING_LITERALS },
+                );
             },
-            macho.S_THREAD_LOCAL_REGULAR => {
-                if (self.tlv_data_section_index == null) {
-                    self.tlv_data_section_index = try self.initSection(
-                        self.data_segment_cmd_index.?,
-                        "__thread_data",
-                        sect.size,
-                        sect.@"align",
-                        .{
-                            .flags = macho.S_THREAD_LOCAL_REGULAR,
-                        },
-                    );
-                }
-                break :blk self.tlv_data_section_index.?;
+            macho.S_MOD_INIT_FUNC_POINTERS,
+            macho.S_MOD_TERM_FUNC_POINTERS,
+            => {
+                break :blk self.getSectionByName("__DATA_CONST", sectname) orelse try self.initSection(
+                    "__DATA_CONST",
+                    sectname,
+                    sect.size,
+                    sect.@"align",
+                    .{ .flags = sect.flags },
+                );
             },
-            macho.S_THREAD_LOCAL_ZEROFILL => {
-                if (self.tlv_bss_section_index == null) {
-                    self.tlv_bss_section_index = try self.initSection(
-                        self.data_segment_cmd_index.?,
-                        "__thread_bss",
-                        sect.size,
-                        sect.@"align",
-                        .{
-                            .flags = macho.S_THREAD_LOCAL_ZEROFILL,
-                        },
-                    );
-                }
-                break :blk self.tlv_bss_section_index.?;
+            macho.S_LITERAL_POINTERS,
+            macho.S_ZEROFILL,
+            macho.S_THREAD_LOCAL_VARIABLES,
+            macho.S_THREAD_LOCAL_VARIABLE_POINTERS,
+            macho.S_THREAD_LOCAL_REGULAR,
+            macho.S_THREAD_LOCAL_ZEROFILL,
+            => {
+                break :blk self.getSectionByName(segname, sectname) orelse try self.initSection(
+                    segname,
+                    sectname,
+                    sect.size,
+                    sect.@"align",
+                    .{ .flags = sect.flags },
+                );
             },
             macho.S_COALESCED => {
-                if (mem.eql(u8, "__TEXT", segname) and mem.eql(u8, "__eh_frame", sectname)) {
-                    // TODO I believe __eh_frame is currently part of __unwind_info section
-                    // in the latest ld64 output.
-                    if (self.eh_frame_section_index == null) {
-                        self.eh_frame_section_index = try self.initSection(
-                            self.text_segment_cmd_index.?,
-                            "__eh_frame",
-                            sect.size,
-                            sect.@"align",
-                            .{},
-                        );
-                    }
-                    break :blk self.eh_frame_section_index.?;
-                }
-
-                // TODO audit this: is this the right mapping?
-                if (self.data_const_section_index == null) {
-                    self.data_const_section_index = try self.initSection(
-                        self.data_const_segment_cmd_index.?,
-                        "__const",
-                        sect.size,
-                        sect.@"align",
-                        .{},
-                    );
-                }
-
-                break :blk self.data_const_section_index.?;
+                break :blk self.getSectionByName(segname, sectname) orelse try self.initSection(
+                    segname,
+                    sectname,
+                    sect.size,
+                    sect.@"align",
+                    .{},
+                );
             },
             macho.S_REGULAR => {
-                if (sect.isCode()) {
-                    if (self.text_section_index == null) {
-                        self.text_section_index = try self.initSection(
-                            self.text_segment_cmd_index.?,
-                            "__text",
-                            sect.size,
-                            sect.@"align",
-                            .{
-                                .flags = macho.S_REGULAR |
-                                    macho.S_ATTR_PURE_INSTRUCTIONS |
-                                    macho.S_ATTR_SOME_INSTRUCTIONS,
-                            },
-                        );
-                    }
-                    break :blk self.text_section_index.?;
-                }
-                if (sect.isDebug()) {
-                    // TODO debug attributes
-                    if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) {
-                        log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{
-                            sect.flags, segname, sectname,
-                        });
-                    }
-                    break :blk null;
-                }
-
                 if (mem.eql(u8, segname, "__TEXT")) {
-                    if (mem.eql(u8, sectname, "__ustring")) {
-                        if (self.ustring_section_index == null) {
-                            self.ustring_section_index = try self.initSection(
-                                self.text_segment_cmd_index.?,
-                                "__ustring",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.ustring_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__gcc_except_tab")) {
-                        if (self.gcc_except_tab_section_index == null) {
-                            self.gcc_except_tab_section_index = try self.initSection(
-                                self.text_segment_cmd_index.?,
-                                "__gcc_except_tab",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.gcc_except_tab_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__objc_methlist")) {
-                        if (self.objc_methlist_section_index == null) {
-                            self.objc_methlist_section_index = try self.initSection(
-                                self.text_segment_cmd_index.?,
-                                "__objc_methlist",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.objc_methlist_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__rodata") or
+                    if (mem.eql(u8, sectname, "__rodata") or
                         mem.eql(u8, sectname, "__typelink") or
                         mem.eql(u8, sectname, "__itablink") or
                         mem.eql(u8, sectname, "__gosymtab") or
                         mem.eql(u8, sectname, "__gopclntab"))
                     {
-                        if (self.data_const_section_index == null) {
-                            self.data_const_section_index = try self.initSection(
-                                self.data_const_segment_cmd_index.?,
-                                "__const",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.data_const_section_index.?;
-                    } else {
-                        if (self.text_const_section_index == null) {
-                            self.text_const_section_index = try self.initSection(
-                                self.text_segment_cmd_index.?,
-                                "__const",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.text_const_section_index.?;
-                    }
-                }
-
-                if (mem.eql(u8, segname, "__DATA_CONST")) {
-                    if (self.data_const_section_index == null) {
-                        self.data_const_section_index = try self.initSection(
-                            self.data_const_segment_cmd_index.?,
+                        break :blk self.getSectionByName("__DATA_CONST", "__const") orelse try self.initSection(
+                            "__DATA_CONST",
                             "__const",
                             sect.size,
                             sect.@"align",
                             .{},
                         );
                     }
-                    break :blk self.data_const_section_index.?;
                 }
-
                 if (mem.eql(u8, segname, "__DATA")) {
-                    if (mem.eql(u8, sectname, "__const")) {
-                        if (self.data_const_section_index == null) {
-                            self.data_const_section_index = try self.initSection(
-                                self.data_const_segment_cmd_index.?,
-                                "__const",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.data_const_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__cfstring")) {
-                        if (self.objc_cfstring_section_index == null) {
-                            self.objc_cfstring_section_index = try self.initSection(
-                                self.data_const_segment_cmd_index.?,
-                                "__cfstring",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.objc_cfstring_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__objc_classlist")) {
-                        if (self.objc_classlist_section_index == null) {
-                            self.objc_classlist_section_index = try self.initSection(
-                                self.data_const_segment_cmd_index.?,
-                                "__objc_classlist",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.objc_classlist_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__objc_imageinfo")) {
-                        if (self.objc_imageinfo_section_index == null) {
-                            self.objc_imageinfo_section_index = try self.initSection(
-                                self.data_const_segment_cmd_index.?,
-                                "__objc_imageinfo",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.objc_imageinfo_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__objc_const")) {
-                        if (self.objc_const_section_index == null) {
-                            self.objc_const_section_index = try self.initSection(
-                                self.data_segment_cmd_index.?,
-                                "__objc_const",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.objc_const_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__objc_classrefs")) {
-                        if (self.objc_classrefs_section_index == null) {
-                            self.objc_classrefs_section_index = try self.initSection(
-                                self.data_segment_cmd_index.?,
-                                "__objc_classrefs",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.objc_classrefs_section_index.?;
-                    } else if (mem.eql(u8, sectname, "__objc_data")) {
-                        if (self.objc_data_section_index == null) {
-                            self.objc_data_section_index = try self.initSection(
-                                self.data_segment_cmd_index.?,
-                                "__objc_data",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                        }
-                        break :blk self.objc_data_section_index.?;
-                    } else if (mem.eql(u8, sectname, ".rustc")) {
-                        if (self.rustc_section_index == null) {
-                            self.rustc_section_index = try self.initSection(
-                                self.data_segment_cmd_index.?,
-                                ".rustc",
-                                sect.size,
-                                sect.@"align",
-                                .{},
-                            );
-                            // We need to preserve the section size for rustc to properly
-                            // decompress the metadata.
-                            self.rustc_section_size = sect.size;
-                        }
-                        break :blk self.rustc_section_index.?;
-                    } else {
+                    if (mem.eql(u8, sectname, "__const") or
+                        mem.eql(u8, sectname, "__cfstring") or
+                        mem.eql(u8, sectname, "__objc_classlist") or
+                        mem.eql(u8, sectname, "__objc_imageinfo"))
+                    {
+                        break :blk self.getSectionByName("__DATA_CONST", sectname) orelse
+                            try self.initSection(
+                            "__DATA_CONST",
+                            sectname,
+                            sect.size,
+                            sect.@"align",
+                            .{},
+                        );
+                    } else if (mem.eql(u8, sectname, "__data")) {
                         if (self.data_section_index == null) {
                             self.data_section_index = try self.initSection(
-                                self.data_segment_cmd_index.?,
-                                "__data",
+                                segname,
+                                sectname,
                                 sect.size,
                                 sect.@"align",
                                 .{},
@@ -2115,14 +1800,13 @@ pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 {
                         break :blk self.data_section_index.?;
                     }
                 }
-
-                if (mem.eql(u8, "__LLVM", segname) and mem.eql(u8, "__asm", sectname)) {
-                    log.debug("TODO LLVM asm section: type 0x{x}, name '{s},{s}'", .{
-                        sect.flags, segname, sectname,
-                    });
-                }
-
-                break :blk null;
+                break :blk self.getSectionByName(segname, sectname) orelse try self.initSection(
+                    segname,
+                    sectname,
+                    sect.size,
+                    sect.@"align",
+                    .{},
+                );
             },
             else => break :blk null,
         }
@@ -2774,11 +2458,16 @@ fn createTentativeDefAtoms(self: *MachO) !void {
         // text blocks for each tentative definition.
         const size = sym.n_value;
         const alignment = (sym.n_desc >> 8) & 0x0f;
+        const n_sect = (try self.getOutputSection(.{
+            .segname = makeStaticString("__DATA"),
+            .sectname = makeStaticString("__bss"),
+            .flags = macho.S_ZEROFILL,
+        })).?;
 
         sym.* = .{
             .n_strx = sym.n_strx,
             .n_type = macho.N_SECT | macho.N_EXT,
-            .n_sect = 0,
+            .n_sect = n_sect,
             .n_desc = 0,
             .n_value = 0,
         };
@@ -2786,7 +2475,7 @@ fn createTentativeDefAtoms(self: *MachO) !void {
         const atom = try MachO.createEmptyAtom(gpa, global.sym_index, size, alignment);
         atom.file = global.file;
 
-        try self.allocateAtomCommon(atom, self.bss_section_index.?);
+        try self.allocateAtomCommon(atom, n_sect);
 
         if (global.file) |file| {
             const object = &self.objects.items[file];
@@ -4174,7 +3863,8 @@ pub fn deleteExport(self: *MachO, exp: Export) void {
 fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void {
     const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
     for (unnamed_consts.items) |atom| {
-        self.freeAtom(atom, self.text_const_section_index.?, true);
+        const sect_id = atom.getSymbol(self).n_sect;
+        self.freeAtom(atom, sect_id, true);
         self.locals_free_list.append(self.base.allocator, atom.sym_index) catch {};
         self.locals.items[atom.sym_index].n_type = 0;
         _ = self.atom_by_index_table.remove(atom.sym_index);
@@ -4307,7 +3997,7 @@ fn populateMissingMetadata(self: *MachO) !void {
         };
         const needed_size = if (self.mode == .incremental) self.base.options.program_code_size_hint else 0;
         self.text_section_index = try self.initSection(
-            self.text_segment_cmd_index.?,
+            "__TEXT",
             "__text",
             needed_size,
             alignment,
@@ -4330,7 +4020,7 @@ fn populateMissingMetadata(self: *MachO) !void {
         };
         const needed_size = if (self.mode == .incremental) stub_size * self.base.options.symbol_count_hint else 0;
         self.stubs_section_index = try self.initSection(
-            self.text_segment_cmd_index.?,
+            "__TEXT",
             "__stubs",
             needed_size,
             alignment,
@@ -4362,7 +4052,7 @@ fn populateMissingMetadata(self: *MachO) !void {
         else
             0;
         self.stub_helper_section_index = try self.initSection(
-            self.text_segment_cmd_index.?,
+            "__TEXT",
             "__stub_helper",
             needed_size,
             alignment,
@@ -4407,7 +4097,7 @@ fn populateMissingMetadata(self: *MachO) !void {
             0;
         const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
         self.got_section_index = try self.initSection(
-            self.data_const_segment_cmd_index.?,
+            "__DATA_CONST",
             "__got",
             needed_size,
             alignment,
@@ -4452,7 +4142,7 @@ fn populateMissingMetadata(self: *MachO) !void {
             0;
         const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
         self.la_symbol_ptr_section_index = try self.initSection(
-            self.data_segment_cmd_index.?,
+            "__DATA",
             "__la_symbol_ptr",
             needed_size,
             alignment,
@@ -4469,7 +4159,7 @@ fn populateMissingMetadata(self: *MachO) !void {
             0;
         const alignment: u16 = 3; // 2^3 = @sizeOf(u64)
         self.data_section_index = try self.initSection(
-            self.data_segment_cmd_index.?,
+            "__DATA",
             "__data",
             needed_size,
             alignment,
@@ -4701,12 +4391,13 @@ const InitSectionOpts = struct {
 
 fn initSection(
     self: *MachO,
-    segment_id: u8,
+    segname: []const u8,
     sectname: []const u8,
     size: u64,
     alignment: u32,
     opts: InitSectionOpts,
 ) !u8 {
+    const segment_id = self.getSegmentByName(segname).?;
     const seg = &self.segments.items[segment_id];
     const index = try self.insertSection(segment_id, .{
         .sectname = makeStaticString(sectname),
@@ -4779,42 +4470,13 @@ fn insertSection(self: *MachO, segment_index: u8, header: macho.section_64) !u8
         header.sectName(),
         insertion_index,
     });
-    // TODO slim it down
     for (&[_]*?u8{
-        // __TEXT
         &self.text_section_index,
         &self.stubs_section_index,
         &self.stub_helper_section_index,
-        &self.gcc_except_tab_section_index,
-        &self.cstring_section_index,
-        &self.ustring_section_index,
-        &self.text_const_section_index,
-        &self.objc_methlist_section_index,
-        &self.objc_methname_section_index,
-        &self.objc_methtype_section_index,
-        &self.objc_classname_section_index,
-        &self.eh_frame_section_index,
-        // __DATA_CONST
         &self.got_section_index,
-        &self.mod_init_func_section_index,
-        &self.mod_term_func_section_index,
-        &self.data_const_section_index,
-        &self.objc_cfstring_section_index,
-        &self.objc_classlist_section_index,
-        &self.objc_imageinfo_section_index,
-        // __DATA
-        &self.rustc_section_index,
         &self.la_symbol_ptr_section_index,
-        &self.objc_const_section_index,
-        &self.objc_selrefs_section_index,
-        &self.objc_classrefs_section_index,
-        &self.objc_data_section_index,
         &self.data_section_index,
-        &self.tlv_section_index,
-        &self.tlv_ptrs_section_index,
-        &self.tlv_data_section_index,
-        &self.tlv_bss_section_index,
-        &self.bss_section_index,
     }) |maybe_index| {
         const index = maybe_index.* orelse continue;
         if (insertion_index <= index) maybe_index.* = index + 1;
@@ -6017,7 +5679,7 @@ fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {
         else => unreachable,
     }
 
-    if (self.tlv_section_index) |_| {
+    if (self.getSectionByName("__DATA", "__thread_vars")) |_| {
         header.flags |= macho.MH_HAS_TLV_DESCRIPTORS;
     }
 
@@ -6042,6 +5704,20 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 {
     return buf;
 }
 
+fn getSegmentByName(self: MachO, segname: []const u8) ?u8 {
+    for (self.segments.items) |seg, i| {
+        if (mem.eql(u8, segname, seg.segName())) return @intCast(u8, i);
+    } else return null;
+}
+
+pub fn getSectionByName(self: MachO, segname: []const u8, sectname: []const u8) ?u8 {
+    // TODO investigate caching with a hashmap
+    for (self.sections.items(.header)) |header, i| {
+        if (mem.eql(u8, header.segName(), segname) and mem.eql(u8, header.sectName(), sectname))
+            return @intCast(u8, i);
+    } else return null;
+}
+
 fn getSectionIndexes(self: MachO, segment_index: u8) struct { start: u8, end: u8 } {
     var start: u8 = 0;
     const nsects = for (self.segments.items) |seg, i| {