public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] AIX: Filename-based shared library versioning for libgcc_s
@ 2014-11-07 12:58 Michael Haubenwallner
  0 siblings, 0 replies; 10+ messages in thread
From: Michael Haubenwallner @ 2014-11-07 12:58 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1492 bytes --]

Hi David (et al)!

The upcoming initial release of gcc-5 feels like a good opportunity for the
AIX port of gcc to introduce optional support for the important Linux-known
feature I'd call "filename-based shared library versioning", aka. SONAME.

We have had some discussion in https://gcc.gnu.org/PR52623 already, and I've
found it most descriptive for the configure option to read:
  "--with-aix-soname=aix|svr4|both"
where 'aix' is the current situation (default), 'svr4' the new variant only,
and 'both' for backwards compatibility - outlined in the install.texi diff.

To allow for backwards compatibility at all, I'd provide the 'svr4' variant
with 'runtime linking' enabled only, as this is true for Linux/SVR4 anyway.

As I'm using the 'svr4' variant for a quite large portable C/C++ application
already (via Gentoo Prefix) on AIX, I can tell this kind of filename-based
versioning of shared libraries does really work as expected.

Besides adding some documentation, attached patch is for libgcc_s only, as for
other libraries I'd prefer to get the "--with-aix-soname" support via upstream
libtool, where I don't have the 'both'-support ready yet. I have to rebase
the existing 'svr4' patches anyway - currently these do "--enable-aix-soname",
found in https://github.com/haubi/libtool/compare/aix-soname

But even if not ready for normal use yet, I'd love to see the gcc-5 release
start introducing 'aix-soname' - allowing for "more Linux with AIX" ;)

Thoughts?

Thank you!
/haubi/

[-- Attachment #2: 0001-AIX-Filename-based-shlib-versioning-for-libgcc_s.patch --]
[-- Type: text/x-patch, Size: 15009 bytes --]

From 9f6fd44eddf3b0c43f0472c172d6420b8b91b7db 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

2012-11-05  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: Support filename-based versioning.
	* 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 |  86 +++++++++++++++++++++++++------
 libgcc/configure                   |  28 ++++++++++
 libgcc/configure.ac                |  17 +++++++
 5 files changed, 219 insertions(+), 15 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..a36700b 100644
--- a/libgcc/config/rs6000/t-slibgcc-aix
+++ b/libgcc/config/rs6000/t-slibgcc-aix
@@ -16,24 +16,80 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-# Build a shared libgcc library.
+# Build a shared libgcc library according to --with-aix-soname selection:
+# aix-soname=aix:
+#       libgcc_s.a(shr.o)                # traditional
+#
+# aix-soname=both:
+#       libgcc_s.so.1(shrXX.o,shrXX.imp) # the SONAME
+#       libgcc_s.so -> libgcc_s.so.1     # the symlink
+#       libgcc_s.a(shr.o)                # traditional
+#
+# aix-soname=svr4:
+#       libgcc_s.so.1(shrXX.o,shrXX.imp) # the SONAME
+#       libgcc_s.so -> libgcc_s.so.1     # the symlink
+#       libgcc_s.a -> libgcc_s.so.1      # compat, no static libgcc_s anyway
 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
+SHLIB_SOVERSION = 1
+SHLIB_SONAME = @shlib_base_name@.so.$(SHLIB_SOVERSION)
+SHLIB_LINK = \
+	if test svr4 != $(with_aix_soname) ; then \
+	  $(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@$(SHLIB_EXT) ; \
+	  $(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-@shlib_base_name@$(SHLIB_EXT) \
+	    @multilib_dir@/shr.o ; \
+	  mv @multilib_dir@/tmp-@shlib_base_name@$(SHLIB_EXT) \
+	     @multilib_dir@/@shlib_base_name@$(SHLIB_EXT) ; \
+	fi ; \
+	case @multilib_dir@ in *64*) shr='shr_64' ;; *) shr='shr' ;; esac ; \
+	if test aix != $(with_aix_soname) ; then \
+	  $(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 ; \
+	fi ; \
+	if test svr4 = $(with_aix_soname) ; then \
+	  rm -f @multilib_dir@/@shlib_base_name@$(SHLIB_EXT) ; \
+	  $(LN_S) $(SHLIB_SONAME) @multilib_dir@/@shlib_base_name@$(SHLIB_EXT) ; \
+	fi ; \
+	rm -f @multilib_dir@/$$shr.imp @multilib_dir@/$$shr.o @multilib_dir@/shr.o
 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 ; \
+	if test svr4 = $(with_aix_soname) ; then \
+	  rm -f $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/@shlib_base_name@.a ; \
+	  $(LN_S) $(SHLIB_SONAME) \
+		  $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/@shlib_base_name@.a ; \
+	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..eb830a7 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
+ powerpc*-*-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..c9f6938 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
+ powerpc*-*-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


^ permalink raw reply	[flat|nested] 10+ messages in thread
* Re: [PATCH] AIX: Filename-based shared library versioning for libgcc_s
@ 2014-11-07 19:52 David Edelsohn
  2014-11-10 10:01 ` Michael Haubenwallner
  0 siblings, 1 reply; 10+ messages in thread
From: David Edelsohn @ 2014-11-07 19:52 UTC (permalink / raw)
  To: Michael Haubenwallner; +Cc: GCC Patches

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.

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.

But the main problem is GCC uses aliases and functions declared as
weak to support some C++ features. Functions declared weak interact
badly with shared libraries compiled for AIX runtime linking and
linked statically.  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.

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.

Thanks, David

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-12-05 14:06 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-07 12:58 [PATCH] AIX: Filename-based shared library versioning for libgcc_s Michael Haubenwallner
2014-11-07 19:52 David Edelsohn
2014-11-10 10:01 ` Michael Haubenwallner
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

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