My adventures with shl_load on HP-UX 10.20.
I'm trying to get bash's loadable functions to work on HP-UX 10.20. But HP-UX 10.20 doesn't have dlopen and friends, so I'm trying to get the shl_load family to work. They look superficially similar in nature. I even managed to hack through all the autoconf stuff, etc. and got it working... sort of. I can load the true and false builtins and observe a change in the help true output. But if I attempt to load any of the more complicated builtins -- the ones that actually do things -- I get unresolved symbols. It seems an shl_loaded library can't resolve symbols that are already part of the running program.
Here is a simple program that loads a "library", in which a function calls something that's already part of the program. This is analogous to what bash is doing with its loadable builtin examples, most of which call internal bash functions.
1 /* foo.c */
2 #include <stdio.h>
3 #include <dl.h>
4
5 int localfunc(void);
6
7 main() {
8 shl_t handle;
9 int (*rf)(void);
10
11 handle = shl_load ("bar.so", BIND_IMMEDIATE | BIND_VERBOSE, 0L);
12 if (handle == NULL) {
13 perror ("shl_load bar.so failed");
14 return 1;
15 }
16
17 printf ("I am foo\n");
18
19 if (shl_findsym (&handle, "remotefunc", TYPE_UNDEFINED, (void *) &rf)) {
20 perror ("shl_findsym remotefunc failed");
21 return 1;
22 }
23 }
24
25 int localfunc(void) {
26 printf ("I am localfunc\n");
27 return 0;
28 }
And here's the "library" it loads:
And here's how I build and run it:
1 imadev:~/tmp$ gcc -c foo.c
2 imadev:~/tmp$ gcc -c -fpic bar.c
3 imadev:~/tmp$ ld -b -o bar.so bar.o
4 imadev:~/tmp$ gcc -o foo foo.o -ldld
5 imadev:~/tmp$ ./foo
6 /usr/lib/dld.sl: Unresolved symbol: localfunc (code) from bar.so
7 shl_load bar.so failed: Unresolved external
And this is bash doing the same thing:
1 imadev:/var/tmp/bash-4.0-shl$ enable -f examples/loadables/whoami.so whoami
2 /usr/lib/dld.sl: Unresolved symbol: loptend (data) from examples/loadables/whoami.so
3 /usr/lib/dld.sl: Unresolved symbol: current_user (data) from examples/loadables/whoami.so
4 /usr/lib/dld.sl: Unresolved symbol: builtin_usage (code) from examples/loadables/whoami.so
5 /usr/lib/dld.sl: Unresolved symbol: reset_internal_getopt (code) from examples/loadables/whoami.so
6 /usr/lib/dld.sl: Unresolved symbol: internal_getopt (code) from examples/loadables/whoami.so
7 /usr/lib/dld.sl: Unresolved symbol: get_current_user_info (code) from examples/loadables/whoami.so
8 bash: enable: cannot open shared object examples/loadables/whoami.so: Unresolved external
I set up an analogous program using dlopen on a Linux box, and that worked (although I had to screw with LD_LIBRARY_PATH to make the load work). I'll omit it for the time being.
TheBonsai tracked down some documentation that explains that you have to supply a linker argument of -E on HP-UX to make the main program export local symbols to the dynamically loaded libraries... so let's try that.
1 imadev:~/tmp$ gcc -Wl,-E -o foo foo.o -ldld
2 imadev:~/tmp$ ./foo
3 I am foo
4 I am remotefunc
5 I am localfunc
... huh, OK. Now I guess I get to figure out how to put that into the bash build process. Maybe by manually setting LDFLAGS during ./configure I suppose.