Subject: Re: Xerces-P link problems
To: Emmanuel Dreyfus <p99dreyf@criens.u-psud.fr>
From: Nick Hudson <skrll@netbsd.org>
List: tech-pkg
Date: 04/02/2001 10:05:15
This is a multi-part message in MIME format.
--------------C600EB516F2D171928EF2EF6
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Emmanuel Dreyfus wrote:
> 
> Hi!
> 
> I'm still working on xerces-p, and I wonder if the problem I encounter
> are caused by the way Xerces-C is linked or the way Perl is linked.
> 
> At run time, perl complain because __eh_alloc is an undefined symbol.
> __eh_malloc is normally statically linked in a binary, through libgcc.a
> 
> The perl executable does not contain the __eh_alloc symbol, an libxerces
> does require it. I think this is why we end up with a problem.

Use -export-dynamic when linking the perl executable.

> It is not possible to link the Perl xerces module with -lgcc, because
> libgcc.a is not built as PIC. linking with -lgcc will cause link errors.

Right.

> I think the problem is in perl, but I'm not sure. The big question is
> why perl does not contain all these symbols? Is perl linked with
> libgcc.a? If not, why isn't it? Could we link it with libgcc.a?

All binaries should be linked with libgcc.a

> Or maybe these symbols references should not be in xerces-c? What are
> they used for?

-export-dynamic makes the symbols from libgcc.a available for dynamic
linking.

I've put together a small example for you in the attached shar

$ diff -rNc2 fail work
diff -rNc2 fail/Makefile work/Makefile
*** fail/Makefile       Mon Apr  2 09:59:17 2001
--- work/Makefile       Mon Apr  2 09:57:59 2001
***************
*** 3,6 ****
--- 3,7 ----
 
  MKMAN=        no
+ LDFLAGS=      -Wl,-export-dynamic
 
  .include <bsd.prog.mk>

Nick
-- 
aka skrll@netbsd.org, skrll@excite.co.uk
--------------C600EB516F2D171928EF2EF6
Content-Type: text/plain; charset=us-ascii;
 name="ed-shar"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ed-shar"

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	.
#	./Makefile
#	./work
#	./work/main.cpp
#	./work/Makefile
#	./fail
#	./fail/Makefile
#	./fail/main.cpp
#	./lib
#	./lib/foo.ln
#	./lib/Makefile
#	./lib/foo.cc
#	./lib/shlib_version
#
echo c - .
mkdir -p . > /dev/null 2>&1
echo x - ./Makefile
sed 's/^X//' >./Makefile << 'END-of-./Makefile'
XSUBDIR=	lib work fail
X
Xall:
X	work/main
X	fail/main
X
X.include <bsd.subdir.mk>
END-of-./Makefile
echo c - ./work
mkdir -p ./work > /dev/null 2>&1
echo x - ./work/main.cpp
sed 's/^X//' >./work/main.cpp << 'END-of-./work/main.cpp'
X#include <dlfcn.h>
X#include <stdio.h>
X
Xint
Xmain()
X{
X	void *handle;
X	int (*fp)(int);
X
X	printf("Started\n");
X
X	handle = dlopen("./lib/libfoo.so.1.0", RTLD_LAZY);
X	if (!handle) {
X		fprintf(stderr, "Can't open module\n");
X		fprintf(stderr, "Error: %s\n", dlerror());
X		exit(1);
X	}
X		
X	printf("handle=%p\n", handle);
X
X	fp = (int (*)(int))dlsym(handle, "foo");
X
X	printf("fp=%p\n", fp);
X	try {
X		(*fp)(1);
X	}
X	catch (char *e) {
X		printf("Exception %s\n", e);
X	}
X}
END-of-./work/main.cpp
echo x - ./work/Makefile
sed 's/^X//' >./work/Makefile << 'END-of-./work/Makefile'
XPROG=	main
XSRCS=	main.cpp
X
XMKMAN=	no
XLDFLAGS=	-Wl,-export-dynamic
X
X.include <bsd.prog.mk>
END-of-./work/Makefile
echo c - ./fail
mkdir -p ./fail > /dev/null 2>&1
echo x - ./fail/Makefile
sed 's/^X//' >./fail/Makefile << 'END-of-./fail/Makefile'
XPROG=	main
XSRCS=	main.cpp
X
XMKMAN=	no
X
X.include <bsd.prog.mk>
END-of-./fail/Makefile
echo x - ./fail/main.cpp
sed 's/^X//' >./fail/main.cpp << 'END-of-./fail/main.cpp'
X#include <dlfcn.h>
X#include <stdio.h>
X
Xint
Xmain()
X{
X	void *handle;
X	int (*fp)(int);
X
X	printf("Started\n");
X
X	handle = dlopen("./lib/libfoo.so.1.0", RTLD_LAZY);
X	if (!handle) {
X		fprintf(stderr, "Can't open module\n");
X		fprintf(stderr, "Error: %s\n", dlerror());
X		exit(1);
X	}
X		
X	printf("handle=%p\n", handle);
X
X	fp = (int (*)(int))dlsym(handle, "foo");
X
X	printf("fp=%p\n", fp);
X	try {
X		(*fp)(1);
X	}
X	catch (char *e) {
X		printf("Exception %s\n", e);
X	}
X}
END-of-./fail/main.cpp
echo c - ./lib
mkdir -p ./lib > /dev/null 2>&1
echo x - ./lib/foo.ln
sed 's/^X//' >./lib/foo.ln << 'END-of-./lib/foo.ln'
X0sfoo.c
XSfoo.c
X4c0.4i8real_foof1II
X2d0.2d3fooF1IV
END-of-./lib/foo.ln
echo x - ./lib/Makefile
sed 's/^X//' >./lib/Makefile << 'END-of-./lib/Makefile'
XLIB=	foo
XSRCS=	foo.cc
XMKLINT=	no
X#CFLAGS=	-fexceptions -frtti
X#LDADD=	-export-dynamic
X
X.include <bsd.lib.mk>
END-of-./lib/Makefile
echo x - ./lib/foo.cc
sed 's/^X//' >./lib/foo.cc << 'END-of-./lib/foo.cc'
X#include <stdio.h>
X
Xvoid
Xreal_foo(int i)
X{
X	try {
X		i++;
X		throw 1;
X	}
X	catch (...) {
X		fprintf(stderr, "Error in library\n");
X	}
X	throw "Oops!";
X}
X
Xextern "C"
X{
X    void *foo(int i)
X    {
X        real_foo(i);
X    }
X}
END-of-./lib/foo.cc
echo x - ./lib/shlib_version
sed 's/^X//' >./lib/shlib_version << 'END-of-./lib/shlib_version'
Xmajor=1
Xminor=0
END-of-./lib/shlib_version
exit



--------------C600EB516F2D171928EF2EF6--