| ... | ... | @@ -38,6 +38,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { |
| 38 | 38 | macho_step.dependOn(testLayout(b, .{ .target = default_target })); |
| 39 | 39 | macho_step.dependOn(testLinkingStaticLib(b, .{ .target = default_target })); |
| 40 | 40 | macho_step.dependOn(testLinksection(b, .{ .target = default_target })); |
| 41 | macho_step.dependOn(testMergeLiteralsX64(b, .{ .target = x86_64_target })); |
| 41 | 42 | macho_step.dependOn(testMergeLiteralsArm64(b, .{ .target = aarch64_target })); |
| 42 | 43 | macho_step.dependOn(testMergeLiteralsArm642(b, .{ .target = aarch64_target })); |
| 43 | 44 | macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target })); |
| ... | ... | @@ -917,8 +918,124 @@ fn testLinksection(b: *Build, opts: Options) *Step { |
| 917 | 918 | return test_step; |
| 918 | 919 | } |
| 919 | 920 | |
| 921 | fn testMergeLiteralsX64(b: *Build, opts: Options) *Step { |
| 922 | const test_step = addTestStep(b, "merge-literals-x64", opts); |
| 923 | |
| 924 | const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = |
| 925 | \\.globl _q1 |
| 926 | \\.globl _s1 |
| 927 | \\ |
| 928 | \\.align 4 |
| 929 | \\_q1: |
| 930 | \\ lea L._q1(%rip), %rax |
| 931 | \\ mov (%rax), %xmm0 |
| 932 | \\ ret |
| 933 | \\ |
| 934 | \\.section __TEXT,__cstring,cstring_literals |
| 935 | \\l._s1: |
| 936 | \\ .asciz "hello" |
| 937 | \\ |
| 938 | \\.section __TEXT,__literal8,8byte_literals |
| 939 | \\.align 8 |
| 940 | \\L._q1: |
| 941 | \\ .double 1.2345 |
| 942 | \\ |
| 943 | \\.section __DATA,__data |
| 944 | \\.align 8 |
| 945 | \\_s1: |
| 946 | \\ .quad l._s1 |
| 947 | }); |
| 948 | |
| 949 | const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes = |
| 950 | \\.globl _q2 |
| 951 | \\.globl _s2 |
| 952 | \\.globl _s3 |
| 953 | \\ |
| 954 | \\.align 4 |
| 955 | \\_q2: |
| 956 | \\ lea L._q2(%rip), %rax |
| 957 | \\ mov (%rax), %xmm0 |
| 958 | \\ ret |
| 959 | \\ |
| 960 | \\.section __TEXT,__cstring,cstring_literals |
| 961 | \\l._s2: |
| 962 | \\ .asciz "hello" |
| 963 | \\l._s3: |
| 964 | \\ .asciz "world" |
| 965 | \\ |
| 966 | \\.section __TEXT,__literal8,8byte_literals |
| 967 | \\.align 8 |
| 968 | \\L._q2: |
| 969 | \\ .double 1.2345 |
| 970 | \\ |
| 971 | \\.section __DATA,__data |
| 972 | \\.align 8 |
| 973 | \\_s2: |
| 974 | \\ .quad l._s2 |
| 975 | \\_s3: |
| 976 | \\ .quad l._s3 |
| 977 | }); |
| 978 | |
| 979 | const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = |
| 980 | \\#include <stdio.h> |
| 981 | \\extern double q1(); |
| 982 | \\extern double q2(); |
| 983 | \\extern const char* s1; |
| 984 | \\extern const char* s2; |
| 985 | \\extern const char* s3; |
| 986 | \\int main() { |
| 987 | \\ printf("%s, %s, %s, %f, %f", s1, s2, s3, q1(), q2()); |
| 988 | \\ return 0; |
| 989 | \\} |
| 990 | }); |
| 991 | |
| 992 | const runWithChecks = struct { |
| 993 | fn runWithChecks(step: *Step, exe: *Compile) void { |
| 994 | const run = addRunArtifact(exe); |
| 995 | run.expectStdOutEqual("hello, hello, world, 1.234500, 1.234500"); |
| 996 | step.dependOn(&run.step); |
| 997 | |
| 998 | const check = exe.checkObject(); |
| 999 | check.dumpSection("__TEXT,__const"); |
| 1000 | check.checkContains("\x8d\x97n\x12\x83\xc0\xf3?"); |
| 1001 | check.dumpSection("__TEXT,__cstring"); |
| 1002 | check.checkContains("hello\x00world\x00%s, %s, %s, %f, %f\x00"); |
| 1003 | step.dependOn(&check.step); |
| 1004 | } |
| 1005 | }.runWithChecks; |
| 1006 | |
| 1007 | { |
| 1008 | const exe = addExecutable(b, opts, .{ .name = "main1" }); |
| 1009 | exe.addObject(a_o); |
| 1010 | exe.addObject(b_o); |
| 1011 | exe.addObject(main_o); |
| 1012 | runWithChecks(test_step, exe); |
| 1013 | } |
| 1014 | |
| 1015 | { |
| 1016 | const exe = addExecutable(b, opts, .{ .name = "main2" }); |
| 1017 | exe.addObject(b_o); |
| 1018 | exe.addObject(a_o); |
| 1019 | exe.addObject(main_o); |
| 1020 | runWithChecks(test_step, exe); |
| 1021 | } |
| 1022 | |
| 1023 | { |
| 1024 | const c_o = addObject(b, opts, .{ .name = "c" }); |
| 1025 | c_o.addObject(a_o); |
| 1026 | c_o.addObject(b_o); |
| 1027 | c_o.addObject(main_o); |
| 1028 | |
| 1029 | const exe = addExecutable(b, opts, .{ .name = "main3" }); |
| 1030 | exe.addObject(c_o); |
| 1031 | runWithChecks(test_step, exe); |
| 1032 | } |
| 1033 | |
| 1034 | return test_step; |
| 1035 | } |
| 1036 | |
| 920 | 1037 | fn testMergeLiteralsArm64(b: *Build, opts: Options) *Step { |
| 921 | | const test_step = addTestStep(b, "merge-literals", opts); |
| 1038 | const test_step = addTestStep(b, "merge-literals-arm64", opts); |
| 922 | 1039 | |
| 923 | 1040 | const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = |
| 924 | 1041 | \\.globl _q1 |
| ... | ... | @@ -1038,7 +1155,7 @@ fn testMergeLiteralsArm64(b: *Build, opts: Options) *Step { |
| 1038 | 1155 | /// which is also the case for the system linker and lld - linking succeeds, runtime segfaults. |
| 1039 | 1156 | /// It should also be mentioned that runtime segfault is not due to the linker but faulty input asm. |
| 1040 | 1157 | fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step { |
| 1041 | | const test_step = addTestStep(b, "merge-literals-2", opts); |
| 1158 | const test_step = addTestStep(b, "merge-literals-arm64-2", opts); |
| 1042 | 1159 | |
| 1043 | 1160 | const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = |
| 1044 | 1161 | \\.globl _q1 |