authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 15:13:35+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-28 15:13:35+02:00
log91f2e66bf9c010bd09a41e21aeb3e7eda80dd49f
tree5aab3ee44eca157c6703dcdacb91e170a7044729
parent785bd270ed47034aac7a7a231e2aa0ab1254c621

elf: test TLS in static programs


1 files changed, 33 insertions(+), 2 deletions(-)

test/link/elf.zig+33-2
...@@ -18,7 +18,8 @@ pub fn build(b: *Build) void {...@@ -18,7 +18,8 @@ pub fn build(b: *Build) void {
18 // Exercise linker with LLVM backend18 // Exercise linker with LLVM backend
19 elf_step.dependOn(testEmptyObject(b, .{ .target = musl_target }));19 elf_step.dependOn(testEmptyObject(b, .{ .target = musl_target }));
20 elf_step.dependOn(testLinkingC(b, .{ .target = musl_target }));20 elf_step.dependOn(testLinkingC(b, .{ .target = musl_target }));
21 elf_step.dependOn(testLinkingZig(b, .{}));21 elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target }));
22 elf_step.dependOn(testTlsStatic(b, .{ .target = musl_target }));
22}23}
2324
24fn testEmptyObject(b: *Build, opts: Options) *Step {25fn testEmptyObject(b: *Build, opts: Options) *Step {
...@@ -91,6 +92,37 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {...@@ -91,6 +92,37 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {
91 return test_step;92 return test_step;
92}93}
9394
95fn testTlsStatic(b: *Build, opts: Options) *Step {
96 const test_step = addTestStep(b, "tls-static", opts);
97
98 const exe = addExecutable(b, opts);
99 addCSourceBytes(exe,
100 \\#include <stdio.h>
101 \\_Thread_local int a = 10;
102 \\_Thread_local int b;
103 \\_Thread_local char c = 'a';
104 \\int main(int argc, char* argv[]) {
105 \\ printf("%d %d %c\n", a, b, c);
106 \\ a += 1;
107 \\ b += 1;
108 \\ c += 1;
109 \\ printf("%d %d %c\n", a, b, c);
110 \\ return 0;
111 \\}
112 );
113 exe.is_linking_libc = true;
114
115 const run = addRunArtifact(exe);
116 run.expectStdOutEqual(
117 \\10 0 a
118 \\11 1 b
119 \\
120 );
121 test_step.dependOn(&run.step);
122
123 return test_step;
124}
125
94const Options = struct {126const Options = struct {
95 target: CrossTarget = .{ .cpu_arch = .x86_64, .os_tag = .linux },127 target: CrossTarget = .{ .cpu_arch = .x86_64, .os_tag = .linux },
96 optimize: std.builtin.OptimizeMode = .Debug,128 optimize: std.builtin.OptimizeMode = .Debug,
...@@ -114,7 +146,6 @@ fn addExecutable(b: *Build, opts: Options) *Compile {...@@ -114,7 +146,6 @@ fn addExecutable(b: *Build, opts: Options) *Compile {
114 .name = "test",146 .name = "test",
115 .target = opts.target,147 .target = opts.target,
116 .optimize = opts.optimize,148 .optimize = opts.optimize,
117 .single_threaded = true, // TODO temp until we teach linker how to handle TLS
118 .use_llvm = opts.use_llvm,149 .use_llvm = opts.use_llvm,
119 .use_lld = false,150 .use_lld = false,
120 });151 });