From 8eea5eddf773a8d1f9f883e71d00409e454ee0bd Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 14 May 2021 10:05:01 +0200 Subject: [PATCH] macho: fix bug with symbol growth and realloc --- src/link/MachO.zig | 8 +++++++- test/stage2/darwin.zig | 29 ++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 2ae9575b7e..d8518c4894 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1193,7 +1193,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment); if (need_realloc) { const vaddr = try self.growTextBlock(&decl.link.macho, code.len, required_alignment); - log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr }); + + log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr }); + if (vaddr != symbol.n_value) { log.debug(" (writing new offset table entry)", .{}); self.offset_table.items[decl.link.macho.offset_table_index] = .{ @@ -1203,6 +1205,8 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { }; try self.writeOffsetTableEntry(decl.link.macho.offset_table_index); } + + symbol.n_value = vaddr; } else if (code.len < decl.link.macho.size) { self.shrinkTextBlock(&decl.link.macho, code.len); } @@ -1219,7 +1223,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { const decl_name = mem.spanZ(decl.name); const name_str_index = try self.makeString(decl_name); const addr = try self.allocateTextBlock(&decl.link.macho, code.len, required_alignment); + log.debug("allocated text block for {s} at 0x{x}", .{ decl_name, addr }); + errdefer self.freeTextBlock(&decl.link.macho); symbol.* = .{ diff --git a/test/stage2/darwin.zig b/test/stage2/darwin.zig index 232bc42d25..f8d82391cc 100644 --- a/test/stage2/darwin.zig +++ b/test/stage2/darwin.zig @@ -41,7 +41,34 @@ pub fn addCases(ctx: *TestContext) !void { "Hello, World!\n", ); - // Now change the message only + // Print it 4 times and force growth and realloc. + case.addCompareOutput( + \\extern "c" fn write(usize, usize, usize) usize; + \\extern "c" fn exit(usize) noreturn; + \\ + \\export fn _start() noreturn { + \\ print(); + \\ print(); + \\ print(); + \\ print(); + \\ + \\ exit(0); + \\} + \\ + \\fn print() void { + \\ const msg = @ptrToInt("Hello, World!\n"); + \\ const len = 14; + \\ _ = write(1, msg, len); + \\} + , + \\Hello, World! + \\Hello, World! + \\Hello, World! + \\Hello, World! + \\ + ); + + // Print it once, and change the message. case.addCompareOutput( \\extern "c" fn write(usize, usize, usize) usize; \\extern "c" fn exit(usize) noreturn;