Skip to content

Commit

Permalink
elf: test ifunc with dlopened dsos
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Jul 20, 2023
1 parent c9a74f6 commit 2088f77
Showing 1 changed file with 142 additions and 98 deletions.
240 changes: 142 additions & 98 deletions test/elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ pub fn addElfTests(b: *Build, opts: Options) *Step {
elf_step.dependOn(testExportSymbolsFromExe(b, opts));
elf_step.dependOn(testFuncAddress(b, opts));
elf_step.dependOn(testGcSections(b, opts));
elf_step.dependOn(testHelloDynamic(b, opts));
elf_step.dependOn(testHelloPie(b, opts));
elf_step.dependOn(testHelloStatic(b, opts));
elf_step.dependOn(testHiddenWeakUndef(b, opts));
elf_step.dependOn(testIfuncAlias(b, opts));
elf_step.dependOn(testIfuncDlopen(b, opts));
elf_step.dependOn(testIfuncDynamic(b, opts));
elf_step.dependOn(testIfuncFuncPtr(b, opts));
elf_step.dependOn(testIfuncNoPlt(b, opts));
elf_step.dependOn(testIfuncStatic(b, opts));
elf_step.dependOn(testIfuncStaticPie(b, opts));
elf_step.dependOn(testHelloDynamic(b, opts));
elf_step.dependOn(testHelloPie(b, opts));
elf_step.dependOn(testHelloStatic(b, opts));
elf_step.dependOn(testHiddenWeakUndef(b, opts));
elf_step.dependOn(testTlsDesc(b, opts));
elf_step.dependOn(testTlsDescImport(b, opts));
elf_step.dependOn(testTlsDescStatic(b, opts));
Expand Down Expand Up @@ -945,6 +946,100 @@ fn testGcSections(b: *Build, opts: Options) *Step {
return test_step;
}

fn testHelloDynamic(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hello-dynamic", "");

const exe = cc(b, opts);
exe.addHelloWorldMain();
exe.addArg("-no-pie");

const run = exe.run();
run.expectHelloWorld();
test_step.dependOn(run.step());

const check = exe.check();
check.checkStart();
check.checkExact("header");
check.checkExact("type EXEC");
check.checkStart();
check.checkExact("section headers");
check.checkExact("name .dynamic");
test_step.dependOn(&check.step);

return test_step;
}

fn testHelloPie(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hello-pie", "");

const exe = cc(b, opts);
exe.addHelloWorldMain();
exe.addArgs(&.{ "-fPIC", "-pie" });

const run = exe.run();
run.expectHelloWorld();
test_step.dependOn(run.step());

const check = exe.check();
check.checkStart();
check.checkExact("header");
check.checkExact("type DYN");
check.checkStart();
check.checkExact("section headers");
check.checkExact("name .dynamic");
test_step.dependOn(&check.step);

return test_step;
}

fn testHelloStatic(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hello-static", "");

if (!opts.has_static) {
skipTestStep(test_step);
return test_step;
}

const exe = cc(b, opts);
exe.addHelloWorldMain();
exe.addArg("-static");

const run = exe.run();
run.expectHelloWorld();
test_step.dependOn(run.step());

const check = exe.check();
check.checkStart();
check.checkExact("header");
check.checkExact("type EXEC");
check.checkStart();
check.checkExact("section headers");
check.checkNotPresent("name .dynamic");
test_step.dependOn(&check.step);

return test_step;
}

fn testHiddenWeakUndef(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hidden-weak-undef", "");

const dso = cc(b, opts);
dso.addCSource(
\\__attribute__((weak, visibility("hidden"))) void foo();
\\void bar() { foo(); }
);
dso.addArgs(&.{ "-fPIC", "-shared" });

const check = dso.check();
check.checkInDynamicSymtab();
check.checkNotPresent("foo");
check.checkInDynamicSymtab();
check.checkContains("bar");
test_step.dependOn(&check.step);

return test_step;
}

fn testIfuncAlias(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-ifunc-alias", "");

Expand All @@ -967,6 +1062,49 @@ fn testIfuncAlias(b: *Build, opts: Options) *Step {
return test_step;
}

fn testIfuncDlopen(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-ifunc-dlopen", "");

const dso = cc(b, opts);
dso.addCSource(
\\__attribute__((ifunc("resolve_foo")))
\\void foo(void);
\\static void real_foo(void) {
\\}
\\typedef void Func();
\\static Func *resolve_foo(void) {
\\ return real_foo;
\\}
);
dso.addArgs(&.{ "-fPIC", "-shared" });
const dso_out = dso.saveOutputAs("a.so");

const exe = cc(b, opts);
exe.addCSource(
\\#include <dlfcn.h>
\\#include <assert.h>
\\#include <stdlib.h>
\\typedef void Func();
\\void foo(void);
\\int main() {
\\ void *handle = dlopen(NULL, RTLD_NOW);
\\ Func *p = dlsym(handle, "foo");
\\
\\ foo();
\\ p();
\\ assert(foo == p);
\\}
);
exe.addFileSource(dso_out.file);
exe.addPrefixedDirectorySource("-Wl,-rpath,", dso_out.dir);
exe.addArgs(&.{ "-fno-PIE", "-no-pie", "-ldl" });

const run = exe.run();
test_step.dependOn(run.step());

return test_step;
}

fn testIfuncDynamic(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-ifunc-dynamic", "");

Expand Down Expand Up @@ -1147,100 +1285,6 @@ fn testIfuncStaticPie(b: *Build, opts: Options) *Step {
return test_step;
}

fn testHelloStatic(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hello-static", "");

if (!opts.has_static) {
skipTestStep(test_step);
return test_step;
}

const exe = cc(b, opts);
exe.addHelloWorldMain();
exe.addArg("-static");

const run = exe.run();
run.expectHelloWorld();
test_step.dependOn(run.step());

const check = exe.check();
check.checkStart();
check.checkExact("header");
check.checkExact("type EXEC");
check.checkStart();
check.checkExact("section headers");
check.checkNotPresent("name .dynamic");
test_step.dependOn(&check.step);

return test_step;
}

fn testHelloDynamic(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hello-dynamic", "");

const exe = cc(b, opts);
exe.addHelloWorldMain();
exe.addArg("-no-pie");

const run = exe.run();
run.expectHelloWorld();
test_step.dependOn(run.step());

const check = exe.check();
check.checkStart();
check.checkExact("header");
check.checkExact("type EXEC");
check.checkStart();
check.checkExact("section headers");
check.checkExact("name .dynamic");
test_step.dependOn(&check.step);

return test_step;
}

fn testHelloPie(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hello-pie", "");

const exe = cc(b, opts);
exe.addHelloWorldMain();
exe.addArgs(&.{ "-fPIC", "-pie" });

const run = exe.run();
run.expectHelloWorld();
test_step.dependOn(run.step());

const check = exe.check();
check.checkStart();
check.checkExact("header");
check.checkExact("type DYN");
check.checkStart();
check.checkExact("section headers");
check.checkExact("name .dynamic");
test_step.dependOn(&check.step);

return test_step;
}

fn testHiddenWeakUndef(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-hidden-weak-undef", "");

const dso = cc(b, opts);
dso.addCSource(
\\__attribute__((weak, visibility("hidden"))) void foo();
\\void bar() { foo(); }
);
dso.addArgs(&.{ "-fPIC", "-shared" });

const check = dso.check();
check.checkInDynamicSymtab();
check.checkNotPresent("foo");
check.checkInDynamicSymtab();
check.checkContains("bar");
test_step.dependOn(&check.step);

return test_step;
}

fn testTlsDesc(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-tls-desc", "");

Expand Down

0 comments on commit 2088f77

Please sign in to comment.