| ... | ... | @@ -6,9 +6,13 @@ pub fn build(b: *Build) void { |
| 6 | 6 | const elf_step = b.step("test-elf", "Run ELF tests"); |
| 7 | 7 | b.default_step = elf_step; |
| 8 | 8 | |
| 9 | | const musl_target = CrossTarget{ |
| 9 | const default_target = CrossTarget{ |
| 10 | 10 | .cpu_arch = .x86_64, // TODO relax this once ELF linker is able to handle other archs |
| 11 | 11 | .os_tag = .linux, |
| 12 | }; |
| 13 | const musl_target = CrossTarget{ |
| 14 | .cpu_arch = .x86_64, |
| 15 | .os_tag = .linux, |
| 12 | 16 | .abi = .musl, |
| 13 | 17 | }; |
| 14 | 18 | const glibc_target = CrossTarget{ |
| ... | ... | @@ -18,7 +22,8 @@ pub fn build(b: *Build) void { |
| 18 | 22 | }; |
| 19 | 23 | |
| 20 | 24 | // Exercise linker with self-hosted backend (no LLVM) |
| 21 | | elf_step.dependOn(testLinkingZig(b, .{ .use_llvm = false })); |
| 25 | elf_step.dependOn(testGcSectionsZig(b, .{ .use_llvm = false, .target = default_target })); |
| 26 | elf_step.dependOn(testLinkingZig(b, .{ .use_llvm = false, .target = default_target })); |
| 22 | 27 | elf_step.dependOn(testImportingDataDynamic(b, .{ .use_llvm = false, .target = glibc_target })); |
| 23 | 28 | elf_step.dependOn(testImportingDataStatic(b, .{ .use_llvm = false, .target = musl_target })); |
| 24 | 29 | |
| ... | ... | @@ -876,6 +881,110 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 876 | 881 | return test_step; |
| 877 | 882 | } |
| 878 | 883 | |
| 884 | fn testGcSectionsZig(b: *Build, opts: Options) *Step { |
| 885 | const test_step = addTestStep(b, "gc-sections-zig", opts); |
| 886 | |
| 887 | const obj = addObject(b, "obj", .{ |
| 888 | .target = opts.target, |
| 889 | .use_llvm = true, |
| 890 | .use_lld = true, |
| 891 | }); |
| 892 | addCSourceBytes(obj, |
| 893 | \\int live_var1 = 1; |
| 894 | \\int live_var2 = 2; |
| 895 | \\int dead_var1 = 3; |
| 896 | \\int dead_var2 = 4; |
| 897 | \\void live_fn1() {} |
| 898 | \\void live_fn2() { live_fn1(); } |
| 899 | \\void dead_fn1() {} |
| 900 | \\void dead_fn2() { dead_fn1(); } |
| 901 | , &.{}); |
| 902 | obj.link_function_sections = true; |
| 903 | obj.link_data_sections = true; |
| 904 | |
| 905 | { |
| 906 | const exe = addExecutable(b, "test1", opts); |
| 907 | addZigSourceBytes(exe, |
| 908 | \\const std = @import("std"); |
| 909 | \\extern var live_var1: i32; |
| 910 | \\extern var live_var2: i32; |
| 911 | \\extern fn live_fn2() void; |
| 912 | \\pub fn main() void { |
| 913 | \\ const stdout = std.io.getStdOut(); |
| 914 | \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable; |
| 915 | \\ live_fn2(); |
| 916 | \\} |
| 917 | ); |
| 918 | exe.addObject(obj); |
| 919 | exe.link_gc_sections = false; |
| 920 | |
| 921 | const run = addRunArtifact(exe); |
| 922 | run.expectStdOutEqual("1 2\n"); |
| 923 | test_step.dependOn(&run.step); |
| 924 | |
| 925 | const check = exe.checkObject(); |
| 926 | check.checkInSymtab(); |
| 927 | check.checkContains("live_var1"); |
| 928 | check.checkInSymtab(); |
| 929 | check.checkContains("live_var2"); |
| 930 | check.checkInSymtab(); |
| 931 | check.checkContains("dead_var1"); |
| 932 | check.checkInSymtab(); |
| 933 | check.checkContains("dead_var2"); |
| 934 | check.checkInSymtab(); |
| 935 | check.checkContains("live_fn1"); |
| 936 | check.checkInSymtab(); |
| 937 | check.checkContains("live_fn2"); |
| 938 | check.checkInSymtab(); |
| 939 | check.checkContains("dead_fn1"); |
| 940 | check.checkInSymtab(); |
| 941 | check.checkContains("dead_fn2"); |
| 942 | test_step.dependOn(&check.step); |
| 943 | } |
| 944 | |
| 945 | { |
| 946 | const exe = addExecutable(b, "test2", opts); |
| 947 | addZigSourceBytes(exe, |
| 948 | \\const std = @import("std"); |
| 949 | \\extern var live_var1: i32; |
| 950 | \\extern var live_var2: i32; |
| 951 | \\extern fn live_fn2() void; |
| 952 | \\pub fn main() void { |
| 953 | \\ const stdout = std.io.getStdOut(); |
| 954 | \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable; |
| 955 | \\ live_fn2(); |
| 956 | \\} |
| 957 | ); |
| 958 | exe.addObject(obj); |
| 959 | exe.link_gc_sections = true; |
| 960 | |
| 961 | const run = addRunArtifact(exe); |
| 962 | run.expectStdOutEqual("1 2\n"); |
| 963 | test_step.dependOn(&run.step); |
| 964 | |
| 965 | const check = exe.checkObject(); |
| 966 | check.checkInSymtab(); |
| 967 | check.checkContains("live_var1"); |
| 968 | check.checkInSymtab(); |
| 969 | check.checkContains("live_var2"); |
| 970 | check.checkInSymtab(); |
| 971 | check.checkNotPresent("dead_var1"); |
| 972 | check.checkInSymtab(); |
| 973 | check.checkNotPresent("dead_var2"); |
| 974 | check.checkInSymtab(); |
| 975 | check.checkContains("live_fn1"); |
| 976 | check.checkInSymtab(); |
| 977 | check.checkContains("live_fn2"); |
| 978 | check.checkInSymtab(); |
| 979 | check.checkNotPresent("dead_fn1"); |
| 980 | check.checkInSymtab(); |
| 981 | check.checkNotPresent("dead_fn2"); |
| 982 | test_step.dependOn(&check.step); |
| 983 | } |
| 984 | |
| 985 | return test_step; |
| 986 | } |
| 987 | |
| 879 | 988 | fn testHiddenWeakUndef(b: *Build, opts: Options) *Step { |
| 880 | 989 | const test_step = addTestStep(b, "hidden-weak-undef", opts); |
| 881 | 990 | |
| ... | ... | @@ -3114,6 +3223,7 @@ const Options = struct { |
| 3114 | 3223 | target: CrossTarget = .{ .cpu_arch = .x86_64, .os_tag = .linux }, |
| 3115 | 3224 | optimize: std.builtin.OptimizeMode = .Debug, |
| 3116 | 3225 | use_llvm: bool = true, |
| 3226 | use_lld: bool = false, |
| 3117 | 3227 | }; |
| 3118 | 3228 | |
| 3119 | 3229 | fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { |
| ... | ... | @@ -3134,7 +3244,7 @@ fn addExecutable(b: *Build, name: []const u8, opts: Options) *Compile { |
| 3134 | 3244 | .target = opts.target, |
| 3135 | 3245 | .optimize = opts.optimize, |
| 3136 | 3246 | .use_llvm = opts.use_llvm, |
| 3137 | | .use_lld = false, |
| 3247 | .use_lld = opts.use_lld, |
| 3138 | 3248 | }); |
| 3139 | 3249 | } |
| 3140 | 3250 | |
| ... | ... | @@ -3144,7 +3254,7 @@ fn addObject(b: *Build, name: []const u8, opts: Options) *Compile { |
| 3144 | 3254 | .target = opts.target, |
| 3145 | 3255 | .optimize = opts.optimize, |
| 3146 | 3256 | .use_llvm = opts.use_llvm, |
| 3147 | | .use_lld = false, |
| 3257 | .use_lld = opts.use_lld, |
| 3148 | 3258 | }); |
| 3149 | 3259 | } |
| 3150 | 3260 | |
| ... | ... | @@ -3164,7 +3274,7 @@ fn addSharedLibrary(b: *Build, name: []const u8, opts: Options) *Compile { |
| 3164 | 3274 | .target = opts.target, |
| 3165 | 3275 | .optimize = opts.optimize, |
| 3166 | 3276 | .use_llvm = opts.use_llvm, |
| 3167 | | .use_lld = false, |
| 3277 | .use_lld = opts.use_lld, |
| 3168 | 3278 | }); |
| 3169 | 3279 | } |
| 3170 | 3280 | |