chuck@morgan.com (Chuck Ocheret) (06/29/90)
I have attempted to dynamically load object files into a running process by using the interface provided by dlopen(3X), dlsym(3X), dlclose(3X) and dlerror(3X) under SUNOS 4.1 with little success. Below are a Makefile and two C source files (very short) in a shar file which demonstrate my problem (dlsun.c and dlsunaux.c). The file dlsunaux.c contains the functions init(), fini(), foo_a(), and foo_b(). I compile this file -pic and create a shared object using ld -assert pure-text. The program in dlsun.c loads in the shared object file with dlopen(3X), attempts to locate the functions foo_a() and foo_b() using dlsym(3X), invokes the functions, and cleans up using dlclose(3X). I use dlerror(3X) to get diagnostics when the other functions fail. Problem #1: According to the documentation the function init() should be called by dlopen(3X) if it exists in the shared object. It is not called. I have tried calling the function init() and _init() and neither works. Problem #2: The call to dlsym(3X) to resolve the symbol foo_a fails. I have tried refering to the symbol as both "foo_a" and "_foo_a" and both fail. What is the problem? Is there some additional preparation of the shared object required? Must there also be a .sa file? Does dlopen(3X) automatically open .sa files if they exist? +------------------+ Chuck Ocheret, Sr. Staff Engineer +-----------------+ | chuck@Morgan.COM | Morgan Stanley & Co., Inc. | (212) 703-4474 | | Duty now ... |19th Floor, 1251 Avenue of the Americas| for the future. | +------------------+ New York, N.Y. 10020 USA +-----------------+ -----------------CUT HERE--------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # Makefile # dlsun.c # dlsunaux.c # This archive created: Fri Jun 29 11:56:13 1990 export PATH; PATH=/bin:$PATH echo shar: extracting "'Makefile'" '(230 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else sed 's/^ X//' << \SHAR_EOF > 'Makefile' X# X# simple makefile for dynamic load problem X# Xall: dlsun dlsunaux.so.1 X Xdlsun: X cc -o dlsun dlsun.c -ldl X Xdlsunaux.o: dlsunaux.c X cc -c -pic dlsunaux.c X Xdlsunaux.so.1: dlsunaux.o X ld -o dlsunaux.so.1 -assert pure-text dlsunaux.o SHAR_EOF if test 230 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 230 characters)' fi fi # end of overwriting check echo shar: extracting "'dlsun.c'" '(986 characters)' if test -f 'dlsun.c' then echo shar: will not over-write existing file "'dlsun.c'" else sed 's/^ X//' << \SHAR_EOF > 'dlsun.c' X#include <stdio.h> X#include <dlfcn.h> X Xmain(argc, argv) X int argc; X char *argv[]; X{ X int a, b; X int (*funca)(), (*funcb)(); X void *handle; X X a = 21; X b = 13; X X /* Open the shared object containing functions foo_a() and foo_b() */ X if ((handle = dlopen("dlsunaux.so.1", 1)) == NULL) { X (void)fprintf(stderr, "dlopen:%s\n", dlerror()); X exit(1); X } X X /* Get address of foo_a() */ X if ((funca = (int (*)())dlsym(handle, "_func_a")) == NULL) { X (void)fprintf(stderr, "funca:dlsym:%s\n", dlerror()); X exit(1); X } X X /* Get address of foo_b() */ X if ((funcb = (int (*)())dlsym(handle, "_func_b")) == NULL) { X (void)fprintf(stderr, "funcb:dlsym:%s\n", dlerror()); X exit(1); X } X X /* Invoke the foo_a() and foo_b() */ X (void)printf("%d + %d = %d\n", a, b, (*funca)(a, b)); X (void)printf("%d - %d = %d\n", a, b, (*funcb)(a, b)); X if (dlclose(handle)) { X (void)fprintf(stderr, "dlclose:%s\n", dlerror()); X exit(1); X } X exit(0); X} X X/* end of dlsun.c */ SHAR_EOF if test 986 -ne "`wc -c < 'dlsun.c'`" then echo shar: error transmitting "'dlsun.c'" '(should have been 986 characters)' fi fi # end of overwriting check echo shar: extracting "'dlsunaux.c'" '(361 characters)' if test -f 'dlsunaux.c' then echo shar: will not over-write existing file "'dlsunaux.c'" else sed 's/^ X//' << \SHAR_EOF > 'dlsunaux.c' X#include <stdio.h> X X/* Should be called when dlopen() is invoked */ Xvoid init() X{ X (void)fprintf(stderr, "init() called\n"); X} X X/* Should be called when dlclose() is invoked */ Xvoid fini() X{ X (void)fprintf(stderr, "fini() called\n"); X} X Xint foo_a(a, b) X int a, b; X{ X return a + b; X} X Xint foo_b(a, b) X int a, b; X{ X return a - b; X} X X/* end of dlsunaux.c */ SHAR_EOF if test 361 -ne "`wc -c < 'dlsunaux.c'`" then echo shar: error transmitting "'dlsunaux.c'" '(should have been 361 characters)' fi fi # end of overwriting check # End of shell archive exit 0
chuck@morgan.com (Chuck Ocheret) (07/06/90)
Sorry, problem number 2 was due to a typo. However, problem number 1 (dlopen() does not call _init() and dlclose() does not call fini()) still holds. I ran "strings - /usr/lib/libdl.so* | grep ini" and saw no references to init or fini. Oh well... +------------------+ Chuck Ocheret, Sr. Staff Engineer +-----------------+ | chuck@Morgan.COM | Morgan Stanley & Co., Inc. | (212) 703-4474 | | Duty now ... |19th Floor, 1251 Avenue of the Americas| for the future. | +------------------+ New York, N.Y. 10020 USA +-----------------+
guy@uunet.uu.net (Guy Harris) (07/08/90)
>Sorry, problem number 2 was due to a typo. However, problem number 1 >(dlopen() does not call _init() and dlclose() does not call fini()) still >holds. > >I ran "strings - /usr/lib/libdl.so* | grep ini" and saw no references to >init or fini. Oh well... Yup, it's a bug. Note that the System V Release 4 documentation on the "dl*()" routines doesn't mention "_init()" nor "_fini()", so if you want your code to work under S5R4 as well, you may want to avoid depending on "_init()" and "_fini()" working even if, as, and when the bug gets fixed.