authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-14 10:05:01+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-14 11:02:43+02:00
log8eea5eddf773a8d1f9f883e71d00409e454ee0bd
treead94c3581a3e8a93d44b05d8abedb35820ee2152
parent826179bff40fdbd8c3b11138897fcfbb3367def8

macho: fix bug with symbol growth and realloc


2 files changed, 35 insertions(+), 2 deletions(-)

src/link/MachO.zig+7-1
...@@ -1193,7 +1193,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -1193,7 +1193,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
1193 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);1193 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);
1194 if (need_realloc) {1194 if (need_realloc) {
1195 const vaddr = try self.growTextBlock(&decl.link.macho, code.len, required_alignment);1195 const vaddr = try self.growTextBlock(&decl.link.macho, code.len, required_alignment);
1196 log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr });1196
1197 log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr });
1198
1197 if (vaddr != symbol.n_value) {1199 if (vaddr != symbol.n_value) {
1198 log.debug(" (writing new offset table entry)", .{});1200 log.debug(" (writing new offset table entry)", .{});
1199 self.offset_table.items[decl.link.macho.offset_table_index] = .{1201 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 {...@@ -1203,6 +1205,8 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
1203 };1205 };
1204 try self.writeOffsetTableEntry(decl.link.macho.offset_table_index);1206 try self.writeOffsetTableEntry(decl.link.macho.offset_table_index);
1205 }1207 }
1208
1209 symbol.n_value = vaddr;
1206 } else if (code.len < decl.link.macho.size) {1210 } else if (code.len < decl.link.macho.size) {
1207 self.shrinkTextBlock(&decl.link.macho, code.len);1211 self.shrinkTextBlock(&decl.link.macho, code.len);
1208 }1212 }
...@@ -1219,7 +1223,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -1219,7 +1223,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
1219 const decl_name = mem.spanZ(decl.name);1223 const decl_name = mem.spanZ(decl.name);
1220 const name_str_index = try self.makeString(decl_name);1224 const name_str_index = try self.makeString(decl_name);
1221 const addr = try self.allocateTextBlock(&decl.link.macho, code.len, required_alignment);1225 const addr = try self.allocateTextBlock(&decl.link.macho, code.len, required_alignment);
1226
1222 log.debug("allocated text block for {s} at 0x{x}", .{ decl_name, addr });1227 log.debug("allocated text block for {s} at 0x{x}", .{ decl_name, addr });
1228
1223 errdefer self.freeTextBlock(&decl.link.macho);1229 errdefer self.freeTextBlock(&decl.link.macho);
12241230
1225 symbol.* = .{1231 symbol.* = .{
test/stage2/darwin.zig+28-1
...@@ -41,7 +41,34 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -41,7 +41,34 @@ pub fn addCases(ctx: *TestContext) !void {
41 "Hello, World!\n",41 "Hello, World!\n",
42 );42 );
4343
44 // Now change the message only44 // Print it 4 times and force growth and realloc.
45 case.addCompareOutput(
46 \\extern "c" fn write(usize, usize, usize) usize;
47 \\extern "c" fn exit(usize) noreturn;
48 \\
49 \\export fn _start() noreturn {
50 \\ print();
51 \\ print();
52 \\ print();
53 \\ print();
54 \\
55 \\ exit(0);
56 \\}
57 \\
58 \\fn print() void {
59 \\ const msg = @ptrToInt("Hello, World!\n");
60 \\ const len = 14;
61 \\ _ = write(1, msg, len);
62 \\}
63 ,
64 \\Hello, World!
65 \\Hello, World!
66 \\Hello, World!
67 \\Hello, World!
68 \\
69 );
70
71 // Print it once, and change the message.
45 case.addCompareOutput(72 case.addCompareOutput(
46 \\extern "c" fn write(usize, usize, usize) usize;73 \\extern "c" fn write(usize, usize, usize) usize;
47 \\extern "c" fn exit(usize) noreturn;74 \\extern "c" fn exit(usize) noreturn;