Commit e5da251635

Jakub Konka <kubkon@jakubkonka.com>
2022-09-10 16:24:41
macho: clean up use of section ids
1 parent 05d0c42
Changed files (3)
src/link/MachO/Atom.zig
@@ -314,13 +314,13 @@ pub fn parseRelocs(self: *Atom, relocs: []align(1) const macho.relocation_info,
                 const sect_id = @intCast(u16, rel.r_symbolnum - 1);
                 const sym_index = object.sections_as_symbols.get(sect_id) orelse blk: {
                     const sect = object.getSourceSection(sect_id);
-                    const match = (try context.macho_file.getOutputSection(sect)) orelse
+                    const out_sect_id = (try context.macho_file.getOutputSection(sect)) orelse
                         unreachable;
                     const sym_index = @intCast(u32, object.symtab.items.len);
                     try object.symtab.append(gpa, .{
                         .n_strx = 0,
                         .n_type = macho.N_SECT,
-                        .n_sect = match + 1,
+                        .n_sect = out_sect_id + 1,
                         .n_desc = 0,
                         .n_value = sect.addr,
                     });
src/link/MachO/Object.zig
@@ -220,15 +220,15 @@ fn filterRelocs(
 
 pub fn scanInputSections(self: Object, macho_file: *MachO) !void {
     for (self.sections.items) |sect| {
-        const match = (try macho_file.getOutputSection(sect)) orelse {
+        const sect_id = (try macho_file.getOutputSection(sect)) orelse {
             log.debug("  unhandled section", .{});
             continue;
         };
-        const output = macho_file.sections.items(.header)[match];
+        const output = macho_file.sections.items(.header)[sect_id];
         log.debug("mapping '{s},{s}' into output sect({d}, '{s},{s}')", .{
             sect.segName(),
             sect.sectName(),
-            match + 1,
+            sect_id + 1,
             output.segName(),
             output.sectName(),
         });
@@ -335,15 +335,15 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
         log.debug("splitting section '{s},{s}' into atoms", .{ sect.segName(), sect.sectName() });
 
         // Get matching segment/section in the final artifact.
-        const match = (try macho_file.getOutputSection(sect)) orelse {
+        const out_sect_id = (try macho_file.getOutputSection(sect)) orelse {
             log.debug("  unhandled section", .{});
             continue;
         };
 
         log.debug("  output sect({d}, '{s},{s}')", .{
-            match + 1,
-            macho_file.sections.items(.header)[match].segName(),
-            macho_file.sections.items(.header)[match].sectName(),
+            out_sect_id + 1,
+            macho_file.sections.items(.header)[out_sect_id].segName(),
+            macho_file.sections.items(.header)[out_sect_id].sectName(),
         });
 
         const cpu_arch = macho_file.base.options.target.cpu.arch;
@@ -376,7 +376,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
                     try self.symtab.append(gpa, .{
                         .n_strx = 0,
                         .n_type = macho.N_SECT,
-                        .n_sect = match + 1,
+                        .n_sect = out_sect_id + 1,
                         .n_desc = 0,
                         .n_value = sect.addr,
                     });
@@ -397,10 +397,10 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
                     atom_code,
                     relocs,
                     &.{},
-                    match,
+                    out_sect_id,
                     sect,
                 );
-                try macho_file.addAtomToSection(atom, match);
+                try macho_file.addAtomToSection(atom);
             }
 
             var next_sym_count: usize = 0;
@@ -452,7 +452,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
                     atom_code,
                     relocs,
                     sorted_atom_syms.items[1..],
-                    match,
+                    out_sect_id,
                     sect,
                 );
 
@@ -465,7 +465,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
                         try self.symtab.append(gpa, .{
                             .n_strx = 0,
                             .n_type = macho.N_SECT,
-                            .n_sect = match + 1,
+                            .n_sect = out_sect_id + 1,
                             .n_desc = 0,
                             .n_value = addr,
                         });
@@ -479,7 +479,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
                     try self.atom_by_index_table.put(gpa, alias, atom);
                 }
 
-                try macho_file.addAtomToSection(atom, match);
+                try macho_file.addAtomToSection(atom);
             }
         } else {
             // If there is no symbol to refer to this atom, we create
@@ -490,7 +490,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
                 try self.symtab.append(gpa, .{
                     .n_strx = 0,
                     .n_type = macho.N_SECT,
-                    .n_sect = match + 1,
+                    .n_sect = out_sect_id + 1,
                     .n_desc = 0,
                     .n_value = sect.addr,
                 });
@@ -506,10 +506,10 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) !void {
                 code,
                 relocs,
                 filtered_syms,
-                match,
+                out_sect_id,
                 sect,
             );
-            try macho_file.addAtomToSection(atom, match);
+            try macho_file.addAtomToSection(atom);
         }
     }
 }
