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
This commit is contained in:
Ingo Weinhold 2008-11-08 02:04:53 +00:00
parent e0540f7ee3
commit 67ef7f5678
21 changed files with 1530 additions and 0 deletions

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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 <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <program> <expected return value>
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
}

View File

@ -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