From: Michael Haubenwallner <michael.haubenwallner@ssi-schaefer.com>
To: David Edelsohn <dje.gcc@gmail.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] AIX: Filename-based shared library versioning for libgcc_s
Date: Mon, 10 Nov 2014 10:01:00 -0000 [thread overview]
Message-ID: <54608C8C.9050605@ssi-schaefer.com> (raw)
In-Reply-To: <CAGWvnynSPN4aAugugjVhZCOBBzTLpVw4VoZGFkef+nQqKAkFWQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3740 bytes --]
Am 2014-11-07 20:52, schrieb David Edelsohn:
> First, please explicitly copy me on AIX or PowerPC patches sent to gcc-patches.
>
> I don't have a fundamental objection to including this option, but
> note that Richi, Honza and I have discovered that using AIX runtime
> linking option interacts badly with some GCC optimizations and can
> result in applications that hang in a loop.
Feels like adding the "aix-soname" linking procedure becomes more important:
> All code on AIX is position independent (PIC) by default. Executables
> and shared libraries essentially are PIE. Because of this, AIX does
> not provide separate "static" libraries and one can link statically
> with a shared library.
>
> Creating a library enabled for runtime linking with -G (-brtl), causes
> a lot of problems, including a newly recognized failure mode. Without
> careful control over AIX symbol export, all global calls with use
> glink code (equivalent to ELF PLTs). This also creates a TOC entry for
> every global call, possibly overflowing the TOC.
About to define "careful control over AIX symbol export":
The symbols listed in the import file are those found in the object files
only, not the ones created at linktime (like __GLOBAL*) or from the static
objects found in libc.a. While I do this in libtool from the beginning here,
I have had a helper script wrapping ld to support '--soname=' for non-libtool
packages, where creating the import file from the final shared object also
included static libc-provided symbols, which turned out as dependency pitfall.
While I haven't focussed on nor explicitly tested, I do believe that this
also solves problems with global C++ constructor/destructor call orders.
> But the main problem is GCC uses aliases and functions declared as
> weak to support some C++ features.
This is another reason why I do force runtime linking for our application,
which uses these C++ features while its main target platform is Linux.
> Functions declared weak interact
> badly with shared libraries compiled for AIX runtime linking and
> linked statically.
The "aix-soname" proposal does not support statically linking shared objects
built with -brtl, but provides lib.a archives either with pure static objects
only (aix-soname=svr4), or with the traditional shared object linked without
-brtl (aix-soname=both).
> This can result in the static binary binding with
> the glink code that loads its own address from the TOC instead of the
> target function, causing endless looping. Honza made some changes to
> GCC code generation for AIX, but there still are problems and I have
> disabled building libstdc++ enabled for runtime linking.
So as long as shared objects built with -brtl actually work for /shared/ linking,
the "aix-soname" linking procedure seems /necessary/ to support all features.
> libgcc always explicitly creates a static library and uses it for
> static linking. All shared libraries for AIX that use this scheme
> (through libtool) would have to follow the same convention to create
> both shared and static libraries. This new option only makes sense if
> it fully emulates SVR4/ELF behavior and always creates both shared .so
> and static .a libraries.
This exactly is what I do in Gentoo Prefix/AIX, with best experience using
gcc-4.2.4 for the moment. As I do provide the complete tool- & library-chain
(like /opt/freeware/), I don't create traditional AIX shared objects at all,
but static only lib.a archives whenever --enable-static is true - which is
the "--with-aix-soname=svr4" use case.
Slightly modified the patch to not create the libgcc_s.a symlink with
aix-soname=svr4 now.
And the Makefile target also has to be libgcc_s.so (via SHLIB_EXT) now.
Thanks!
/haubi/
[-- Attachment #2: 0001-AIX-Filename-based-shlib-versioning-for-libgcc_s.patch --]
[-- Type: text/x-patch, Size: 14627 bytes --]
From ab834013e504ddfbbc0a04aca2bd94ef0b49ace5 Mon Sep 17 00:00:00 2001
From: Michael Haubenwallner <michael.haubenwallner@salomon.at>
Date: Fri, 16 Mar 2012 14:49:20 +0100
Subject: [PATCH] AIX: Filename-based shlib versioning for libgcc_s
2014-11-10 Michael Haubenwallner <michael.haubenwallner@ssi-schaefer.com>
(libgcc_s) Optional filename-based shared library versioning on AIX.
* gcc/doc/install.texi: Describe --with-aix-soname option.
* Makefile.in (with_aix_soname): Define.
* config/rs6000/t-slibgcc-aix: Act upon --with-aix-soname option.
* configure.in: Accept --with-aix-soname=aix|svr4|both option.
* configure: Recreate.
---
gcc/doc/install.texi | 102 +++++++++++++++++++++++++++++++++++++
libgcc/Makefile.in | 1 +
libgcc/config/rs6000/t-slibgcc-aix | 82 +++++++++++++++++++++++------
libgcc/configure | 28 ++++++++++
libgcc/configure.ac | 17 +++++++
5 files changed, 214 insertions(+), 16 deletions(-)
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 3df78ff..161f7e5 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1414,6 +1414,102 @@ particularly useful if you intend to use several versions of GCC in
parallel. This is currently supported by @samp{libgfortran},
@samp{libjava}, @samp{libstdc++}, and @samp{libobjc}.
+@item @anchor{WithAixSoname}--with-aix-soname=@samp{aix}, @samp{svr4} or @samp{both}
+Traditional AIX shared library versioning (versioned @code{Shared Object}
+files as members of unversioned @code{Archive Library} files named
+@samp{lib.a}) causes numerous headaches for package managers. However,
+@code{Import Files} as members of @code{Archive Library} files allow for
+@strong{filename-based versioning} of shared libraries as seen on Linux/SVR4,
+where this is called the "SONAME". But as they prevent static linking,
+@code{Import Files} may be used with @code{Runtime Linking} only, where the
+linker does search for @samp{libNAME.so} before @samp{libNAME.a} library
+filenames with the @samp{-lNAME} linker flag.
+
+@anchor{AixLdCommand}For detailed information please refer to the AIX
+@uref{http://www-01.ibm.com/support/knowledgecenter/search/%22the%20ld%20command%2C%20also%20called%20the%20linkage%20editor%20or%20binder%22,,ld
+Command} reference.
+
+As long as shared library creation is enabled, upon:
+@table @code
+@item --with-aix-soname=aix
+@item --with-aix-soname=both
+ A (traditional AIX) @code{Shared Archive Library} file is created:
+ @itemize @bullet
+ @item using the @samp{libNAME.a} filename scheme
+ @item with the @code{Shared Object} file as archive member named
+ @samp{libNAME.so.V} (except for @samp{libgcc_s}, where the @code{Shared
+ Object} file is named @samp{shr.o} for backwards compatibility), which
+ @itemize @minus
+ @item is used for runtime loading from inside the @samp{libNAME.a} file
+ @item is used for dynamic loading via
+ @code{dlopen("libNAME.a(libNAME.so.V)", RTLD_MEMBER)}
+ @item is used for shared linking
+ @item is used for static linking, so no separate @code{Static Archive
+ Library} file is needed
+ @end itemize
+ @end itemize
+@item --with-aix-soname=both
+@item --with-aix-soname=svr4
+ A (second) @code{Shared Archive Library} file is created:
+ @itemize @bullet
+ @item using the @samp{libNAME.so.V} filename scheme
+ @item with the @code{Shared Object} file as archive member named
+ @samp{shr.o}, which
+ @itemize @minus
+ @item is created with the @code{-G linker flag}
+ @item has the @code{F_LOADONLY} flag set
+ @item is used for runtime loading from inside the @samp{libNAME.so.V} file
+ @item is used for dynamic loading via @code{dlopen("libNAME.so.V(shr.o)",
+ RTLD_MEMBER)}
+ @end itemize
+ @item with the @code{Import File} as archive member named @samp{shr.imp},
+ which
+ @itemize @minus
+ @item refers to @samp{libNAME.so.V(shr.o)} as the "SONAME", to be recorded
+ in the @code{Loader Section} of subsequent binaries
+ @item indicates whether @samp{libNAME.so.V(shr.o)} is 32 or 64 bit
+ @item lists all the public symbols exported by @samp{lib.so.V(shr.o)},
+ eventually decorated with the @code{@samp{weak} Keyword}
+ @item is necessary for shared linking against @samp{lib.so.V(shr.o)}
+ @end itemize
+ @end itemize
+ A symbolic link using the @samp{libNAME.so} filename scheme is created:
+ @itemize @bullet
+ @item pointing to the @samp{libNAME.so.V} @code{Shared Archive Library} file
+ @item to permit the @code{ld Command} to find @samp{lib.so.V(shr.imp)} via
+ the @samp{-lNAME} argument (requires @code{Runtime Linking} to be enabled)
+ @item to permit dynamic loading of @samp{lib.so.V(shr.o)} without the need
+ to specify the version number via @code{dlopen("libNAME.so(shr.o)",
+ RTLD_MEMBER)}
+ @end itemize
+@end table
+
+As long as static library creation is enabled, upon:
+@table @code
+@item --with-aix-soname=svr4
+ A @code{Static Archive Library} is created:
+ @itemize @bullet
+ @item using the @samp{libNAME.a} filename scheme
+ @item with all the @code{Static Object} files as archive members, which
+ @itemize @minus
+ @item are used for static linking
+ @end itemize
+ @end itemize
+@end table
+
+While the aix-soname=@samp{svr4} option does not create @code{Shared Object}
+files as members of unversioned @code{Archive Library} files any more, package
+managers still are responsible to
+@uref{./specific.html#TransferAixShobj,,transfer} @code{Shared Object} files
+found as member of a previously installed unversioned @code{Archive Library}
+file into the newly installed @code{Archive Library} file with the same
+filename.
+
+@option{--with-aix-soname} is currently supported by @samp{libgcc_s} only, so
+this option is still experimental and not for normal use yet.
+
+Default is the traditional behaviour @option{--with-aix-soname=@samp{aix}}.
+
@item --enable-languages=@var{lang1},@var{lang2},@dots{}
Specify that only a particular subset of compilers and
their runtime libraries should be built. For a list of valid values for
@@ -3847,6 +3943,7 @@ APAR IY26685 (AIX 4.3) or APAR IY25528 (AIX 5.1). It also requires a
fix for another AIX Assembler bug and a co-dependent AIX Archiver fix
referenced as APAR IY53606 (AIX 5.2) or as APAR IY54774 (AIX 5.1)
+@anchor{TransferAixShobj}
@samp{libstdc++} in GCC 3.4 increments the major version number of the
shared object and GCC installation places the @file{libstdc++.a}
shared library in a common location which will overwrite the and GCC
@@ -3877,6 +3974,11 @@ Archive the runtime-only shared object in the GCC 3.4
% ar -q libstdc++.a libstdc++.so.4 libstdc++.so.5
@end smallexample
+Eventually, the
+@uref{./configure.html#WithAixSoname,,@option{--with-aix-soname=svr4}}
+configure option may drop the need for this procedure for libraries that
+support it.
+
Linking executables and shared libraries may produce warnings of
duplicate symbols. The assembly files generated by GCC for AIX always
have included multiple symbol definitions for certain global variable
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 357e15c..1982653 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -42,6 +42,7 @@ decimal_float = @decimal_float@
enable_vtable_verify = @enable_vtable_verify@
enable_decimal_float = @enable_decimal_float@
fixed_point = @fixed_point@
+with_aix_soname = @with_aix_soname@
host_noncanonical = @host_noncanonical@
target_noncanonical = @target_noncanonical@
diff --git a/libgcc/config/rs6000/t-slibgcc-aix b/libgcc/config/rs6000/t-slibgcc-aix
index 288c2c9..2de307e 100644
--- a/libgcc/config/rs6000/t-slibgcc-aix
+++ b/libgcc/config/rs6000/t-slibgcc-aix
@@ -16,24 +16,74 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-# Build a shared libgcc library.
-SHLIB_EXT = .a
-SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
- -Wl,-bE:@shlib_map_file@ -o @multilib_dir@/shr.o \
- @multilib_flags@ @shlib_objs@ -lc \
- `case @multilib_dir@ in \
- *pthread*) echo -L$(TARGET_SYSTEM_ROOT)/usr/lib/threads -lpthreads -lc_r $(TARGET_SYSTEM_ROOT)/usr/lib/libc.a ;; \
- *) echo -lc ;; esac` ; \
- rm -f @multilib_dir@/tmp-@shlib_base_name@.a ; \
- $(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-@shlib_base_name@.a \
- @multilib_dir@/shr.o ; \
- mv @multilib_dir@/tmp-@shlib_base_name@.a \
- @multilib_dir@/@shlib_base_name@.a ; \
- rm -f @multilib_dir@/shr.o
+# Build a shared libgcc library according to --with-aix-soname selection:
+# aix-soname=aix:
+# libgcc_s.a(shr.o) # traditional (-bnortl)
+#
+# aix-soname=both:
+# libgcc_s.a(shr.o) # traditional (-bnortl)
+# libgcc_s.so.1(shrXX.o,shrXX.imp) # the SONAME (-G)
+# libgcc_s.so -> libgcc_s.so.1 # the symlink
+#
+# aix-soname=svr4:
+# libgcc_s.so.1(shrXX.o,shrXX.imp) # the SONAME (-G)
+# libgcc_s.so -> libgcc_s.so.1 # the symlink
+SHLIB_EXT_aix = .a
+SHLIB_EXT_both = .so
+SHLIB_EXT_svr4 = .so
+SHLIB_EXT = $(SHLIB_EXT_$(with_aix_soname))
+SHLIB_SOVERSION = 1
+SHLIB_SONAME = @shlib_base_name@.so.$(SHLIB_SOVERSION)
+SHLIB_LINK = \
+ if test svr4 != $(with_aix_soname) ; then \
+ $(CC) $(LIBGCC2_CFLAGS) -shared -Wl,-bnortl -nodefaultlibs \
+ -Wl,-bE:@shlib_map_file@ -o @multilib_dir@/shr.o \
+ @multilib_flags@ @shlib_objs@ -lc \
+ `case @multilib_dir@ in \
+ *pthread*) echo -L$(TARGET_SYSTEM_ROOT)/usr/lib/threads -lpthreads -lc_r $(TARGET_SYSTEM_ROOT)/usr/lib/libc.a ;; \
+ *) echo -lc ;; esac` ; \
+ rm -f @multilib_dir@/tmp-@shlib_base_name@.a ; \
+ $(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-@shlib_base_name@.a \
+ @multilib_dir@/shr.o ; \
+ mv @multilib_dir@/tmp-@shlib_base_name@.a \
+ @multilib_dir@/@shlib_base_name@.a ; \
+ rm -f @multilib_dir@/shr.o ; \
+ fi ; \
+ if test aix != $(with_aix_soname) ; then \
+ case @multilib_dir@ in *64*) shr='shr_64' ;; *) shr='shr' ;; esac ; \
+ $(CC) $(LIBGCC2_CFLAGS) -shared -Wl,-G -nodefaultlibs \
+ -Wl,-bE:@shlib_map_file@ -o @multilib_dir@/$$shr.o \
+ @multilib_flags@ @shlib_objs@ -lc \
+ `case @multilib_dir@ in \
+ *pthread*) echo -L$(TARGET_SYSTEM_ROOT)/usr/lib/threads -lpthreads -lc_r $(TARGET_SYSTEM_ROOT)/usr/lib/libc.a ;; \
+ *) echo -lc ;; esac` ; \
+ $(STRIP_FOR_TARGET) -X32_64 -e @multilib_dir@/$$shr.o ; \
+ { echo "\#! $(SHLIB_SONAME)($$shr.o)" ; \
+ case @multilib_dir@ in *64*) echo '\# 64' ;; *) echo '\# 32' ;; esac ; \
+ cat @shlib_map_file@ ; \
+ } > @multilib_dir@/$$shr.imp ; \
+ rm -f @multilib_dir@/tmp-$(SHLIB_SONAME) ; \
+ $(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-$(SHLIB_SONAME) \
+ @multilib_dir@/$$shr.imp @multilib_dir@/$$shr.o ; \
+ mv @multilib_dir@/tmp-$(SHLIB_SONAME) \
+ @multilib_dir@/$(SHLIB_SONAME) ; \
+ rm -f @multilib_dir@/@shlib_base_name@.so ; \
+ $(LN_S) $(SHLIB_SONAME) @multilib_dir@/@shlib_base_name@.so ; \
+ rm -f @multilib_dir@/$$shr.imp @multilib_dir@/$$shr.o ; \
+ fi
SHLIB_INSTALL = \
$(mkinstalldirs) $(DESTDIR)$(slibdir)@shlib_slibdir_qual@; \
- $(INSTALL_DATA) @multilib_dir@/@shlib_base_name@.a \
- $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/
+ if test svr4 != $(with_aix_soname) ; then \
+ $(INSTALL_DATA) @multilib_dir@/@shlib_base_name@.a \
+ $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/ ; \
+ fi ; \
+ if test aix != $(with_aix_soname) ; then \
+ $(INSTALL_DATA) @multilib_dir@/$(SHLIB_SONAME) \
+ $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/ ; \
+ rm -f $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/@shlib_base_name@.so ; \
+ $(LN_S) $(SHLIB_SONAME) \
+ $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/@shlib_base_name@.so ; \
+ fi
SHLIB_LIBS = -lc `case @multilib_dir@ in *pthread*) echo -lpthread ;; esac`
SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
SHLIB_MAPFILES = libgcc-std.ver
diff --git a/libgcc/configure b/libgcc/configure
index 3f53aaf..4f8776f 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -609,6 +609,7 @@ build_os
build_vendor
build_cpu
build
+with_aix_soname
enable_vtable_verify
enable_shared
libgcc_topdir
@@ -658,6 +659,7 @@ with_cross_host
with_ld
enable_shared
enable_vtable_verify
+with_aix_soname
enable_version_specific_runtime_libs
with_slibdir
enable_maintainer_mode
@@ -1316,6 +1318,9 @@ Optional Packages:
--with-target-subdir=SUBDIR Configuring in a subdirectory for target
--with-cross-host=HOST Configuring with a cross compiler
--with-ld arrange to use the specified ld (full pathname)
+ --with-aix-soname=aix|svr4|both
+ shared library versioning (aka "SONAME") variant to
+ provide on AIX
--with-slibdir=DIR shared libraries in DIR LIBDIR
--with-build-libsubdir=DIR Directory where to find libraries for build system
--with-system-libunwind use installed libunwind
@@ -2165,6 +2170,29 @@ fi
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+ withval=$with_aix_soname; case "${host}:${enable_shared}" in
+ p*-*-aix[5-9]*:yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide for shared libgcc" >&5
+$as_echo_n "checking which variant of shared library versioning to provide for shared libgcc... " >&6; }
+ case ${withval} in
+ aix|svr4|both) ;;
+ *) as_fn_error "Unknown argument to --with-aix-soname" "$LINENO" 5;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
+$as_echo "$withval" >&6; }
+ ;;
+ *) with_aix_soname=aix ;;
+ esac
+
+else
+ with_aix_soname=aix
+fi
+
+
+
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 79d0ea4..edd9fd5 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -76,6 +76,23 @@ AC_ARG_ENABLE(vtable-verify,
[enable_vtable_verify=no])
AC_SUBST(enable_vtable_verify)
+AC_ARG_WITH(aix-soname,
+[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+ [shared library versioning (aka "SONAME") variant to provide on AIX])],
+[case "${host}:${enable_shared}" in
+ p*-*-aix[[5-9]]*:yes)
+ AC_MSG_CHECKING([which variant of shared library versioning to provide for shared libgcc])
+ case ${withval} in
+ aix|svr4|both) ;;
+ *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]);;
+ esac
+ AC_MSG_RESULT($withval)
+ ;;
+ *) with_aix_soname=aix ;;
+ esac
+], [with_aix_soname=aix])
+AC_SUBST(with_aix_soname)
+
GCC_PICFLAG
AC_SUBST(PICFLAG)
--
1.8.5.5
next prev parent reply other threads:[~2014-11-10 9:59 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-07 19:52 David Edelsohn
2014-11-10 10:01 ` Michael Haubenwallner [this message]
2014-11-10 16:17 ` David Edelsohn
2014-11-10 18:01 ` Michael Haubenwallner
2014-11-11 15:03 ` David Edelsohn
2014-11-11 15:44 ` Michael Haubenwallner
2014-11-25 14:25 ` David Edelsohn
2014-12-05 12:56 ` Michael Haubenwallner
2014-12-05 14:06 ` David Edelsohn
-- strict thread matches above, loose matches on Subject: below --
2014-11-07 12:58 Michael Haubenwallner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54608C8C.9050605@ssi-schaefer.com \
--to=michael.haubenwallner@ssi-schaefer.com \
--cc=dje.gcc@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).