From d31eb744cec1d991def2d6d42a14ded82af1dbbe Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 23 May 2024 12:03:46 +0200 Subject: [PATCH] link/macho: fix 32bit build --- src/link/MachO/InternalObject.zig | 5 +- src/link/MachO/Object.zig | 11 +++-- test/link/macho.zig | 80 +++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 6 deletions(-) diff --git a/src/link/MachO/InternalObject.zig b/src/link/MachO/InternalObject.zig index 10f81355f0..cbc7f3025c 100644 --- a/src/link/MachO/InternalObject.zig +++ b/src/link/MachO/InternalObject.zig @@ -134,8 +134,9 @@ pub fn resolveLiterals(self: InternalObject, lp: *MachO.LiteralPool, macho_file: assert(rel.tag == .local); const target = macho_file.getAtom(rel.target).?; const addend = std.math.cast(u32, rel.addend) orelse return error.Overflow; - try buffer.ensureUnusedCapacity(target.size); - buffer.resize(target.size) catch unreachable; + const target_size = std.math.cast(usize, target.size) orelse return error.Overflow; + try buffer.ensureUnusedCapacity(target_size); + buffer.resize(target_size) catch unreachable; try target.getData(macho_file, buffer.items); const res = try lp.insert(gpa, header.type(), buffer.items[addend..]); buffer.clearRetainingCapacity(); diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index b3e5d01c6c..28c3c127e3 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -508,7 +508,7 @@ fn initPointerLiterals(self: *Object, macho_file: *MachO) !void { ); return error.MalformedObject; } - const num_ptrs = @divExact(sect.size, rec_size); + const num_ptrs = math.cast(usize, @divExact(sect.size, rec_size)) orelse return error.Overflow; for (0..num_ptrs) |i| { const pos: u32 = @as(u32, @intCast(i)) * rec_size; @@ -541,7 +541,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO) for (subs.items) |sub| { const atom = macho_file.getAtom(sub.atom).?; - const atom_data = data[atom.off..][0..atom.size]; + const atom_off = math.cast(usize, atom.off) orelse return error.Overflow; + const atom_size = math.cast(usize, atom.size) orelse return error.Overflow; + const atom_data = data[atom_off..][0..atom_size]; const res = try lp.insert(gpa, header.type(), atom_data); if (!res.found_existing) { res.atom.* = sub.atom; @@ -561,8 +563,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO) }; const addend = math.cast(u32, rel.addend) orelse return error.Overflow; const target_atom = macho_file.getAtom(target).?; - try buffer.ensureUnusedCapacity(target_atom.size); - buffer.resize(target_atom.size) catch unreachable; + const target_atom_size = math.cast(usize, target_atom.size) orelse return error.Overflow; + try buffer.ensureUnusedCapacity(target_atom_size); + buffer.resize(target_atom_size) catch unreachable; try target_atom.getData(macho_file, buffer.items); const res = try lp.insert(gpa, header.type(), buffer.items[addend..]); buffer.clearRetainingCapacity(); diff --git a/test/link/macho.zig b/test/link/macho.zig index 64a7f2c46e..02450d880f 100644 --- a/test/link/macho.zig +++ b/test/link/macho.zig @@ -41,6 +41,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { macho_step.dependOn(testMergeLiteralsX64(b, .{ .target = x86_64_target })); macho_step.dependOn(testMergeLiteralsArm64(b, .{ .target = aarch64_target })); macho_step.dependOn(testMergeLiteralsArm642(b, .{ .target = aarch64_target })); + macho_step.dependOn(testMergeLiteralsAlignment(b, .{ .target = aarch64_target })); macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target })); macho_step.dependOn(testNoDeadStrip(b, .{ .target = default_target })); macho_step.dependOn(testNoExportsDylib(b, .{ .target = default_target })); @@ -1228,6 +1229,85 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step { return test_step; } +fn testMergeLiteralsAlignment(b: *Build, opts: Options) *Step { + const test_step = addTestStep(b, "merge-literals-alignment", opts); + + const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = + \\.globl _s1 + \\.globl _s2 + \\ + \\.section __TEXT,__cstring,cstring_literals + \\.align 3 + \\_s1: + \\ .asciz "str1" + \\_s2: + \\ .asciz "str2" + }); + + const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes = + \\.globl _s3 + \\.globl _s4 + \\ + \\.section __TEXT,__cstring,cstring_literals + \\.align 2 + \\_s3: + \\ .asciz "str1" + \\_s4: + \\ .asciz "str2" + }); + + const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = + \\#include + \\#include + \\#include + \\extern const char* s1; + \\extern const char* s2; + \\extern const char* s3; + \\extern const char* s4; + \\int main() { + \\ assert((uintptr_t)(&s1) % 8 == 0 && s1 == s3); + \\ assert((uintptr_t)(&s2) % 8 == 0 && s2 == s4); + \\ printf("%s%s%s%s", &s1, &s2, &s3, &s4); + \\ return 0; + \\} + , .c_source_flags = &.{"-Wno-format"} }); + + const runWithChecks = struct { + fn runWithChecks(step: *Step, exe: *Compile) void { + const run = addRunArtifact(exe); + run.expectStdOutEqual("str1str2str1str2"); + step.dependOn(&run.step); + + const check = exe.checkObject(); + check.dumpSection("__TEXT,__cstring"); + check.checkContains("str1\x00\x00\x00\x00str2\x00"); + check.checkInHeaders(); + check.checkExact("segname __TEXT"); + check.checkExact("sectname __cstring"); + check.checkExact("align 3"); + step.dependOn(&check.step); + } + }.runWithChecks; + + { + const exe = addExecutable(b, opts, .{ .name = "main1" }); + exe.addObject(a_o); + exe.addObject(b_o); + exe.addObject(main_o); + runWithChecks(test_step, exe); + } + + { + const exe = addExecutable(b, opts, .{ .name = "main2" }); + exe.addObject(b_o); + exe.addObject(a_o); + exe.addObject(main_o); + runWithChecks(test_step, exe); + } + + return test_step; +} + fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "merge-literals-objc", opts);