1#!/bin/sh
2
3# program
4#
5# dlopen():
6# libe.so
7# liba.so
8# <- libb.so
9#    <- libd.so
10#
11# Expected: dlsym(RTLD_NEXT) finds symbol in order libe.so, liba.so, libb.so,
12# libd.so
13
14
15. ./test_setup
16
17
18# create libd.so
19cat > libd.c << EOI
20int a() { return 1; }
21EOI
22
23# build
24compile_lib -o libd.so libd.c
25
26
27# create libb.so
28cat > libb.c << EOI
29#define __USE_GNU
30#include <dlfcn.h>
31int
32a()
33{
34	int (*nextA)();
35	*(void**)&nextA = dlsym(RTLD_NEXT, "a");
36	return (nextA != 0 ? nextA() : 0) + 2;
37}
38EOI
39
40# build
41compile_lib_dl -o libb.so libb.c ./libd.so
42
43
44# create liba.so
45cat > liba.c << EOI
46#include <dlfcn.h>
47int
48a()
49{
50	int (*nextA)();
51	*(void**)&nextA = dlsym(RTLD_NEXT, "a");
52	return (nextA != 0 ? nextA() : 0) + 4;
53}
54EOI
55
56# build
57compile_lib_dl -o liba.so liba.c ./libb.so
58
59
60# create libe.so
61cat > libe.c << EOI
62#include <dlfcn.h>
63int
64a()
65{
66	int (*nextA)();
67	*(void**)&nextA = dlsym(RTLD_NEXT, "a");
68	return (nextA != 0 ? nextA() : 0) + 8;
69}
70EOI
71
72# build
73compile_lib_dl -o libe.so libe.c
74
75
76# create program
77cat > program.c << EOI
78#include <dlfcn.h>
79#include <stdio.h>
80#include <stdlib.h>
81
82int
83a()
84{
85	int (*nextA)();
86	*(void**)&nextA = dlsym(RTLD_NEXT, "a");
87	return (nextA != 0 ? nextA() : 0) + 16;
88}
89
90int
91main()
92{
93	void* liba;
94	void* libe;
95	void* self;
96
97	libe = dlopen("./libe.so", RTLD_NOW | RTLD_GLOBAL);
98	if (libe == NULL) {
99		fprintf(stderr, "Error opening libe.so: %s\n", dlerror());
100		exit(117);
101	}
102
103	liba = dlopen("./liba.so", RTLD_NOW | RTLD_GLOBAL);
104	if (liba == NULL) {
105		fprintf(stderr, "Error opening liba.so: %s\n", dlerror());
106		exit(117);
107	}
108
109	return a();
110}
111EOI
112
113# build
114compile_program_dl -o program program.c
115
116# run
117test_run_ok ./program 31
118