authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-05-23 12:03:46+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-05-23 12:04:17+02:00
logd31eb744cec1d991def2d6d42a14ded82af1dbbe
treef613ac6f06fe2cb46c58cd55eb1eaaee09990e07
parentf3a503eca26e39e7a0870bf02c24b2879ae2cc18

link/macho: fix 32bit build


3 files changed, 90 insertions(+), 6 deletions(-)

src/link/MachO/InternalObject.zig+3-2
...@@ -134,8 +134,9 @@ pub fn resolveLiterals(self: InternalObject, lp: *MachO.LiteralPool, macho_file:...@@ -134,8 +134,9 @@ pub fn resolveLiterals(self: InternalObject, lp: *MachO.LiteralPool, macho_file:
134 assert(rel.tag == .local);134 assert(rel.tag == .local);
135 const target = macho_file.getAtom(rel.target).?;135 const target = macho_file.getAtom(rel.target).?;
136 const addend = std.math.cast(u32, rel.addend) orelse return error.Overflow;136 const addend = std.math.cast(u32, rel.addend) orelse return error.Overflow;
137 try buffer.ensureUnusedCapacity(target.size);137 const target_size = std.math.cast(usize, target.size) orelse return error.Overflow;
138 buffer.resize(target.size) catch unreachable;138 try buffer.ensureUnusedCapacity(target_size);
139 buffer.resize(target_size) catch unreachable;
139 try target.getData(macho_file, buffer.items);140 try target.getData(macho_file, buffer.items);
140 const res = try lp.insert(gpa, header.type(), buffer.items[addend..]);141 const res = try lp.insert(gpa, header.type(), buffer.items[addend..]);
141 buffer.clearRetainingCapacity();142 buffer.clearRetainingCapacity();
src/link/MachO/Object.zig+7-4
...@@ -508,7 +508,7 @@ fn initPointerLiterals(self: *Object, macho_file: *MachO) !void {...@@ -508,7 +508,7 @@ fn initPointerLiterals(self: *Object, macho_file: *MachO) !void {
508 );508 );
509 return error.MalformedObject;509 return error.MalformedObject;
510 }510 }
511 const num_ptrs = @divExact(sect.size, rec_size);511 const num_ptrs = math.cast(usize, @divExact(sect.size, rec_size)) orelse return error.Overflow;
512512
513 for (0..num_ptrs) |i| {513 for (0..num_ptrs) |i| {
514 const pos: u32 = @as(u32, @intCast(i)) * rec_size;514 const pos: u32 = @as(u32, @intCast(i)) * rec_size;
...@@ -541,7 +541,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)...@@ -541,7 +541,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
541541
542 for (subs.items) |sub| {542 for (subs.items) |sub| {
543 const atom = macho_file.getAtom(sub.atom).?;543 const atom = macho_file.getAtom(sub.atom).?;
544 const atom_data = data[atom.off..][0..atom.size];544 const atom_off = math.cast(usize, atom.off) orelse return error.Overflow;
545 const atom_size = math.cast(usize, atom.size) orelse return error.Overflow;
546 const atom_data = data[atom_off..][0..atom_size];
545 const res = try lp.insert(gpa, header.type(), atom_data);547 const res = try lp.insert(gpa, header.type(), atom_data);
546 if (!res.found_existing) {548 if (!res.found_existing) {
547 res.atom.* = sub.atom;549 res.atom.* = sub.atom;
...@@ -561,8 +563,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)...@@ -561,8 +563,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
561 };563 };
562 const addend = math.cast(u32, rel.addend) orelse return error.Overflow;564 const addend = math.cast(u32, rel.addend) orelse return error.Overflow;
563 const target_atom = macho_file.getAtom(target).?;565 const target_atom = macho_file.getAtom(target).?;
564 try buffer.ensureUnusedCapacity(target_atom.size);566 const target_atom_size = math.cast(usize, target_atom.size) orelse return error.Overflow;
565 buffer.resize(target_atom.size) catch unreachable;567 try buffer.ensureUnusedCapacity(target_atom_size);
568 buffer.resize(target_atom_size) catch unreachable;
566 try target_atom.getData(macho_file, buffer.items);569 try target_atom.getData(macho_file, buffer.items);
567 const res = try lp.insert(gpa, header.type(), buffer.items[addend..]);570 const res = try lp.insert(gpa, header.type(), buffer.items[addend..]);
568 buffer.clearRetainingCapacity();571 buffer.clearRetainingCapacity();
test/link/macho.zig+80
...@@ -41,6 +41,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {...@@ -41,6 +41,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
41 macho_step.dependOn(testMergeLiteralsX64(b, .{ .target = x86_64_target }));41 macho_step.dependOn(testMergeLiteralsX64(b, .{ .target = x86_64_target }));
42 macho_step.dependOn(testMergeLiteralsArm64(b, .{ .target = aarch64_target }));42 macho_step.dependOn(testMergeLiteralsArm64(b, .{ .target = aarch64_target }));
43 macho_step.dependOn(testMergeLiteralsArm642(b, .{ .target = aarch64_target }));43 macho_step.dependOn(testMergeLiteralsArm642(b, .{ .target = aarch64_target }));
44 macho_step.dependOn(testMergeLiteralsAlignment(b, .{ .target = aarch64_target }));
44 macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target }));45 macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target }));
45 macho_step.dependOn(testNoDeadStrip(b, .{ .target = default_target }));46 macho_step.dependOn(testNoDeadStrip(b, .{ .target = default_target }));
46 macho_step.dependOn(testNoExportsDylib(b, .{ .target = default_target }));47 macho_step.dependOn(testNoExportsDylib(b, .{ .target = default_target }));
...@@ -1228,6 +1229,85 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step {...@@ -1228,6 +1229,85 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step {
1228 return test_step;1229 return test_step;
1229}1230}
12301231
1232fn testMergeLiteralsAlignment(b: *Build, opts: Options) *Step {
1233 const test_step = addTestStep(b, "merge-literals-alignment", opts);
1234
1235 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
1236 \\.globl _s1
1237 \\.globl _s2
1238 \\
1239 \\.section __TEXT,__cstring,cstring_literals
1240 \\.align 3
1241 \\_s1:
1242 \\ .asciz "str1"
1243 \\_s2:
1244 \\ .asciz "str2"
1245 });
1246
1247 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes =
1248 \\.globl _s3
1249 \\.globl _s4
1250 \\
1251 \\.section __TEXT,__cstring,cstring_literals
1252 \\.align 2
1253 \\_s3:
1254 \\ .asciz "str1"
1255 \\_s4:
1256 \\ .asciz "str2"
1257 });
1258
1259 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
1260 \\#include <assert.h>
1261 \\#include <stdint.h>
1262 \\#include <stdio.h>
1263 \\extern const char* s1;
1264 \\extern const char* s2;
1265 \\extern const char* s3;
1266 \\extern const char* s4;
1267 \\int main() {
1268 \\ assert((uintptr_t)(&s1) % 8 == 0 && s1 == s3);
1269 \\ assert((uintptr_t)(&s2) % 8 == 0 && s2 == s4);
1270 \\ printf("%s%s%s%s", &s1, &s2, &s3, &s4);
1271 \\ return 0;
1272 \\}
1273 , .c_source_flags = &.{"-Wno-format"} });
1274
1275 const runWithChecks = struct {
1276 fn runWithChecks(step: *Step, exe: *Compile) void {
1277 const run = addRunArtifact(exe);
1278 run.expectStdOutEqual("str1str2str1str2");
1279 step.dependOn(&run.step);
1280
1281 const check = exe.checkObject();
1282 check.dumpSection("__TEXT,__cstring");
1283 check.checkContains("str1\x00\x00\x00\x00str2\x00");
1284 check.checkInHeaders();
1285 check.checkExact("segname __TEXT");
1286 check.checkExact("sectname __cstring");
1287 check.checkExact("align 3");
1288 step.dependOn(&check.step);
1289 }
1290 }.runWithChecks;
1291
1292 {
1293 const exe = addExecutable(b, opts, .{ .name = "main1" });
1294 exe.addObject(a_o);
1295 exe.addObject(b_o);
1296 exe.addObject(main_o);
1297 runWithChecks(test_step, exe);
1298 }
1299
1300 {
1301 const exe = addExecutable(b, opts, .{ .name = "main2" });
1302 exe.addObject(b_o);
1303 exe.addObject(a_o);
1304 exe.addObject(main_o);
1305 runWithChecks(test_step, exe);
1306 }
1307
1308 return test_step;
1309}
1310
1231fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step {1311fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step {
1232 const test_step = addTestStep(b, "merge-literals-objc", opts);1312 const test_step = addTestStep(b, "merge-literals-objc", opts);
12331313