| ... | ... | @@ -41,6 +41,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { |
| 41 | 41 | macho_step.dependOn(testMergeLiteralsX64(b, .{ .target = x86_64_target })); |
| 42 | 42 | macho_step.dependOn(testMergeLiteralsArm64(b, .{ .target = aarch64_target })); |
| 43 | 43 | macho_step.dependOn(testMergeLiteralsArm642(b, .{ .target = aarch64_target })); |
| 44 | macho_step.dependOn(testMergeLiteralsAlignment(b, .{ .target = aarch64_target })); |
| 44 | 45 | macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target })); |
| 45 | 46 | macho_step.dependOn(testNoDeadStrip(b, .{ .target = default_target })); |
| 46 | 47 | macho_step.dependOn(testNoExportsDylib(b, .{ .target = default_target })); |
| ... | ... | @@ -1228,6 +1229,85 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step { |
| 1228 | 1229 | return test_step; |
| 1229 | 1230 | } |
| 1230 | 1231 | |
| 1232 | fn 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 | |
| 1231 | 1311 | fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step { |
| 1232 | 1312 | const test_step = addTestStep(b, "merge-literals-objc", opts); |
| 1233 | 1313 | |