@@ -524,21 +524,21 @@ fn createAtomFromSubsection(
     code: ?[]const u8,
     relocs: []align(1) const macho.relocation_info,
     indexes: []const SymbolAtIndex,
-    match: u8,
+    out_sect_id: u8,
     sect: macho.section_64,
 ) !*Atom {
     const gpa = macho_file.base.allocator;
     const sym = self.symtab.items[sym_index];
     const atom = try MachO.createEmptyAtom(gpa, sym_index, size, alignment);
     atom.file = object_id;
-    self.symtab.items[sym_index].n_sect = match + 1;
+    self.symtab.items[sym_index].n_sect = out_sect_id + 1;
 
     log.debug("creating ATOM(%{d}, '{s}') in sect({d}, '{s},{s}') in object({d})", .{
         sym_index,
         self.getString(sym.n_strx),
-        match + 1,
-        macho_file.sections.items(.header)[match].segName(),
-        macho_file.sections.items(.header)[match].sectName(),
+        out_sect_id + 1,
+        macho_file.sections.items(.header)[out_sect_id].segName(),
+        macho_file.sections.items(.header)[out_sect_id].sectName(),
         object_id,
     });
 
@@ -566,7 +566,7 @@ fn createAtomFromSubsection(
     try atom.contained.ensureTotalCapacity(gpa, indexes.len);
     for (indexes) |inner_sym_index| {
         const inner_sym = &self.symtab.items[inner_sym_index.index];
-        inner_sym.n_sect = match + 1;
+        inner_sym.n_sect = out_sect_id + 1;
         atom.contained.appendAssumeCapacity(.{
             .sym_index = inner_sym_index.index,
             .offset = inner_sym.n_value - sym.n_value,
src/link/MachO.zig
@@ -1215,10 +1215,11 @@ pub fn createEmptyAtom(gpa: Allocator, sym_index: u32, size: u64, alignment: u32
     return atom;
 }
 
-pub fn writeAtom(self: *MachO, atom: *Atom, sect_id: u8) !void {
-    const section = self.sections.get(sect_id);
+pub fn writeAtom(self: *MachO, atom: *Atom) !void {
     const sym = atom.getSymbol(self);
+    const section = self.sections.get(sym.n_sect - 1);
     const file_offset = section.header.offset + sym.n_value - section.header.addr;
+    try atom.resolveRelocs(self);
     log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset });
     try self.base.file.?.pwriteAll(atom.code.items, file_offset);
 }
@@ -1327,7 +1328,7 @@ fn writeAtoms(self: *MachO) !void {
 
         while (true) {
             if (atom.dirty) {
-                try self.writeAtom(atom, sect_i);
+                try self.writeAtom(atom);
                 atom.dirty = false;
             }
 
@@ -1344,6 +1345,7 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom {
     const atom = try MachO.createEmptyAtom(gpa, sym_index, @sizeOf(u64), 3);
     const sym = atom.getSymbolPtr(self);
     sym.n_type = macho.N_SECT;
+    sym.n_sect = self.got_section_index.? + 1;
 
     try atom.relocs.append(gpa, .{
         .offset = 0,
@@ -1373,7 +1375,7 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom {
     try self.managed_atoms.append(gpa, atom);
     try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom);
 
-    try self.allocateAtomCommon(atom, self.got_section_index.?);
+    try self.allocateAtomCommon(atom);
 
     return atom;
 }
@@ -1382,8 +1384,6 @@ pub fn createTlvPtrAtom(self: *MachO, target: SymbolWithLoc) !*Atom {
     const gpa = self.base.allocator;
     const sym_index = try self.allocateSymbol();
     const atom = try MachO.createEmptyAtom(gpa, sym_index, @sizeOf(u64), 3);
-    const sym = atom.getSymbolPtr(self);
-    sym.n_type = macho.N_SECT;
 
     const target_sym = self.getSymbol(target);
     assert(target_sym.undf());
@@ -1397,12 +1397,16 @@ pub fn createTlvPtrAtom(self: *MachO, target: SymbolWithLoc) !*Atom {
     try self.managed_atoms.append(gpa, atom);
     try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom);
 
-    const match = (try self.getOutputSection(.{
+    const sym = atom.getSymbolPtr(self);
+    sym.n_type = macho.N_SECT;
+    const sect_id = (try self.getOutputSection(.{
         .segname = makeStaticString("__DATA"),
         .sectname = makeStaticString("__thread_ptrs"),
         .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS,
     })).?;
-    try self.allocateAtomCommon(atom, match);
+    sym.n_sect = sect_id + 1;
+
+    try self.allocateAtomCommon(atom);
 
     return atom;
 }
@@ -1416,9 +1420,10 @@ pub fn createDyldPrivateAtom(self: *MachO) !void {
     const atom = try MachO.createEmptyAtom(gpa, sym_index, @sizeOf(u64), 3);
     const sym = atom.getSymbolPtr(self);
     sym.n_type = macho.N_SECT;
+    sym.n_sect = self.data_section_index.? + 1;
     self.dyld_private_atom = atom;
 
-    try self.allocateAtomCommon(atom, self.data_section_index.?);
+    try self.allocateAtomCommon(atom);
 
     try self.managed_atoms.append(gpa, atom);
     try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom);
@@ -1444,6 +1449,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void {
     const atom = try MachO.createEmptyAtom(gpa, sym_index, size, alignment);
     const sym = atom.getSymbolPtr(self);
     sym.n_type = macho.N_SECT;
+    sym.n_sect = self.stub_helper_section_index.? + 1;
 
     const dyld_private_sym_index = self.dyld_private_atom.?.sym_index;
     switch (arch) {
@@ -1542,7 +1548,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void {
     }
     self.stub_helper_preamble_atom = atom;
 
-    try self.allocateAtomCommon(atom, self.stub_helper_section_index.?);
+    try self.allocateAtomCommon(atom);
 
     try self.managed_atoms.append(gpa, atom);
     try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom);
@@ -1565,6 +1571,7 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {
     const atom = try MachO.createEmptyAtom(gpa, sym_index, stub_size, alignment);
     const sym = atom.getSymbolPtr(self);
     sym.n_type = macho.N_SECT;
+    sym.n_sect = self.stub_helper_section_index.? + 1;
 
     try atom.relocs.ensureTotalCapacity(gpa, 1);
 
@@ -1614,7 +1621,7 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {
     try self.managed_atoms.append(gpa, atom);
     try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom);
 
-    try self.allocateAtomCommon(atom, self.stub_helper_section_index.?);
+    try self.allocateAtomCommon(atom);
 
     return atom;
 }
@@ -1625,6 +1632,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi
     const atom = try MachO.createEmptyAtom(gpa, sym_index, @sizeOf(u64), 3);
     const sym = atom.getSymbolPtr(self);
     sym.n_type = macho.N_SECT;
+    sym.n_sect = self.la_symbol_ptr_section_index.? + 1;
 
     try atom.relocs.append(gpa, .{
         .offset = 0,
@@ -1650,7 +1658,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi
     try self.managed_atoms.append(gpa, atom);
     try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom);
 
-    try self.allocateAtomCommon(atom, self.la_symbol_ptr_section_index.?);
+    try self.allocateAtomCommon(atom);
 
     return atom;
 }
@@ -1672,6 +1680,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {
     const atom = try MachO.createEmptyAtom(gpa, sym_index, stub_size, alignment);
     const sym = atom.getSymbolPtr(self);
     sym.n_type = macho.N_SECT;
+    sym.n_sect = self.stubs_section_index.? + 1;
 
     switch (arch) {
         .x86_64 => {
@@ -1725,7 +1734,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {
     try self.managed_atoms.append(gpa, atom);
     try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom);
 
-    try self.allocateAtomCommon(atom, self.stubs_section_index.?);
+    try self.allocateAtomCommon(atom);
 
     return atom;
 }
@@ -1762,7 +1771,7 @@ pub fn createTentativeDefAtoms(self: *MachO) !void {
         const atom = try MachO.createEmptyAtom(gpa, global.sym_index, size, alignment);
         atom.file = global.file;
 
-        try self.allocateAtomCommon(atom, n_sect);
+        try self.allocateAtomCommon(atom);
 
         if (global.file) |file| {
             const object = &self.objects.items[file];
@@ -2376,12 +2385,13 @@ pub fn deinit(self: *MachO) void {
     }
 }
 
-fn freeAtom(self: *MachO, atom: *Atom, sect_id: u8, owns_atom: bool) void {
+fn freeAtom(self: *MachO, atom: *Atom, owns_atom: bool) void {
     log.debug("freeAtom {*}", .{atom});
     if (!owns_atom) {
         atom.deinit(self.base.allocator);
     }
 
+    const sect_id = atom.getSymbol(self).n_sect - 1;
     const free_list = &self.sections.items(.free_list)[sect_id];
     var already_have_free_list_node = false;
     {
@@ -2434,21 +2444,20 @@ fn freeAtom(self: *MachO, atom: *Atom, sect_id: u8, owns_atom: bool) void {
     }
 }
 
-fn shrinkAtom(self: *MachO, atom: *Atom, new_block_size: u64, sect_id: u8) void {
+fn shrinkAtom(self: *MachO, atom: *Atom, new_block_size: u64) void {
     _ = self;
     _ = atom;
     _ = new_block_size;
-    _ = sect_id;
     // TODO check the new capacity, and if it crosses the size threshold into a big enough
     // capacity, insert a free list node for it.
 }
 
-fn growAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, sect_id: u8) !u64 {
+fn growAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) !u64 {
     const sym = atom.getSymbol(self);
     const align_ok = mem.alignBackwardGeneric(u64, sym.n_value, alignment) == sym.n_value;
     const need_realloc = !align_ok or new_atom_size > atom.capacity(self);
     if (!need_realloc) return sym.n_value;
-    return self.allocateAtom(atom, new_atom_size, alignment, sect_id);
+    return self.allocateAtom(atom, new_atom_size, alignment);
 }
 
 fn allocateSymbol(self: *MachO) !u32 {
@@ -2704,21 +2713,16 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
         typed_value.val,
         required_alignment,
     );
-    const addr = try self.allocateAtom(atom, code.len, required_alignment, sect_id);
+    const symbol = atom.getSymbolPtr(self);
+    symbol.n_strx = name_str_index;
+    symbol.n_type = macho.N_SECT;
+    symbol.n_sect = sect_id + 1;
+    symbol.n_value = try self.allocateAtom(atom, code.len, required_alignment);
 
-    log.debug("allocated atom for {?s} at 0x{x}", .{ name, addr });
+    log.debug("allocated atom for {?s} at 0x{x}", .{ name, symbol.n_value });
     log.debug("  (required alignment 0x{x})", .{required_alignment});
 
-    errdefer self.freeAtom(atom, sect_id, true);
-
-    const symbol = atom.getSymbolPtr(self);
-    symbol.* = .{
-        .n_strx = name_str_index,
-        .n_type = macho.N_SECT,
-        .n_sect = sect_id + 1,
-        .n_desc = 0,
-        .n_value = addr,
-    };
+    errdefer self.freeAtom(atom, true);
 
     try unnamed_consts.append(gpa, atom);
 
@@ -2968,15 +2972,20 @@ fn placeDecl(self: *MachO, decl_index: Module.Decl.Index, code_len: usize) !u64
             required_alignment,
         );
     }
-    const match = decl_ptr.*.?;
+    const sect_id = decl_ptr.*.?;
 
     if (decl.link.macho.size != 0) {
         const symbol = decl.link.macho.getSymbolPtr(self);
+        symbol.n_strx = try self.strtab.insert(self.base.allocator, sym_name);
+        symbol.n_type = macho.N_SECT;
+        symbol.n_sect = sect_id + 1;
+        symbol.n_desc = 0;
+
         const capacity = decl.link.macho.capacity(self);
         const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);
 
         if (need_realloc) {
-            const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment, match);
+            const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment);
             log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ sym_name, symbol.n_value, vaddr });
             log.debug("  (required alignment 0x{x})", .{required_alignment});
             symbol.n_value = vaddr;
@@ -2987,32 +2996,24 @@ fn placeDecl(self: *MachO, decl_index: Module.Decl.Index, code_len: usize) !u64
             }).?;
             got_atom.dirty = true;
         } else if (code_len < decl.link.macho.size) {
-            self.shrinkAtom(&decl.link.macho, code_len, match);
+            self.shrinkAtom(&decl.link.macho, code_len);
         }
+
         decl.link.macho.size = code_len;
         decl.link.macho.dirty = true;
-
-        symbol.n_strx = try self.strtab.insert(self.base.allocator, sym_name);
-        symbol.n_type = macho.N_SECT;
-        symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
-        symbol.n_desc = 0;
     } else {
         const name_str_index = try self.strtab.insert(self.base.allocator, sym_name);
-        const addr = try self.allocateAtom(&decl.link.macho, code_len, required_alignment, match);
+        const symbol = decl.link.macho.getSymbolPtr(self);
+        symbol.n_strx = name_str_index;
+        symbol.n_type = macho.N_SECT;
+        symbol.n_sect = sect_id + 1;
+        symbol.n_desc = 0;
+        symbol.n_value = try self.allocateAtom(&decl.link.macho, code_len, required_alignment);
 
-        log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, addr });
+        log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, symbol.n_value });
         log.debug("  (required alignment 0x{x})", .{required_alignment});
 
-        errdefer self.freeAtom(&decl.link.macho, match, false);
-
-        const symbol = decl.link.macho.getSymbolPtr(self);
-        symbol.* = .{
-            .n_strx = name_str_index,
-            .n_type = macho.N_SECT,
-            .n_sect = match + 1,
-            .n_desc = 0,
-            .n_value = addr,
-        };
+        errdefer self.freeAtom(&decl.link.macho, false);
 
         const got_target = SymbolWithLoc{ .sym_index = decl.link.macho.sym_index, .file = null };
         const got_index = try self.allocateGotEntry(got_target);
@@ -3171,10 +3172,7 @@ 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| {
-        // TODO
-        // const sect_id = atom.getSymbol(self).n_sect;
-        const sect_id = self.getSectionByName("__TEXT", "__const").?;
-        self.freeAtom(atom, sect_id, true);
+        self.freeAtom(atom, 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);
@@ -3192,8 +3190,8 @@ pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void {
     const decl = mod.declPtr(decl_index);
     log.debug("freeDecl {*}", .{decl});
     const kv = self.decls.fetchSwapRemove(decl_index);
-    if (kv.?.value) |match| {
-        self.freeAtom(&decl.link.macho, match, false);
+    if (kv.?.value) |_| {
+        self.freeAtom(&decl.link.macho, false);
         self.freeUnnamedConsts(decl_index);
     }
     // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
@@ -3928,29 +3926,22 @@ fn getSectionMaxAlignment(self: *MachO, start: u8, end: u8) !u32 {
     return max_alignment;
 }
 
-fn allocateAtomCommon(self: *MachO, atom: *Atom, sect_id: u8) !void {
-    const sym = atom.getSymbolPtr(self);
+fn allocateAtomCommon(self: *MachO, atom: *Atom) !void {
     if (self.mode == .incremental) {
+        const sym_name = atom.getName(self);
         const size = atom.size;
         const alignment = try math.powi(u32, 2, atom.alignment);
-        const vaddr = try self.allocateAtom(atom, size, alignment, sect_id);
-        const sym_name = atom.getName(self);
+        const vaddr = try self.allocateAtom(atom, size, alignment);
         log.debug("allocated {s} atom at 0x{x}", .{ sym_name, vaddr });
-        sym.n_value = vaddr;
-    } else try self.addAtomToSection(atom, sect_id);
-    sym.n_sect = sect_id + 1;
+        atom.getSymbolPtr(self).n_value = vaddr;
+    } else try self.addAtomToSection(atom);
 }
 
-fn allocateAtom(
-    self: *MachO,
-    atom: *Atom,
-    new_atom_size: u64,
-    alignment: u64,
-    sect_id: u8,
-) !u64 {
+fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) !u64 {
     const tracy = trace(@src());
     defer tracy.end();
 
+    const sect_id = atom.getSymbol(self).n_sect - 1;
     const header = &self.sections.items(.header)[sect_id];
     const free_list = &self.sections.items(.free_list)[sect_id];
     const maybe_last_atom = &self.sections.items(.last_atom)[sect_id];
@@ -4050,7 +4041,8 @@ fn allocateAtom(
     return vaddr;
 }
 
-pub fn addAtomToSection(self: *MachO, atom: *Atom, sect_id: u8) !void {
+pub fn addAtomToSection(self: *MachO, atom: *Atom) !void {
+    const sect_id = atom.getSymbol(self).n_sect - 1;
     var section = self.sections.get(sect_id);
     if (section.header.size > 0) {
         section.last_atom.?.next = atom;