From: witr@rwwa.COM (Robert Withrow)
Subject: Problem with symbol resolving in dyn-loaded modules.
Reply-To: witr@rwwa.com
Organization: R.W. Withrow Associates
Distribution: usa
Date: Mon, 4 Jan 1993 01:33:48 GMT

I am using (on SVR4.0.3.0/386) the dlxxx(3X) routines to load modules.
These modules need to reference routines (symbols) in the a.out that
executed the dlopen.  The documentation seems to imply that either this
can or cannot be done depending on how you twist your glasses.  I've found
a slimy hack to make it work, but it seems like I shouldn't have to do this.
Example files are appended, but let me be more explicit:

assume that a.c looks like this:

  main()
  {
     dlopen("./b.so",RTLD_NOW)
  
     routineInB()
  }

  routineInA() {}

and that b.c looks like:

  routineInB()
  {
    routineInA();
  }

Without my slimy hack the dlopen fails complaining it can't resolve routineInA.
The hack seems to force ld to export symbol routineInA so that the loader
can see it.  Surely there must be a non-hack way of making this happen?

P.S. the hack involves creating a shared object that simply references
the global text symbols in the a.out, and linking it with the a.out.
This is distastefull because it slows down the startup of the a.out and
generally clutters things up...

-=-=-=-=- Example -=-=-=-=-=

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile fee.c foo.c fum.c
# Wrapped by witr@spooky on Sun Jan  3 20:28:29 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(478 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# makes two versions of the foo program, one *with* the hack of
X# fum.so and one without.  The *with* program succeeds.  Why?
X
X.SUFFIXES: .so .o .c 
X
X.o.so:
X	cc -G -o $(@F) $(<F)
X
Xall:	with without fee.so
X
Xwithout: foo.o
X	$(CC) $(CFLAGS) -o $(@F) foo.o -ldl
X
Xwith:	foo.o fum.so
X	$(CC) $(CFLAGS) -o $(@F) foo.o ./fum.so -ldl
X
Xfum.o:	fum.c
X	$(CC) $(CFLAGS) -K PIC -c fum.c
X
Xfee.o:	fee.c
X	$(CC) $(CFLAGS) -K PIC -c fee.c
X
Xclean:
X	rm -f foo.o fee.o fee.so fum.o fum.so with without
END_OF_FILE
if test 478 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'fee.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fee.c'\"
else
echo shar: Extracting \"'fee.c'\" \(137 characters\)
sed "s/^X//" >'fee.c' <<'END_OF_FILE'
Xint TheFunc(int arg)
X{
X  extern int YetAnotherFunc(int arg);
X
X  printf("TheFunc(%d) got called.\n",arg);
X  return YetAnotherFunc(arg);
X}
END_OF_FILE
if test 137 -ne `wc -c <'fee.c'`; then
    echo shar: \"'fee.c'\" unpacked with wrong size!
fi
# end of 'fee.c'
fi
if test -f 'foo.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'foo.c'\"
else
echo shar: Extracting \"'foo.c'\" \(715 characters\)
sed "s/^X//" >'foo.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <stdlib.h>
X#include <dlfcn.h>
X
Xtypedef int afunc(int);
X
Xmain(int argc,char *argv[])
X{
X  void *dlhandle;
X  afunc *thefunc;
X  char file[] = "./fee.so";
X  char func[] = "TheFunc";
X  int funcret;
X
X  fprintf(stderr,"Loading %s\n",file);
X  if ((dlhandle = dlopen(file,RTLD_NOW)) == NULL) {
X    fprintf(stderr,"Load of %s failed: %s.\n",file,dlerror());
X    exit(EXIT_FAILURE);
X  }
X
X  if ((thefunc = (afunc *)dlsym(dlhandle,func)) == NULL) {
X    fprintf(stderr,"Couldn't resolve %s: %s.\n",func,dlerror());
X    exit(EXIT_FAILURE);
X  }
X
X  funcret = thefunc(42);
X  exit(funcret);
X}
X
Xint YetAnotherFunc(int arg)
X{
X  fprintf(stderr,"YetAnotherFunc(%d) was called.\n",arg);
X  return EXIT_SUCCESS;
X}
END_OF_FILE
if test 715 -ne `wc -c <'foo.c'`; then
    echo shar: \"'foo.c'\" unpacked with wrong size!
fi
# end of 'foo.c'
fi
if test -f 'fum.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fum.c'\"
else
echo shar: Extracting \"'fum.c'\" \(104 characters\)
sed "s/^X//" >'fum.c' <<'END_OF_FILE'
Xtypedef void f(void);
Xextern void YetAnotherFunc(void);
Xstatic f *localYetAnotherFunc = YetAnotherFunc;
END_OF_FILE
if test 104 -ne `wc -c <'fum.c'`; then
    echo shar: \"'fum.c'\" unpacked with wrong size!
fi
# end of 'fum.c'
fi
echo shar: End of shell archive.
exit 0

-- 
 Robert Withrow, Tel: +1 617 598 4480, Fax: +1 617 598 4430, Net: witr@rwwa.COM
 R.W. Withrow Associates, 21 Railroad Ave, Swampscott MA 01907-1821 USA