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