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>
   5 int localfunc(void);
   7 main() {
   8     shl_t handle;
   9     int (*rf)(void);
  11     handle = shl_load ("", BIND_IMMEDIATE | BIND_VERBOSE, 0L);
  12     if (handle == NULL) {
  13         perror ("shl_load failed");
  14         return 1;
  15     }
  17     printf ("I am foo\n");
  19     if (shl_findsym (&handle, "remotefunc", TYPE_UNDEFINED, (void *) &rf)) {
  20         perror ("shl_findsym remotefunc failed");
  21         return 1;
  22     }
  23 }
  25 int localfunc(void) {
  26     printf ("I am localfunc\n");
  27     return 0;
  28 }

And here's the "library" it loads:

   1 /* bar.c */
   2 #include <stdio.h>
   4 extern int localfunc(void);
   6 int remotefunc(void) {
   7     printf ("I am remotefunc\n");
   8     localfunc();
   9 }

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.o
   4 imadev:~/tmp$ gcc -o foo foo.o -ldld
   5 imadev:~/tmp$ ./foo
   6 /usr/lib/ Unresolved symbol: localfunc (code)  from
   7 shl_load failed: Unresolved external

And this is bash doing the same thing:

   1 imadev:/var/tmp/bash-4.0-shl$ enable -f examples/loadables/ whoami
   2 /usr/lib/ Unresolved symbol: loptend (data)  from examples/loadables/
   3 /usr/lib/ Unresolved symbol: current_user (data)  from examples/loadables/
   4 /usr/lib/ Unresolved symbol: builtin_usage (code)  from examples/loadables/
   5 /usr/lib/ Unresolved symbol: reset_internal_getopt (code)  from examples/loadables/
   6 /usr/lib/ Unresolved symbol: internal_getopt (code)  from examples/loadables/
   7 /usr/lib/ Unresolved symbol: get_current_user_info (code)  from examples/loadables/
   8 bash: enable: cannot open shared object examples/loadables/ 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.

ShlLoad (last edited 2015-09-28 19:13:18 by GreyCat)