diff --git a/src/link/MachO.zig b/src/link/MachO.zig index e87488974c..8dbf5784c4 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -845,12 +845,21 @@ pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void { try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1); try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1); - log.debug("allocating symbol index {} for {}\n", .{ self.local_symbols.items.len, decl.name }); - decl.link.macho.local_sym_index = @intCast(u32, self.local_symbols.items.len); - _ = self.local_symbols.addOneAssumeCapacity(); + if (self.local_symbol_free_list.popOrNull()) |i| { + log.debug("reusing symbol index {} for {}\n", .{i, decl.name}); + decl.link.macho.local_sym_index = i; + } else { + log.debug("allocating symbol index {} for {}\n", .{ self.local_symbols.items.len, decl.name }); + decl.link.macho.local_sym_index = @intCast(u32, self.local_symbols.items.len); + _ = self.local_symbols.addOneAssumeCapacity(); + } - decl.link.macho.offset_table_index = @intCast(u32, self.offset_table.items.len); - _ = self.offset_table.addOneAssumeCapacity(); + if (self.offset_table_free_list.popOrNull()) |i| { + decl.link.macho.offset_table_index = i; + } else { + decl.link.macho.offset_table_index = @intCast(u32, self.offset_table.items.len); + _ = self.offset_table.addOneAssumeCapacity(); + } self.local_symbols.items[decl.link.macho.local_sym_index] = .{ .n_strx = 0, @@ -1401,12 +1410,11 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, } else if (self.last_text_block) |last| { const last_symbol = self.local_symbols.items[last.local_sym_index]; - // TODO pad out with NOPs and reenable - // const ideal_capacity = last.size * alloc_num / alloc_den; - // const ideal_capacity_end_addr = last_symbol.n_value + ideal_capacity; - // const new_start_addr = mem.alignForwardGeneric(u64, ideal_capacity_end_addr, alignment); - const end_vaddr = last_symbol.n_value + last.size; - const new_start_vaddr = mem.alignForwardGeneric(u64, end_vaddr, alignment); + // TODO We should pad out the excess capacity with NOPs. For executables, + // no padding seems to be OK, but it will probably not be for objects. + const ideal_capacity = last.size * alloc_num / alloc_den; + const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity; + const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment); block_placement = last; break :blk new_start_vaddr; } else { @@ -1421,7 +1429,7 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, assert(needed_size <= text_capacity); // TODO must move the entire text section. self.last_text_block = text_block; - text_section.size = needed_size; // TODO temp until we pad out with NOPs + text_section.size = needed_size; self.cmd_table_dirty = true; } diff --git a/test/stage2/test.zig b/test/stage2/test.zig index 3599478aa9..183555e331 100644 --- a/test/stage2/test.zig +++ b/test/stage2/test.zig @@ -218,6 +218,41 @@ pub fn addCases(ctx: *TestContext) !void { , "What is up? This is a longer message that will force the data to be relocated in virtual address space.\n", ); + // Now we print it twice. + case.addCompareOutput( + \\export fn _start() noreturn { + \\ print(); + \\ print(); + \\ + \\ exit(); + \\} + \\ + \\fn print() void { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (0x2000004), + \\ [arg1] "{rdi}" (1), + \\ [arg2] "{rsi}" (@ptrToInt("What is up? This is a longer message that will force the data to be relocated in virtual address space.\n")), + \\ [arg3] "{rdx}" (104) + \\ : "memory" + \\ ); + \\ return; + \\} + \\ + \\fn exit() noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (0x2000001), + \\ [arg1] "{rdi}" (0) + \\ : "memory" + \\ ); + \\ unreachable; + \\} + , + \\What is up? This is a longer message that will force the data to be relocated in virtual address space. + \\What is up? This is a longer message that will force the data to be relocated in virtual address space. + \\ + ); } {