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:
134134 assert(rel.tag == .local);
135135 const target = macho_file.getAtom(rel.target).?;
136136 const addend = std.math.cast(u32, rel.addend) orelse return error.Overflow;
137 try buffer.ensureUnusedCapacity(target.size);
138 buffer.resize(target.size) catch unreachable;
137 const target_size = std.math.cast(usize, target.size) orelse return error.Overflow;
138 try buffer.ensureUnusedCapacity(target_size);
139 buffer.resize(target_size) catch unreachable;
139140 try target.getData(macho_file, buffer.items);
140141 const res = try lp.insert(gpa, header.type(), buffer.items[addend..]);
141142 buffer.clearRetainingCapacity();
src/link/MachO/Object.zig+7-4
......@@ -508,7 +508,7 @@ fn initPointerLiterals(self: *Object, macho_file: *MachO) !void {
508508 );
509509 return error.MalformedObject;
510510 }
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
513513 for (0..num_ptrs) |i| {
514514 const pos: u32 = @as(u32, @intCast(i)) * rec_size;
......@@ -541,7 +541,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
541541
542542 for (subs.items) |sub| {
543543 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];
545547 const res = try lp.insert(gpa, header.type(), atom_data);
546548 if (!res.found_existing) {
547549 res.atom.* = sub.atom;
......@@ -561,8 +563,9 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
561563 };
562564 const addend = math.cast(u32, rel.addend) orelse return error.Overflow;
563565 const target_atom = macho_file.getAtom(target).?;
564 try buffer.ensureUnusedCapacity(target_atom.size);
565 buffer.resize(target_atom.size) catch unreachable;
566 const target_atom_size = math.cast(usize, target_atom.size) orelse return error.Overflow;
567 try buffer.ensureUnusedCapacity(target_atom_size);
568 buffer.resize(target_atom_size) catch unreachable;
566569 try target_atom.getData(macho_file, buffer.items);
567570 const res = try lp.insert(gpa, header.type(), buffer.items[addend..]);
568571 buffer.clearRetainingCapacity();
test/link/macho.zig+80
......@@ -41,6 +41,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
4141 macho_step.dependOn(testMergeLiteralsX64(b, .{ .target = x86_64_target }));
4242 macho_step.dependOn(testMergeLiteralsArm64(b, .{ .target = aarch64_target }));
4343 macho_step.dependOn(testMergeLiteralsArm642(b, .{ .target = aarch64_target }));
44 macho_step.dependOn(testMergeLiteralsAlignment(b, .{ .target = aarch64_target }));
4445 macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target }));
4546 macho_step.dependOn(testNoDeadStrip(b, .{ .target = default_target }));
4647 macho_step.dependOn(testNoExportsDylib(b, .{ .target = default_target }));
......@@ -1228,6 +1229,85 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step {
12281229 return test_step;
12291230}
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
12311311fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step {
12321312 const test_step = addTestStep(b, "merge-literals-objc", opts);
12331313