SUNOS 4.1 dynamic loading doesn't work as documented

Chuck Ocheret chuck at morgan.com
Sat Jun 30 02:19:33 AEST 1990


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 at 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



More information about the Comp.sys.sun mailing list