Here's an updated version of a patch I did a few years ago to add loadable support for bash under HP-UX 10. The previous patch was for bash 4.0. This one has been updated for bash 4.2. It is fundamentally the same patch, just with different context and line numbers and stuff, so that it applies cleanly.
This patch adds shl_load (old HP-UX) support to bash 4.2 for enabling loadable builtins. In order for bash on HP-UX to actually load most of the builtins, it must be linked with the linker's -E flag as well, so you'll need to do something like this:
.../bash-4.2$ patch -p1 < ../bash-4.2-shl.diff .../bash-4.2$ autoconf .../bash-4.2$ CC=gcc LDFLAGS=-Wl,-E ./configure .../bash-4.2$ make If you're using the native HP-UX compiler, then the options may differ. diff -ur bash-4.2/builtins/enable.def bash-4.2-shl/builtins/enable.def --- bash-4.2/builtins/enable.def Sun Jan 4 14:32:22 2009 +++ bash-4.2-shl/builtins/enable.def Fri Oct 5 08:13:38 2012 @@ -82,11 +82,11 @@ #define PFLAG 0x10 #define SFLAG 0x20 -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) +#if (defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)) || (defined (HAVE_SHL_LOAD) && defined (HAVE_SHL_FINDSYM)) static int dyn_load_builtin __P((WORD_LIST *, int, char *)); #endif -#if defined (HAVE_DLCLOSE) +#if defined (HAVE_DLCLOSE) || defined (HAVE_SHL_UNLOAD) static int dyn_unload_builtin __P((char *)); static void delete_builtin __P((struct builtin *)); static int local_dlclose __P((void *)); @@ -104,7 +104,7 @@ { int result, flags; int opt, filter; -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) +#if (defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)) || (defined (HAVE_SHL_LOAD) && defined (HAVE_SHL_FINDSYM)) char *filename; #endif @@ -129,7 +129,7 @@ flags |= SFLAG; break; case 'f': -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) +#if (defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)) || (defined (HAVE_SHL_LOAD) && defined (HAVE_SHL_FINDSYM)) flags |= FFLAG; filename = list_optarg; break; @@ -137,7 +137,7 @@ builtin_error (_("dynamic loading not available")); return (EX_USAGE); #endif -#if defined (HAVE_DLCLOSE) +#if defined (HAVE_DLCLOSE) || defined (HAVE_SHL_UNLOAD) case 'd': flags |= DFLAG; break; @@ -172,7 +172,7 @@ list_some_builtins (filter); } -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) +#if (defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)) || (defined (HAVE_SHL_LOAD) && defined (HAVE_SHL_FINDSYM)) else if (flags & FFLAG) { filter = (flags & NFLAG) ? DISABLED : ENABLED; @@ -185,7 +185,7 @@ #endif } #endif -#if defined (HAVE_DLCLOSE) +#if defined (HAVE_DLCLOSE) || defined (HAVE_SHL_UNLOAD) else if (flags & DFLAG) { while (list) @@ -275,11 +275,17 @@ return (EXECUTION_SUCCESS); } -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) +#if (defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)) || (defined (HAVE_SHL_LOAD) && defined (HAVE_SHL_FINDSYM)) #if defined (HAVE_DLFCN_H) # include <dlfcn.h> #endif +#if defined (HAVE_DL_H) +# include <dl.h> +#endif +#if defined (HAVE_ERRNO_H) +# include <errno.h> +#endif static int dyn_load_builtin (list, flags, filename) @@ -288,7 +294,11 @@ char *filename; { WORD_LIST *l; +#if defined (HAVE_DLOPEN) void *handle; +#elif defined (HAVE_SHL_LOAD) + shl_t handle; +#endif int total, size, new, replaced; char *struct_name, *name; @@ -301,15 +311,22 @@ #define RTLD_LAZY 1 #endif -#if defined (_AIX) +#if defined (HAVE_DLOPEN) && defined (_AIX) handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL); -#else +#elif defined (HAVE_DLOPEN) handle = dlopen (filename, RTLD_LAZY); +#elif defined (HAVE_SHL_LOAD) + handle = shl_load (filename, BIND_IMMEDIATE | BIND_VERBOSE, 0L); #endif /* !_AIX */ if (handle == 0) { - builtin_error (_("cannot open shared object %s: %s"), filename, dlerror ()); + builtin_error (_("cannot open shared object %s: %s"), filename, +#if defined (HAVE_DLOPEN) + dlerror ()); +#elif defined (HAVE_SHL_LOAD) + strerror (errno)); +#endif return (EXECUTION_FAILURE); } @@ -329,11 +346,20 @@ strcpy (struct_name, name); strcpy (struct_name + size, "_struct"); +#if defined (HAVE_DLSYM) b = (struct builtin *)dlsym (handle, struct_name); if (b == 0) +#elif defined (HAVE_SHL_FINDSYM) + if (0 != shl_findsym (&handle, struct_name, TYPE_UNDEFINED, (void *) &b)) +#endif { builtin_error (_("cannot find %s in shared object %s: %s"), - struct_name, filename, dlerror ()); + struct_name, filename, +#if defined (HAVE_DLOPEN) + dlerror ()); +#elif defined (HAVE_SHL_LOAD) + strerror (errno)); +#endif free (struct_name); continue; } @@ -357,7 +383,11 @@ if (replaced == 0 && new == 0) { free (new_builtins); +#if defined (HAVE_DLCLOSE) dlclose (handle); +#elif defined (HAVE_SHL_UNLOAD) + shl_unload (handle); +#endif return (EXECUTION_FAILURE); } @@ -391,7 +421,7 @@ } #endif -#if defined (HAVE_DLCLOSE) +#if defined (HAVE_DLCLOSE) || defined (HAVE_SHL_UNLOAD) static void delete_builtin (b) struct builtin *b; @@ -432,12 +462,16 @@ local_dlclose (handle) void *handle; { +#if defined (HAVE_DLCLOSE) #if !defined (__MACHTEN__) return (dlclose (handle)); #else /* __MACHTEN__ */ dlclose (handle); return ((dlerror () != NULL) ? -1 : 0); #endif /* __MACHTEN__ */ +#elif defined (HAVE_SHL_UNLOAD) + return (shl_unload (handle)); +#endif /* HAVE_DLCLOSE or HAVE_SHL_UNLOAD */ } static int @@ -471,7 +505,12 @@ using it drops to zero. */ if (ref == 1 && local_dlclose (handle) != 0) { - builtin_error (_("%s: cannot delete: %s"), name, dlerror ()); + builtin_error (_("%s: cannot delete: %s"), name, +#if defined (HAVE_DLOPEN) + dlerror ()); +#elif defined (HAVE_SHL_LOAD) + strerror (errno)); +#endif return (EXECUTION_FAILURE); } diff -ur bash-4.2/config.h.in bash-4.2-shl/config.h.in --- bash-4.2/config.h.in Mon Aug 2 20:53:10 2010 +++ bash-4.2-shl/config.h.in Fri Oct 5 08:13:37 2012 @@ -548,6 +548,15 @@ /* Define if you have the dlsym function. */ #undef HAVE_DLSYM +/* Define if you have the shl_load function. */ +#undef HAVE_SHL_LOAD + +/* Define if you have the shl_unload function. */ +#undef HAVE_SHL_UNLOAD + +/* Define if you have the shl_findsym function. */ +#undef HAVE_SHL_FINDSYM + /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT @@ -894,6 +903,9 @@ /* Define if you have the <dirent.h> header file. */ #undef HAVE_DIRENT_H + +/* Define if you have the <dl.h> header file. */ +#undef HAVE_DL_H /* Define if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H diff -ur bash-4.2/configure.in bash-4.2-shl/configure.in --- bash-4.2/configure.in Mon Feb 7 17:03:14 2011 +++ bash-4.2-shl/configure.in Fri Oct 5 08:14:08 2012 @@ -657,7 +657,7 @@ BASH_HEADER_INTTYPES AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \ - memory.h locale.h termcap.h termio.h termios.h dlfcn.h \ + memory.h locale.h termcap.h termio.h termios.h dl.h dlfcn.h \ stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h \ syslog.h ulimit.h) AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h \ @@ -808,6 +808,8 @@ if test "$opt_static_link" != yes; then AC_CHECK_LIB(dl, dlopen) AC_CHECK_FUNCS(dlopen dlclose dlsym) +AC_CHECK_LIB(dld, shl_load) +AC_CHECK_FUNCS(shl_load shl_unload shl_findsym) fi dnl this defines HAVE_DECL_SYS_SIGLIST @@ -1078,7 +1080,8 @@ # Shared object configuration section. These values are generated by # ${srcdir}/support/shobj-conf # -if test "$ac_cv_func_dlopen" = "yes" && test -f ${srcdir}/support/shobj-conf +if ( test "$ac_cv_func_dlopen" = "yes" || test "$ac_cv_func_shl_load" = "yes" )\ + && test -f ${srcdir}/support/shobj-conf then AC_MSG_CHECKING(shared object configuration for loadable builtins) eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c "${host_cpu}" -o "${host_os}" -v "${host_vendor}"`