1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
As see on Linux when running:
saoconfig shmainlib
make
make shmainlib
setenv LD_LIBRARY_PATH .
gcc -g -o tmain -I. -I./util tmain.c libfuntoolsMainLib.a libfuntools.a -ldl -lm
or
gcc -g -o tmain -I. -I./util tmain.c libfuntools.a -ldl -lm
./tmain -s libfuntoolsMainLib.so $S "fundisp foo[cir(512,512,.1)]"
gives:
...
0xb7ef80f4 0xb7ef80f4
0xb7ef80f4
0xb7ef80f4 0xb7ef80f4
executing: fundisp "buf:0xb7f3e008:648000[cir(512,512,.1)]"
0x8062650
0x8062650 0x8062650
The hex numbers are the address of the mainlibhead list header for
mainlib records. How can this address change?
We link tmain against either libutil.a or libfuntools.a to get the
MainLibLoad() routine. When this routine is called, it loads the
libfuntoolsMainLib.so library, and, using that library calls
funtoolsMainLibInit(). This routine makes a bunch of MainLibNew()
and uses mainlibhead in the static executable as the list head.
Apparently, because we add -L. -lfuntools to the mklib command line:
./mklib -o $(PACKAGE)MainLib -L. -lfuntools $(PACKAGE)tmp/*.o; \
libfuntools.so is loaded as well. This has the mainlib.o module in it,
and of course, a new copy of mainlibhead.
So, when MainLibProcess() is subsequently called, it probably comes
from the shared object, not the statically linked executable. At any
rate, it uses the mainllibhead from the shared object, which is NULL,
and therefore does not see that fundisp has been defined.
If we don't add -L. -lfuntools to the mklib command line:
./mklib -o $(PACKAGE)MainLib $(PACKAGE)tmp/*.o; \
and remake the libfuntoolsMainLib.so file, we get an error when we try to run:
make shmainlib
mklib: Making Linux shared library: libfuntoolsMainLib.so.1.0
./tmain -s libfuntoolsMainLib.so $S "fundisp foo[cir(512,512,.1)]"
can't load shared object libfuntoolsMainLib.so (./libfuntoolsMainLib.so: undefined symbol: SAOdtype)
This is because the statically linked program does not call SAOdtype
and therefore does not have it linked in. It must come from a loaded
shared object.
So we have to load a shared object to get funtools entry points, but we
don't want a second copy of mainlibhead ...
Even if we separate MainLibLoad from mainlib.c and don't explicitly
load mainlib.c, we still get the wrong mainlibhead:
nm tmain | egrep mainlib
08062650 b mainlibhead
08062654 b mainlibinit
08062658 b mainlib_path
080625f0 d mainlibundef
|