From 67ef7f5678fff0af426b21de4ef3822bbbedee62 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 8 Nov 2008 02:04:53 +0000 Subject: [PATCH] Added a small test suite for the runtime loader. The tests are designed to succeed on Linux. FreeBSD fails some tests since it seems to have a different load order (depth-first instead of breadth-first). Haiku fails a lot of tests due to its POSIX non-compliant dlopen(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28556 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../test_suite/dlopen_lookup_order1 | 90 ++++++++++++++ .../test_suite/dlopen_lookup_order2 | 90 ++++++++++++++ .../test_suite/dlopen_lookup_order3 | 85 +++++++++++++ .../test_suite/dlopen_lookup_order4 | 90 ++++++++++++++ .../test_suite/dlopen_resolve_basic1 | 60 ++++++++++ .../test_suite/dlopen_resolve_basic2 | 67 +++++++++++ .../test_suite/dlopen_resolve_basic3 | 77 ++++++++++++ .../test_suite/dlopen_resolve_order1 | 77 ++++++++++++ .../test_suite/dlopen_resolve_order2 | 87 ++++++++++++++ .../test_suite/dlopen_resolve_order3 | 83 +++++++++++++ .../test_suite/dlopen_resolve_order4 | 94 +++++++++++++++ .../test_suite/dlopen_resolve_order5 | 104 ++++++++++++++++ .../test_suite/dlopen_resolve_order6 | 112 ++++++++++++++++++ .../test_suite/dlopen_resolve_order7 | 83 +++++++++++++ .../test_suite/load_resolve_basic1 | 44 +++++++ .../test_suite/load_resolve_order1 | 57 +++++++++ .../test_suite/load_resolve_order2 | 57 +++++++++ .../test_suite/load_resolve_order3 | 58 +++++++++ .../test_suite/load_resolve_order4 | 52 ++++++++ .../runtime_loader/test_suite/test_setup | 32 +++++ .../runtime_loader/test_suite/test_suite | 31 +++++ 21 files changed, 1530 insertions(+) create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_lookup_order1 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_lookup_order2 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_lookup_order3 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_lookup_order4 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic1 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic2 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic3 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_order1 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_order2 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_order3 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_order4 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_order5 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_order6 create mode 100755 src/tests/system/runtime_loader/test_suite/dlopen_resolve_order7 create mode 100755 src/tests/system/runtime_loader/test_suite/load_resolve_basic1 create mode 100755 src/tests/system/runtime_loader/test_suite/load_resolve_order1 create mode 100755 src/tests/system/runtime_loader/test_suite/load_resolve_order2 create mode 100755 src/tests/system/runtime_loader/test_suite/load_resolve_order3 create mode 100755 src/tests/system/runtime_loader/test_suite/load_resolve_order4 create mode 100644 src/tests/system/runtime_loader/test_suite/test_setup create mode 100755 src/tests/system/runtime_loader/test_suite/test_suite diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order1 b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order1 new file mode 100755 index 0000000000..d506ac59c0 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order1 @@ -0,0 +1,90 @@ +#!/bin/sh + +# program +# +# dlopen(): +# liba.so +# libb.so +# <- libb_dependency.so +# +# Expected: Global lookup: symbol in liba.so superseeds symbol in +# libb_dependency.so. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +int a() { return 1; } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libb; + void* self; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + libb = dlopen("./libb.so", RTLD_NOW | RTLD_GLOBAL); + if (libb == NULL) { + fprintf(stderr, "Error opening libb.so: %s\n", dlerror()); + exit(117); + } + + self = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + if (self == NULL) { + fprintf(stderr, "Error opening self: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(self, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order2 b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order2 new file mode 100755 index 0000000000..ae801422b7 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order2 @@ -0,0 +1,90 @@ +#!/bin/sh + +# program +# +# dlopen(): +# libb.so +# <- libb_dependency.so +# liba.so +# +# Expected: Global lookup: Symbol in libb_dependency.so superseeds symbol in +# liba.so. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +int a() { return 1; } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libb; + void* self; + int (*a)(); + + libb = dlopen("./libb.so", RTLD_NOW | RTLD_GLOBAL); + if (libb == NULL) { + fprintf(stderr, "Error opening libb.so: %s\n", dlerror()); + exit(117); + } + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + self = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + if (self == NULL) { + fprintf(stderr, "Error opening self: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(self, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 2 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order3 b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order3 new file mode 100755 index 0000000000..359ccf9e70 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order3 @@ -0,0 +1,85 @@ +#!/bin/sh + +# program +# +# dlopen(): +# liba.so +# <- libb.so +# <- libb_dependency.so +# <- libd.so +# +# Expected: liba.so lookup: Symbol in libd.so superseeds symbol in +# libb_dependency.so. + + +. test_setup + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 1; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create liba.so +cat > libd.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libd.so libd.c + + +# create liba.so +cat > liba.c << EOI +int c() { return 1; } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so ./libd.so + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 2 diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order4 b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order4 new file mode 100755 index 0000000000..3427f54270 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_lookup_order4 @@ -0,0 +1,90 @@ +#!/bin/sh + +# program +# +# dlopen(): +# libb.so (local) +# <- libb_dependency.so +# liba.so +# +# Expected: Global lookup: Symbol in libb_dependency.so does not superseeds +# symbol in liba.so, since libb.so is loaded RTLD_LOCAL. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +int a() { return 1; } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libb; + void* self; + int (*a)(); + + libb = dlopen("./libb.so", RTLD_NOW | RTLD_LOCAL); + if (libb == NULL) { + fprintf(stderr, "Error opening libb.so: %s\n", dlerror()); + exit(117); + } + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + self = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + if (self == NULL) { + fprintf(stderr, "Error opening self: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(self, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic1 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic1 new file mode 100755 index 0000000000..9abb56491b --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic1 @@ -0,0 +1,60 @@ +#!/bin/sh + +# program +# +# dlopen(): +# liba.so +# +# Expected: Undefined symbol in liba.so might resolve to symbol in program, but +# the program image is ignored, so dlopen() on liba.so fails. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +extern int b(); +int a() { return b(); } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create program +cat > program.c << EOI +#include +#include +#include + +int b() { return 1; } + +int +main() +{ + void* liba; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + /* Fails expectedly. */ + /* fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); */ + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 117 diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic2 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic2 new file mode 100755 index 0000000000..b7a6ffa49c --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic2 @@ -0,0 +1,67 @@ +#!/bin/sh + +# program +# <- libb.so +# +# dlopen(): +# liba.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in libb.so. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +extern int b(); +int a() { return b(); } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c + + +# create program +cat > program.c << EOI +#include +#include +#include + +int +main() +{ + void* liba; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c ./libb.so $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic3 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic3 new file mode 100755 index 0000000000..6898ee9f53 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_basic3 @@ -0,0 +1,77 @@ +#!/bin/sh + +# program +# +# dlopen(): +# liba.so +# <- libb.so +# <- libb_dependency.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in +# libb_dependency.so. + + +. test_setup + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int c() { return 1; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create liba.so +cat > liba.c << EOI +extern int c(); +int a() { return c(); } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order1 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order1 new file mode 100755 index 0000000000..b2801234d0 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order1 @@ -0,0 +1,77 @@ +#!/bin/sh + +# program +# +# dlopen(): +# libb.so +# liba.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in libb.so, not +# to symbol in program, since program image is ignored. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +extern int b(); +int a() { return b(); } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 2; } +EOI + +# build +gcc -shared -o libb.so libb.c + + +# create program +cat > program.c << EOI +#include +#include +#include + +int b() { return 1; } + +int +main() +{ + void* liba; + void* libb; + int (*a)(); + + libb = dlopen("./libb.so", RTLD_NOW | RTLD_GLOBAL); + if (libb == NULL) { + fprintf(stderr, "Error opening libb.so: %s\n", dlerror()); + exit(117); + } + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 2 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order2 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order2 new file mode 100755 index 0000000000..88c444982a --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order2 @@ -0,0 +1,87 @@ +#!/bin/sh + +# program +# +# dlopen(): +# liba.so +# <- libb.so +# <- libb_dependency.so +# <- libd.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in +# libd.so, not to symbol in libb_dependency.so. + + +. test_setup + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int c() { return 1; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create libd.so +cat > libd.c << EOI +int c() { return 2; } +EOI + +# build +gcc -shared -o libd.so libd.c + + +# create liba.so +cat > liba.c << EOI +extern int c(); +int a() { return c(); } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so ./libd.so + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 2 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order3 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order3 new file mode 100755 index 0000000000..8a6d0779ed --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order3 @@ -0,0 +1,83 @@ +#!/bin/sh + +# program +# +# dlopen(): +# libd.so +# liba.so +# <- libb.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in libd.so, +# not to symbol in libb.so. + + +. test_setup + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c + + +# create liba.so +cat > liba.c << EOI +extern int b(); +int a() { return b(); } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so + + +# create libd.so +cat > libd.c << EOI +int b() { return 2; } +EOI + +# build +gcc -shared -o libd.so libd.c + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libd; + int (*a)(); + + libd = dlopen("./libd.so", RTLD_NOW | RTLD_GLOBAL); + if (libd == NULL) { + fprintf(stderr, "Error opening libd.so: %s\n", dlerror()); + exit(117); + } + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 2 diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order4 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order4 new file mode 100755 index 0000000000..e5c02395e9 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order4 @@ -0,0 +1,94 @@ +#!/bin/sh + +# program +# +# dlopen(): +# libd.so +# liba.so +# <- libb.so +# <- libb_dependency.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in libd.so, +# not to symbol in libb_dependency.so. + + +. test_setup + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int c() { return 1; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create liba.so +cat > liba.c << EOI +extern int c(); +int a() { return c(); } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so + + +# create libd.so +cat > libd.c << EOI +int c() { return 2; } +EOI + +# build +gcc -shared -o libd.so libd.c + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libd; + int (*a)(); + + libd = dlopen("./libd.so", RTLD_NOW | RTLD_GLOBAL); + if (libd == NULL) { + fprintf(stderr, "Error opening libd.so: %s\n", dlerror()); + exit(117); + } + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 2 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order5 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order5 new file mode 100755 index 0000000000..02b5107fd6 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order5 @@ -0,0 +1,104 @@ +#!/bin/sh + +# program +# +# dlopen(): +# liba.so +# <- libb.so +# <- libb_dependency.so +# <- libd.so +# libe.so +# +# Expected: Undefined symbol in libe.so resolves to symbol in +# libd.so, not to symbol in libb_dependency.so. + + +. test_setup + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int c() { return 1; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create libd.so +cat > libd.c << EOI +int c() { return 2; } +EOI + +# build +gcc -shared -o libd.so libd.c + + +# create liba.so +cat > liba.c << EOI +int e() { return 0; } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so ./libd.so + + +# create libe.so +cat > libe.c << EOI +extern int c(); +int a() { return c(); } +EOI + +# build +gcc -shared -o libe.so libe.c + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libe; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + libe = dlopen("./libe.so", RTLD_NOW | RTLD_GLOBAL); + if (libe == NULL) { + fprintf(stderr, "Error opening libe.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(libe, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 2 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order6 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order6 new file mode 100755 index 0000000000..c7b57a4170 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order6 @@ -0,0 +1,112 @@ +#!/bin/sh + +# program +# +# dlopen(): +# liba.so +# <- libb.so +# <- libb_dependency.so +# libd.so +# libe.so +# +# Expected: Undefined symbol in libe.so resolves to symbol in +# libb_dependency.so, not to symbol in libd.so. + + +. test_setup + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int c() { return 1; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create libd.so +cat > libd.c << EOI +int c() { return 2; } +EOI + +# build +gcc -shared -o libd.so libd.c + + +# create liba.so +cat > liba.c << EOI +extern int c(); +int e() { return 0; } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so + + +# create libe.so +cat > libe.c << EOI +extern int c(); +int a() { return c(); } +EOI + +# build +gcc -shared -o libe.so libe.c + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libd; + void* libe; + int (*a)(); + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + libd = dlopen("./libd.so", RTLD_NOW | RTLD_GLOBAL); + if (libd == NULL) { + fprintf(stderr, "Error opening libd.so: %s\n", dlerror()); + exit(117); + } + + libe = dlopen("./libe.so", RTLD_NOW | RTLD_GLOBAL); + if (libe == NULL) { + fprintf(stderr, "Error opening libe.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(libe, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order7 b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order7 new file mode 100755 index 0000000000..adac3e6f96 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/dlopen_resolve_order7 @@ -0,0 +1,83 @@ +#!/bin/sh + +# program +# +# dlopen(): +# libd.so (local) +# liba.so +# <- libb.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in libb.so, +# not to symbol in libd.so, since it's loaded RTLD_LOCAL. + + +. test_setup + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c + + +# create liba.so +cat > liba.c << EOI +extern int b(); +int a() { return b(); } +EOI + +# build +gcc -shared -o liba.so liba.c ./libb.so + + +# create libd.so +cat > libd.c << EOI +int b() { return 2; } +EOI + +# build +gcc -shared -o libd.so libd.c + + +# create program +cat > program.c << EOI +#include +#include +#include +int +main() +{ + void* liba; + void* libd; + int (*a)(); + + libd = dlopen("./libd.so", RTLD_NOW | RTLD_LOCAL); + if (libd == NULL) { + fprintf(stderr, "Error opening libd.so: %s\n", dlerror()); + exit(117); + } + + liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL); + if (liba == NULL) { + fprintf(stderr, "Error opening liba.so: %s\n", dlerror()); + exit(117); + } + + a = (int (*)())dlsym(liba, "a"); + if (a == NULL) { + fprintf(stderr, "Error getting symbol a: %s\n", dlerror()); + exit(116); + } + + return a(); +} +EOI + +# build +gcc -o program program.c $libdl -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 diff --git a/src/tests/system/runtime_loader/test_suite/load_resolve_basic1 b/src/tests/system/runtime_loader/test_suite/load_resolve_basic1 new file mode 100755 index 0000000000..fce8f9c663 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/load_resolve_basic1 @@ -0,0 +1,44 @@ +#!/bin/sh + +# program +# <- liba.so +# +# Expected: Undefined symbol in liba.so resolves to symbol in program. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +extern int b(); +int a() { return b(); } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create program +cat > program.c << EOI +extern int a(); + +int +b() +{ + return 1; +} + +int +main() +{ + return a(); +} +EOI + +# build +gcc -o program program.c ./liba.so + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/load_resolve_order1 b/src/tests/system/runtime_loader/test_suite/load_resolve_order1 new file mode 100755 index 0000000000..83bce0e92a --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/load_resolve_order1 @@ -0,0 +1,57 @@ +#!/bin/sh + +# program +# <- liba.so +# <- libb.so +# <- libb_dependency.so +# +# Expected: Undefined symbol in program resolves to symbol in liba.so, +# not to symbol in libb_dependency.so. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +int a() { return 1; } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create program +cat > program.c << EOI +extern int a(); +int +main() +{ + return a(); +} +EOI + +# build +gcc -o program program.c ./liba.so ./libb.so -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/load_resolve_order2 b/src/tests/system/runtime_loader/test_suite/load_resolve_order2 new file mode 100755 index 0000000000..cc43400a81 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/load_resolve_order2 @@ -0,0 +1,57 @@ +#!/bin/sh + +# program +# <- libb.so +# <- libb_dependency.so +# <- liba.so +# +# Expected: Undefined symbol in program resolves to symbol in liba.so, +# not to symbol in libb_dependency.so. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +int a() { return 1; } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +int b() { return 1; } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create program +cat > program.c << EOI +extern int a(); +int +main() +{ + return a(); +} +EOI + +# build +gcc -o program program.c ./libb.so ./liba.so -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/load_resolve_order3 b/src/tests/system/runtime_loader/test_suite/load_resolve_order3 new file mode 100755 index 0000000000..18d73cb345 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/load_resolve_order3 @@ -0,0 +1,58 @@ +#!/bin/sh + +# program +# <- liba.so +# <- libb.so +# <- libb_dependency.so +# +# Expected: Undefined symbol in libb.so resolves to symbol in liba.so, +# not to symbol in libb_dependency.so. + + +. test_setup + + +# create liba.so +cat > liba.c << EOI +int a() { return 1; } +EOI + +# build +gcc -shared -o liba.so liba.c + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +extern int a(); +int b() { return a(); } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create program +cat > program.c << EOI +extern int b(); +int +main() +{ + return b(); +} +EOI + +# build +gcc -o program program.c ./liba.so ./libb.so -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/load_resolve_order4 b/src/tests/system/runtime_loader/test_suite/load_resolve_order4 new file mode 100755 index 0000000000..41e5ace78b --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/load_resolve_order4 @@ -0,0 +1,52 @@ +#!/bin/sh + +# program +# <- libb.so +# <- libb_dependency.so +# +# Expected: Undefined symbol in libb.so resolves to symbol in program, +# not to symbol in libb_dependency.so. + + +. test_setup + + +# create libb_dependency.so +cat > libb_dependency.c << EOI +int a() { return 2; } +EOI + +# build +gcc -shared -o libb_dependency.so libb_dependency.c + + +# create libb.so +cat > libb.c << EOI +extern int a(); +int b() { return a(); } +EOI + +# build +gcc -shared -o libb.so libb.c ./libb_dependency.so + + +# create program +cat > program.c << EOI + +extern int b(); + +int a() { return 1; } + +int +main() +{ + return b(); +} +EOI + +# build +gcc -o program program.c ./libb.so -Xlinker -rpath -Xlinker . + +# run +test_run_ok ./program 1 + diff --git a/src/tests/system/runtime_loader/test_suite/test_setup b/src/tests/system/runtime_loader/test_suite/test_setup new file mode 100644 index 0000000000..ad1597589b --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/test_setup @@ -0,0 +1,32 @@ + +os=$(uname) + +case $os in + FreeBSD) libdl=;; + Linux) libdl=-ldl;; + Haiku) libdl=;; + *) echo "Unsupported OS: $os"; exit 1;; +esac + +testdir=${testdir-testdir}/$(basename $0) + +rm -rf $testdir +mkdir -p $testdir +cd $testdir + +# test_run_ok +test_run_ok() +{ + # exists? + if [ ! -f $1 ]; then + exit 1 + fi + + # run + $1 + retval=$? + if [ $retval != $2 ]; then + echo "test_run_ok: $1: return value: $retval, expected: $2" + exit 1 + fi +} diff --git a/src/tests/system/runtime_loader/test_suite/test_suite b/src/tests/system/runtime_loader/test_suite/test_suite new file mode 100755 index 0000000000..ac71281bb3 --- /dev/null +++ b/src/tests/system/runtime_loader/test_suite/test_suite @@ -0,0 +1,31 @@ +#!/bin/sh + +for test in \ + load_resolve_basic1 \ + load_resolve_order1 \ + load_resolve_order2 \ + load_resolve_order3 \ + load_resolve_order4 \ + dlopen_resolve_basic1 \ + dlopen_resolve_basic2 \ + dlopen_resolve_basic3 \ + dlopen_lookup_order1 \ + dlopen_lookup_order2 \ + dlopen_lookup_order3 \ + dlopen_lookup_order4 \ + dlopen_resolve_order1 \ + dlopen_resolve_order2 \ + dlopen_resolve_order3 \ + dlopen_resolve_order4 \ + dlopen_resolve_order5 \ + dlopen_resolve_order6 \ + dlopen_resolve_order7 +do + echo -n "$test ... " + testdir=testdir ./$test + if [ $? = 0 ]; then + echo "ok" + else + echo "FAILED" + fi +done