elf: port more linker tests

This commit is contained in:
Jakub Konka
2023-10-09 15:40:38 +02:00
parent 9487007ffe
commit 1fe0fd69e0

View File

@@ -21,6 +21,7 @@ pub fn build(b: *Build) void {
// elf_step.dependOn(testLinkingZig(b, .{ .use_llvm = false }));
// Exercise linker with LLVM backend
// musl tests
elf_step.dependOn(testAbsSymbols(b, .{ .target = musl_target }));
elf_step.dependOn(testCommonSymbols(b, .{ .target = musl_target }));
elf_step.dependOn(testCommonSymbolsInArchive(b, .{ .target = musl_target }));
@@ -29,11 +30,17 @@ pub fn build(b: *Build) void {
elf_step.dependOn(testGcSections(b, .{ .target = musl_target }));
elf_step.dependOn(testImageBase(b, .{ .target = musl_target }));
elf_step.dependOn(testInitArrayOrder(b, .{ .target = musl_target }));
elf_step.dependOn(testLargeAlignmentExe(b, .{ .target = musl_target }));
// https://github.com/ziglang/zig/issues/17449
// elf_step.dependOn(testLargeBss(b, .{ .target = musl_target }));
elf_step.dependOn(testLinkingC(b, .{ .target = musl_target }));
elf_step.dependOn(testLinkingCpp(b, .{ .target = musl_target }));
elf_step.dependOn(testLinkingZig(b, .{ .target = musl_target }));
// https://github.com/ziglang/zig/issues/17451
// elf_step.dependOn(testNoEhFrameHdr(b, .{ .target = musl_target }));
elf_step.dependOn(testTlsStatic(b, .{ .target = musl_target }));
// glibc tests
elf_step.dependOn(testAsNeeded(b, .{ .target = glibc_target }));
// https://github.com/ziglang/zig/issues/17430
// elf_step.dependOn(testCanonicalPlt(b, .{ .target = glibc_target }));
@@ -63,7 +70,13 @@ pub fn build(b: *Build) void {
elf_step.dependOn(testInitArrayOrder(b, .{ .target = glibc_target }));
elf_step.dependOn(testLargeAlignmentDso(b, .{ .target = glibc_target }));
elf_step.dependOn(testLargeAlignmentExe(b, .{ .target = glibc_target }));
elf_step.dependOn(testLargeBss(b, .{ .target = glibc_target }));
elf_step.dependOn(testLinkOrder(b, .{ .target = glibc_target }));
// https://github.com/ziglang/zig/issues/17451
// elf_step.dependOn(testNoEhFrameHdr(b, .{ .target = glibc_target }));
elf_step.dependOn(testPie(b, .{ .target = glibc_target }));
elf_step.dependOn(testPltGot(b, .{ .target = glibc_target }));
elf_step.dependOn(testPreinitArray(b, .{ .target = glibc_target }));
}
fn testAbsSymbols(b: *Build, opts: Options) *Step {
@@ -1353,6 +1366,85 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {
return test_step;
}
fn testLargeBss(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "large-bss", opts);
const exe = addExecutable(b, "main", opts);
addCSourceBytes(exe,
\\char arr[0x100000000];
\\int main() {
\\ return arr[2000];
\\}
, &.{});
exe.linkLibC();
const run = addRunArtifact(exe);
test_step.dependOn(&run.step);
return test_step;
}
fn testLinkOrder(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "link-order", opts);
const obj = addObject(b, "obj", opts);
addCSourceBytes(obj, "void foo() {}", &.{});
obj.force_pic = true;
const dso = addSharedLibrary(b, "a", opts);
dso.addObject(obj);
const lib = addStaticLibrary(b, "b", opts);
lib.addObject(obj);
const main_o = addObject(b, "main", opts);
addCSourceBytes(main_o,
\\void foo();
\\int main() {
\\ foo();
\\}
, &.{});
// https://github.com/ziglang/zig/issues/17450
// {
// const exe = addExecutable(b, "main1", opts);
// exe.addObject(main_o);
// exe.linkSystemLibrary2("a", .{});
// exe.addLibraryPath(dso.getEmittedBinDirectory());
// exe.addRPath(dso.getEmittedBinDirectory());
// exe.linkSystemLibrary2("b", .{});
// exe.addLibraryPath(lib.getEmittedBinDirectory());
// exe.addRPath(lib.getEmittedBinDirectory());
// exe.linkLibC();
// exe.verbose_link = true;
// const check = exe.checkObject();
// check.checkInDynamicSection();
// check.checkContains("libb.so");
// test_step.dependOn(&check.step);
// }
{
const exe = addExecutable(b, "main2", opts);
exe.addObject(main_o);
exe.linkSystemLibrary2("b", .{});
exe.addLibraryPath(lib.getEmittedBinDirectory());
exe.addRPath(lib.getEmittedBinDirectory());
exe.linkSystemLibrary2("a", .{});
exe.addLibraryPath(dso.getEmittedBinDirectory());
exe.addRPath(dso.getEmittedBinDirectory());
exe.linkLibC();
exe.verbose_link = true;
const check = exe.checkObject();
check.checkInDynamicSection();
check.checkNotPresent("libb.so");
test_step.dependOn(&check.step);
}
return test_step;
}
fn testLinkingC(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "linking-c", opts);
@@ -1438,6 +1530,23 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {
return test_step;
}
fn testNoEhFrameHdr(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "no-eh-frame-hdr", opts);
const exe = addExecutable(b, "main", opts);
addCSourceBytes(exe, "int main() { return 0; }", &.{});
exe.link_eh_frame_hdr = false;
exe.linkLibC();
const check = exe.checkObject();
check.checkStart();
check.checkExact("section headers");
check.checkNotPresent("name .eh_frame_hdr");
test_step.dependOn(&check.step);
return test_step;
}
fn testPie(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "hello-pie", opts);
@@ -1469,6 +1578,70 @@ fn testPie(b: *Build, opts: Options) *Step {
return test_step;
}
fn testPltGot(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "plt-got", opts);
const dso = addSharedLibrary(b, "a", opts);
addCSourceBytes(dso,
\\#include <stdio.h>
\\void ignore(void *foo) {}
\\void hello() {
\\ printf("Hello world\n");
\\}
, &.{});
dso.linkLibC();
const exe = addExecutable(b, "main", opts);
addCSourceBytes(exe,
\\void ignore(void *);
\\int hello();
\\void foo() { ignore(hello); }
\\int main() { hello(); }
, &.{});
exe.linkLibrary(dso);
exe.force_pic = true;
exe.linkLibC();
const run = addRunArtifact(exe);
run.expectStdOutEqual("Hello world\n");
test_step.dependOn(&run.step);
return test_step;
}
fn testPreinitArray(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "preinit-array", opts);
{
const obj = addObject(b, "obj", opts);
addCSourceBytes(obj, "void _start() {}", &.{});
const exe = addExecutable(b, "main1", opts);
exe.addObject(obj);
const check = exe.checkObject();
check.checkInDynamicSection();
check.checkNotPresent("PREINIT_ARRAY");
}
{
const exe = addExecutable(b, "main2", opts);
addCSourceBytes(exe,
\\void preinit_fn() {}
\\int main() {}
\\__attribute__((section(".preinit_array")))
\\void *preinit[] = { preinit_fn };
, &.{});
exe.linkLibC();
const check = exe.checkObject();
check.checkInDynamicSection();
check.checkContains("PREINIT_ARRAY");
}
return test_step;
}
fn testTlsStatic(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "tls-static", opts);