authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-07 10:47:44+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:05+02:00
logc940735c4d091d77594deb15226bbd67cf36cdf2
tree430cda0620a8021f2e7205ea0bb395ca0b6a8122
parent149dd82d5465abc136d9ef2f4270ed041a3b6e3e

elf: port more linker tests


1 files changed, 115 insertions(+), 25 deletions(-)

test/link/elf.zig+115-25
...@@ -31,6 +31,7 @@ pub fn build(b: *Build) void {...@@ -31,6 +31,7 @@ pub fn build(b: *Build) void {
31 // elf_step.dependOn(testLinkingZig(b, .{ .use_llvm = false }));31 // elf_step.dependOn(testLinkingZig(b, .{ .use_llvm = false }));
3232
33 // Exercise linker with LLVM backend33 // Exercise linker with LLVM backend
34 elf_step.dependOn(testAbsSymbols(b, .{ .target = musl_target }));
34 elf_step.dependOn(testCommonSymbols(b, .{ .target = musl_target }));35 elf_step.dependOn(testCommonSymbols(b, .{ .target = musl_target }));
35 elf_step.dependOn(testCommonSymbolsInArchive(b, .{ .target = musl_target }));36 elf_step.dependOn(testCommonSymbolsInArchive(b, .{ .target = musl_target }));
36 elf_step.dependOn(testEmptyObject(b, .{ .target = musl_target }));37 elf_step.dependOn(testEmptyObject(b, .{ .target = musl_target }));
...@@ -41,6 +42,7 @@ pub fn build(b: *Build) void {...@@ -41,6 +42,7 @@ pub fn build(b: *Build) void {
41 elf_step.dependOn(testTlsStatic(b, .{ .target = musl_target }));42 elf_step.dependOn(testTlsStatic(b, .{ .target = musl_target }));
4243
43 elf_step.dependOn(testAsNeeded(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));44 elf_step.dependOn(testAsNeeded(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
45 elf_step.dependOn(testCanonicalPlt(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
44 elf_step.dependOn(testDsoPlt(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));46 elf_step.dependOn(testDsoPlt(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
45 elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));47 elf_step.dependOn(testDsoUndef(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
46 elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));48 elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target, .dynamic_linker = dynamic_linker }));
...@@ -50,6 +52,46 @@ pub fn build(b: *Build) void {...@@ -50,6 +52,46 @@ pub fn build(b: *Build) void {
50 }52 }
51}53}
5254
55fn testAbsSymbols(b: *Build, opts: Options) *Step {
56 const test_step = addTestStep(b, "abs-symbols", opts);
57
58 const obj = addObject(b, "obj", opts);
59 addAsmSourceBytes(obj,
60 \\.globl foo
61 \\foo = 0x800008
62 );
63
64 const exe = addExecutable(b, "test", opts);
65 addCSourceBytes(exe,
66 \\#include <signal.h>
67 \\#include <stdio.h>
68 \\#include <stdlib.h>
69 \\#include <ucontext.h>
70 \\#include <assert.h>
71 \\void handler(int signum, siginfo_t *info, void *ptr) {
72 \\ assert((size_t)info->si_addr == 0x800008);
73 \\ exit(0);
74 \\}
75 \\extern int foo;
76 \\int main() {
77 \\ struct sigaction act;
78 \\ act.sa_flags = SA_SIGINFO | SA_RESETHAND;
79 \\ act.sa_sigaction = handler;
80 \\ sigemptyset(&act.sa_mask);
81 \\ sigaction(SIGSEGV, &act, 0);
82 \\ foo = 5;
83 \\ return 0;
84 \\}
85 , &.{});
86 exe.addObject(obj);
87 exe.linkLibC();
88
89 const run = addRunArtifact(exe);
90 test_step.dependOn(&run.step);
91
92 return test_step;
93}
94
53fn testAsNeeded(b: *Build, opts: Options) *Step {95fn testAsNeeded(b: *Build, opts: Options) *Step {
54 const test_step = addTestStep(b, "as-needed", opts);96 const test_step = addTestStep(b, "as-needed", opts);
5597
...@@ -62,7 +104,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {...@@ -62,7 +104,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {
62 \\ return 0;104 \\ return 0;
63 \\}105 \\}
64 , &.{});106 , &.{});
65 main_o.is_linking_libc = true;107 main_o.linkLibC();
66108
67 const libfoo = addSharedLibrary(b, "foo", opts);109 const libfoo = addSharedLibrary(b, "foo", opts);
68 addCSourceBytes(libfoo, "int foo() { return 42; }", &.{"-fPIC"});110 addCSourceBytes(libfoo, "int foo() { return 42; }", &.{"-fPIC"});
...@@ -88,7 +130,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {...@@ -88,7 +130,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {
88 exe.linkSystemLibrary2("baz", .{ .needed = true });130 exe.linkSystemLibrary2("baz", .{ .needed = true });
89 exe.addLibraryPath(libbaz.getEmittedBinDirectory());131 exe.addLibraryPath(libbaz.getEmittedBinDirectory());
90 exe.addRPath(libbaz.getEmittedBinDirectory());132 exe.addRPath(libbaz.getEmittedBinDirectory());
91 exe.is_linking_libc = true;133 exe.linkLibC();
92134
93 const run = addRunArtifact(exe);135 const run = addRunArtifact(exe);
94 run.expectStdOutEqual("42\n");136 run.expectStdOutEqual("42\n");
...@@ -114,7 +156,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {...@@ -114,7 +156,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {
114 exe.linkSystemLibrary2("baz", .{ .needed = false });156 exe.linkSystemLibrary2("baz", .{ .needed = false });
115 exe.addLibraryPath(libbaz.getEmittedBinDirectory());157 exe.addLibraryPath(libbaz.getEmittedBinDirectory());
116 exe.addRPath(libbaz.getEmittedBinDirectory());158 exe.addRPath(libbaz.getEmittedBinDirectory());
117 exe.is_linking_libc = true;159 exe.linkLibC();
118160
119 const run = addRunArtifact(exe);161 const run = addRunArtifact(exe);
120 run.expectStdOutEqual("42\n");162 run.expectStdOutEqual("42\n");
...@@ -132,6 +174,54 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {...@@ -132,6 +174,54 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {
132 return test_step;174 return test_step;
133}175}
134176
177fn testCanonicalPlt(b: *Build, opts: Options) *Step {
178 const test_step = addTestStep(b, "canonical-plt", opts);
179
180 const dso = addSharedLibrary(b, "a", opts);
181 addCSourceBytes(dso,
182 \\void *foo() {
183 \\ return foo;
184 \\}
185 \\void *bar() {
186 \\ return bar;
187 \\}
188 , &.{"-fPIC"});
189
190 const b_o = addObject(b, "obj", opts);
191 addCSourceBytes(b_o,
192 \\void *bar();
193 \\void *baz() {
194 \\ return bar;
195 \\}
196 , &.{"-fPIC"});
197
198 const main_o = addObject(b, "main", opts);
199 addCSourceBytes(main_o,
200 \\#include <assert.h>
201 \\void *foo();
202 \\void *bar();
203 \\void *baz();
204 \\int main() {
205 \\ assert(foo == foo());
206 \\ assert(bar == bar());
207 \\ assert(bar == baz());
208 \\}
209 , &.{"-fno-PIC"});
210 main_o.linkLibC();
211
212 const exe = addExecutable(b, "main", opts);
213 exe.addObject(main_o);
214 exe.addObject(b_o);
215 exe.linkLibrary(dso);
216 exe.linkLibC();
217 exe.pie = false;
218
219 const run = addRunArtifact(exe);
220 test_step.dependOn(&run.step);
221
222 return test_step;
223}
224
135fn testCommonSymbols(b: *Build, opts: Options) *Step {225fn testCommonSymbols(b: *Build, opts: Options) *Step {
136 const test_step = addTestStep(b, "common-symbols", opts);226 const test_step = addTestStep(b, "common-symbols", opts);
137227
...@@ -150,7 +240,7 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step {...@@ -150,7 +240,7 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step {
150 \\ printf("%d %d %d\n", foo, bar, baz);240 \\ printf("%d %d %d\n", foo, bar, baz);
151 \\}241 \\}
152 , &.{"-fcommon"});242 , &.{"-fcommon"});
153 exe.is_linking_libc = true;243 exe.linkLibC();
154244
155 const run = addRunArtifact(exe);245 const run = addRunArtifact(exe);
156 run.expectStdOutEqual("0 5 42\n");246 run.expectStdOutEqual("0 5 42\n");
...@@ -173,7 +263,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {...@@ -173,7 +263,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
173 \\ printf("%d %d %d %d\n", foo, bar, baz, two ? two() : -1);263 \\ printf("%d %d %d %d\n", foo, bar, baz, two ? two() : -1);
174 \\}264 \\}
175 , &.{"-fcommon"});265 , &.{"-fcommon"});
176 a_o.is_linking_libc = true;266 a_o.linkLibC();
177267
178 const b_o = addObject(b, "b", opts);268 const b_o = addObject(b, "b", opts);
179 addCSourceBytes(b_o, "int foo = 5;", &.{"-fcommon"});269 addCSourceBytes(b_o, "int foo = 5;", &.{"-fcommon"});
...@@ -196,7 +286,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {...@@ -196,7 +286,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
196 const exe = addExecutable(b, "test", opts);286 const exe = addExecutable(b, "test", opts);
197 exe.addObject(a_o);287 exe.addObject(a_o);
198 exe.linkLibrary(lib);288 exe.linkLibrary(lib);
199 exe.is_linking_libc = true;289 exe.linkLibC();
200290
201 const run = addRunArtifact(exe);291 const run = addRunArtifact(exe);
202 run.expectStdOutEqual("5 0 0 -1\n");292 run.expectStdOutEqual("5 0 0 -1\n");
...@@ -218,7 +308,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {...@@ -218,7 +308,7 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
218 const exe = addExecutable(b, "test", opts);308 const exe = addExecutable(b, "test", opts);
219 exe.addObject(a_o);309 exe.addObject(a_o);
220 exe.linkLibrary(lib);310 exe.linkLibrary(lib);
221 exe.is_linking_libc = true;311 exe.linkLibC();
222312
223 const run = addRunArtifact(exe);313 const run = addRunArtifact(exe);
224 run.expectStdOutEqual("5 0 7 2\n");314 run.expectStdOutEqual("5 0 7 2\n");
...@@ -245,7 +335,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {...@@ -245,7 +335,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {
245 \\ real_hello();335 \\ real_hello();
246 \\}336 \\}
247 , &.{"-fPIC"});337 , &.{"-fPIC"});
248 dso.is_linking_libc = true;338 dso.linkLibC();
249339
250 const exe = addExecutable(b, "test", opts);340 const exe = addExecutable(b, "test", opts);
251 addCSourceBytes(exe,341 addCSourceBytes(exe,
...@@ -259,7 +349,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {...@@ -259,7 +349,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {
259 \\}349 \\}
260 , &.{});350 , &.{});
261 exe.linkLibrary(dso);351 exe.linkLibrary(dso);
262 exe.is_linking_libc = true;352 exe.linkLibC();
263353
264 const run = addRunArtifact(exe);354 const run = addRunArtifact(exe);
265 run.expectStdOutEqual("Hello WORLD\n");355 run.expectStdOutEqual("Hello WORLD\n");
...@@ -277,7 +367,7 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {...@@ -277,7 +367,7 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {
277 \\int bar = 5;367 \\int bar = 5;
278 \\int baz() { return foo; }368 \\int baz() { return foo; }
279 , &.{"-fPIC"});369 , &.{"-fPIC"});
280 dso.is_linking_libc = true;370 dso.linkLibC();
281371
282 const obj = addObject(b, "obj", opts);372 const obj = addObject(b, "obj", opts);
283 addCSourceBytes(obj, "int foo = 3;", &.{});373 addCSourceBytes(obj, "int foo = 3;", &.{});
...@@ -294,7 +384,7 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {...@@ -294,7 +384,7 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {
294 \\ return bar - 5;384 \\ return bar - 5;
295 \\}385 \\}
296 , &.{});386 , &.{});
297 exe.is_linking_libc = true;387 exe.linkLibC();
298388
299 const run = addRunArtifact(exe);389 const run = addRunArtifact(exe);
300 run.expectExitCode(0);390 run.expectExitCode(0);
...@@ -314,7 +404,7 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {...@@ -314,7 +404,7 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {
314 const exe = addExecutable(b, "test", opts);404 const exe = addExecutable(b, "test", opts);
315 addCSourceBytes(exe, "int main() { return 0; }", &.{});405 addCSourceBytes(exe, "int main() { return 0; }", &.{});
316 addCSourceBytes(exe, "", &.{});406 addCSourceBytes(exe, "", &.{});
317 exe.is_linking_libc = true;407 exe.linkLibC();
318408
319 const run = addRunArtifact(exe);409 const run = addRunArtifact(exe);
320 run.expectExitCode(0);410 run.expectExitCode(0);
...@@ -345,15 +435,15 @@ fn testGcSections(b: *Build, opts: Options) *Step {...@@ -345,15 +435,15 @@ fn testGcSections(b: *Build, opts: Options) *Step {
345 , &.{});435 , &.{});
346 obj.link_function_sections = true;436 obj.link_function_sections = true;
347 obj.link_data_sections = true;437 obj.link_data_sections = true;
348 obj.is_linking_libc = true;438 obj.linkLibC();
349 obj.is_linking_libcpp = true;439 obj.linkLibCpp();
350440
351 {441 {
352 const exe = addExecutable(b, "test", opts);442 const exe = addExecutable(b, "test", opts);
353 exe.addObject(obj);443 exe.addObject(obj);
354 exe.link_gc_sections = false;444 exe.link_gc_sections = false;
355 exe.is_linking_libc = true;445 exe.linkLibC();
356 exe.is_linking_libcpp = true;446 exe.linkLibCpp();
357447
358 const run = addRunArtifact(exe);448 const run = addRunArtifact(exe);
359 run.expectStdOutEqual("1 2\n");449 run.expectStdOutEqual("1 2\n");
...@@ -383,8 +473,8 @@ fn testGcSections(b: *Build, opts: Options) *Step {...@@ -383,8 +473,8 @@ fn testGcSections(b: *Build, opts: Options) *Step {
383 const exe = addExecutable(b, "test", opts);473 const exe = addExecutable(b, "test", opts);
384 exe.addObject(obj);474 exe.addObject(obj);
385 exe.link_gc_sections = true;475 exe.link_gc_sections = true;
386 exe.is_linking_libc = true;476 exe.linkLibC();
387 exe.is_linking_libcpp = true;477 exe.linkLibCpp();
388478
389 const run = addRunArtifact(exe);479 const run = addRunArtifact(exe);
390 run.expectStdOutEqual("1 2\n");480 run.expectStdOutEqual("1 2\n");
...@@ -434,7 +524,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {...@@ -434,7 +524,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
434 \\}524 \\}
435 , &.{"-fPIC"});525 , &.{"-fPIC"});
436 dso.link_function_sections = true;526 dso.link_function_sections = true;
437 dso.is_linking_libc = true;527 dso.linkLibC();
438528
439 const check = dso.checkObject();529 const check = dso.checkObject();
440 check.checkInSymtab();530 check.checkInSymtab();
...@@ -451,7 +541,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {...@@ -451,7 +541,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
451 \\int main() { greet(); }541 \\int main() { greet(); }
452 , &.{});542 , &.{});
453 exe.linkLibrary(dso);543 exe.linkLibrary(dso);
454 exe.is_linking_libc = true;544 exe.linkLibC();
455545
456 const run = addRunArtifact(exe);546 const run = addRunArtifact(exe);
457 run.expectStdOutEqual("Hello world");547 run.expectStdOutEqual("Hello world");
...@@ -485,7 +575,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {...@@ -485,7 +575,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {
485 \\}575 \\}
486 , &.{});576 , &.{});
487 exe.link_function_sections = true;577 exe.link_function_sections = true;
488 exe.is_linking_libc = true;578 exe.linkLibC();
489579
490 const run = addRunArtifact(exe);580 const run = addRunArtifact(exe);
491 run.expectStdOutEqual("Hello world");581 run.expectStdOutEqual("Hello world");
...@@ -514,7 +604,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step {...@@ -514,7 +604,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step {
514 \\ return 0;604 \\ return 0;
515 \\}605 \\}
516 , &.{});606 , &.{});
517 exe.is_linking_libc = true;607 exe.linkLibC();
518608
519 const run = addRunArtifact(exe);609 const run = addRunArtifact(exe);
520 run.expectStdOutEqual("Hello World!\n");610 run.expectStdOutEqual("Hello World!\n");
...@@ -543,8 +633,8 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step {...@@ -543,8 +633,8 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step {
543 \\ return 0;633 \\ return 0;
544 \\}634 \\}
545 , &.{});635 , &.{});
546 exe.is_linking_libc = true;636 exe.linkLibC();
547 exe.is_linking_libcpp = true;637 exe.linkLibCpp();
548638
549 const run = addRunArtifact(exe);639 const run = addRunArtifact(exe);
550 run.expectStdOutEqual("Hello World!\n");640 run.expectStdOutEqual("Hello World!\n");
...@@ -606,7 +696,7 @@ fn testTlsStatic(b: *Build, opts: Options) *Step {...@@ -606,7 +696,7 @@ fn testTlsStatic(b: *Build, opts: Options) *Step {
606 \\ return 0;696 \\ return 0;
607 \\}697 \\}
608 , &.{});698 , &.{});
609 exe.is_linking_libc = true;699 exe.linkLibC();
610700
611 const run = addRunArtifact(exe);701 const run = addRunArtifact(exe);
612 run.expectStdOutEqual(702 run.expectStdOutEqual(