A patch to make libgcc local in shared library
H.J. Lu
hjl@lucon.org
Fri Dec 11 14:07:00 GMT 1998
> > reached. But it ensures those symbols will be included in libfoo.so.
>
> But you have to do this for _every_ routine in libgcc.a! You might
> just as well use
>
> ld ... foo.o -lc --whole-archive libgcc.a --no-whole-archive
>
> to link everything.
>
> Any libgcc.a routine may end up in a shared object, and any shared
> object might be changed so that its external interface doesn't change
> but the set of libgcc.a routines that it uses changes.
>
Here is a patch for egcs. It will make function symbols local in
shared libraries.
H.J.
----
Fri Dec 11 07:08:59 1998 H.J. Lu (hjl@gnu.org)
* Makefile.in (OBJDUMP_FOR_TARGET): New.
(LIBGCC_MAP): New. Set to empty.
(all.cross, rest.cross, rest.encap): Add $(LIBGCC_MAP) to
dependency.
(install-common): Install libgcc.map if appropriate.
(stage1-start, stage2-start, stage3-start, stage4-start): Copy
libgcc.map if appropriate.
(clean): Also remove libgcc.map.
(libgcc.map): New rule.
* config/t-linux (LIBGCC_MAP): New.
(EXTRACT_LIBGCC): New.
* config/t-linux-gnulibc1 (LIBGCC_MAP): Cleared.
* config/linux.h (LIB_SPEC): Modefied if USE_GNULIBC_1 is not
defined.
Index: Makefile.in
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/Makefile.in,v
retrieving revision 1.1.1.88
diff -u -r1.1.1.88 Makefile.in
--- Makefile.in 1998/12/10 22:51:22 1.1.1.88
+++ Makefile.in 1998/12/11 18:09:43
@@ -195,6 +196,16 @@
fi; \
fi`
AR_FOR_TARGET_FLAGS = rc
+OBJDUMP_FOR_TARGET= ` \
+ if [ -f $(objdir)/../binutils/objdump ] ; then \
+ echo $(objdir)/../binutils/objdump ; \
+ else \
+ if [ "$(host_canonical)" = "$(target)" ] ; then \
+ echo objdump; \
+ else \
+ t='$(program_transform_name)'; echo objdump | sed -e $$t ; \
+ fi; \
+ fi`
RANLIB_FOR_TARGET = ` \
if [ -f $(objdir)/../binutils/ranlib ] ; then \
echo $(objdir)/../binutils/ranlib ; \
@@ -355,6 +367,9 @@
# libgcc1-test target (must also be overridable for a target)
LIBGCC1_TEST = libgcc1-test
+# The libgcc symbol versioning map.
+LIBGCC_MAP=
+
# List of extra executables that should be compiled for this target machine
# that are used for compiling from source code to object code.
# The rules for compiling them should be in the t-* file for the machine.
@@ -809,13 +824,14 @@
# Note that we can compile enquire using the cross-compiler just built,
# although we can't run it on this machine.
all.cross: native gcc-cross specs stmp-headers $(STMP_FIXPROTO) $(LIBGCC) \
- $(LIBGCC1_TEST) $(EXTRA_PARTS) lang.all.cross
+ $(LIBGCC_MAP) $(LIBGCC1_TEST) $(EXTRA_PARTS) lang.all.cross
# This is what to compile if making gcc with a cross-compiler.
all.build: native xgcc$(exeext) $(EXTRA_PARTS) lang.all.build
# This is what must be made before installing GCC and converting libraries.
start.encap: native xgcc$(exeext) specs $(LIBGCC1) xlimits.h lang.start.encap
# These can't be made until after GCC can run.
-rest.encap: stmp-headers $(STMP_FIXPROTO) $(LIBGCC) $(EXTRA_PARTS) lang.rest.encap
+rest.encap: stmp-headers $(STMP_FIXPROTO) $(LIBGCC) $(LIBGCC_MAP) \
+ $(EXTRA_PARTS) lang.rest.encap
# This is what is made with the host's compiler
# whether making a cross compiler or not.
native: config.status auto-host.h cpp$(exeext) $(LANGUAGES) \
@@ -830,7 +846,7 @@
# On the target machine, finish building a cross compiler.
# This does the things that can't be done on the host machine.
-rest.cross: $(LIBGCC) gfloat.h specs
+rest.cross: $(LIBGCC) $(LIBGCC_MAP) gfloat.h specs
# Verify that it works to compile and link libgcc1-test.
# If it does, then there are sufficient replacements for libgcc1.a.
@@ -2267,7 +2285,7 @@
# Using unprotoize.c is not quite right in the first place,
# but what better way is there?
-rm -f libgcc.a libgcc1.a libgcc1-asm.a libgcc2.a libgcc2.ready
- -rm -f libgcc1.null
+ -rm -f libgcc1.null libgcc.map
-rm -f *.dvi
-rm -f */*.dvi
-if [ -f md.pre-cpp ]; then \
@@ -2416,6 +2434,12 @@
$(INSTALL_DATA) specs $(libsubdir)/specs; \
chmod a-x $(libsubdir)/specs; \
fi
+# Install libgcc.map if it exists.
+ -if [ -n "$(LIBGCC_MAP)" -a -f libgcc.map ] ; then \
+ rm -f $(libsubdir)/libgcc.map; \
+ $(INSTALL_DATA) libgcc.map $(libsubdir)/libgcc.map; \
+ chmod a-x $(libsubdir)/libgcc.map; \
+ fi
# Install protoize if it was compiled.
-if [ -f protoize$(exeext) ]; \
then \
@@ -2903,6 +2934,10 @@
-if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage1 ; else true ; fi
-rm -f stage1/libgcc.a
-cp libgcc.a stage1
+ -if [ -n "$(LIBGCC_MAP)" -a -f libgcc.map ] ; then \
+ rm -f stage1/libgcc.map; \
+ cp libgcc.map stage1; \
+ fi
-if $(RANLIB_TEST) ; then $(RANLIB) stage1/libgcc.a; else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage1/$${f} . ; \
@@ -2924,6 +2959,10 @@
-if [ -f collect-ld ] ; then $(LN_S) ../collect-ld$(exeext) stage2 ; else true ; fi
-rm -f stage2/libgcc.a
-cp libgcc.a stage2
+ -if [ -n "$(LIBGCC_MAP)" -a -f libgcc.map ] ; then \
+ rm -f stage2/libgcc.map; \
+ cp libgcc.map stage2; \
+ fi
-if $(RANLIB_TEST) ; then $(RANLIB) stage2/libgcc.a; else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage2/$${f} . ; \
@@ -2945,6 +2984,10 @@
-if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage3 ; else true ; fi
-rm -f stage3/libgcc.a
-cp libgcc.a stage3
+ -if [ -n "$(LIBGCC_MAP)" -a -f libgcc.map ] ; then \
+ rm -f stage3/libgcc.map; \
+ cp libgcc.map stage3; \
+ fi
-if $(RANLIB_TEST) ; then $(RANLIB) stage3/libgcc.a; else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage3/$${f} . ; \
@@ -2966,6 +3009,10 @@
-if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage4 ; else true ; fi
-rm -f stage4/libgcc.a
-cp libgcc.a stage4
+ -if [ -n "$(LIBGCC_MAP)" -a -f libgcc.map ] ; then \
+ rm -f stage4/libgcc.map; \
+ cp libgcc.map stage4; \
+ fi
-if $(RANLIB_TEST) ; then $(RANLIB) stage4/libgcc.a; else true; fi
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage4/$${f} . ; \
@@ -3047,3 +3094,9 @@
echo "#endif" >> t-float.h-cross
mv t-float.h-cross float.h-cross
+# Rule to generate the libgcc symbol versioning map.
+libgcc.map: libgcc.a
+ echo "GCC.INTERNAL {" > $@
+ echo " local:" >> $@
+ $(EXTRACT_LIBGCC) >> $@
+ echo "};" >> $@
Index: config/t-linux
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/t-linux,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 t-linux
--- config/t-linux 1998/02/28 03:52:25 1.1.1.2
+++ config/t-linux 1998/12/11 18:10:48
@@ -14,3 +14,9 @@
LIBGCC1 =
CROSS_LIBGCC1 =
LIBGCC1_TEST =
+
+# Make glocal functions in libgcc.a local to the shared library with
+# symbol versioning.
+LIBGCC_MAP=libgcc.map
+EXTRACT_LIBGCC=$(OBJDUMP_FOR_TARGET) --syms libgcc.a | \
+ grep "[ ]g[ ]\+F[ ]" | awk '{print " "$$6";";}' | sort
Index: config/t-linux-gnulibc1
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/t-linux-gnulibc1,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 t-linux-gnulibc1
--- config/t-linux-gnulibc1 1997/08/26 00:20:43 1.1.1.1
+++ config/t-linux-gnulibc1 1998/12/11 14:30:53
@@ -1,2 +1,5 @@
# We are building for the Linux C library 5.
T_CFLAGS = -DUSE_GNULIBC_1
+
+# No symbol versioning.
+LIBGCC_MAP=
Index: config/linux.h
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/linux.h,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 linux.h
--- config/linux.h 1998/05/07 16:44:24 1.1.1.7
+++ config/linux.h 1998/12/11 14:36:16
@@ -103,7 +103,7 @@
%{!profile:%{!ggdb:-lc} %{ggdb:-lg}}}"
#else
#define LIB_SPEC \
- "%{shared: -lc} \
+ "%{shared: -lc --version-script libgcc.map%s} \
%{!shared: %{mieee-fp:-lieee} %{pthread:-lpthread} \
%{profile:-lc_p} %{!profile: -lc}}"
#endif
More information about the Libc-hacker
mailing list