Path: utzoo!attcan!uunet!jarthur!usc!cs.utexas.edu!rice!sun-spots-request From: chuck@morgan.com (Chuck Ocheret) Newsgroups: comp.sys.sun Subject: SUNOS 4.1 dynamic loading doesn't work as documented Keywords: SunOS Message-ID: <9579@brazos.Rice.edu> Date: 29 Jun 90 16:19:33 GMT Sender: root@rice.edu Organization: Sun-Spots Lines: 165 Approved: Sun-Spots@rice.edu X-Sun-Spots-Digest: Volume 9, Issue 250, message 1 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 X#include 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 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