diff mbox

AIX: Filename-based shared library versioning for libgcc_s

Message ID 54608C8C.9050605@ssi-schaefer.com
State New
Headers show

Commit Message

Michael Haubenwallner Nov. 10, 2014, 9:59 a.m. UTC
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/

Comments

David Edelsohn Nov. 10, 2014, 4:06 p.m. UTC | #1
On Mon, Nov 10, 2014 at 4:59 AM, Michael Haubenwallner
<michael.haubenwallner@ssi-schaefer.com> wrote:
>
> 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.

AIX added ELF-like visibility support to XCOFF, which would be
preferred.  Except it was not added in a formal release, like AIX 8.1
and apparently was back-ported to at least AIX 6.1, so its difficult
to phase in the support. One would need to add a configure test for
the feature and not all users are upgrading the system. So one cannot
build and distribute "GCC for AIX 7.1" and know the feature is
available in the system tools.  GCC builds would be incompatible and
object files, libraries, executables created by GCC would be
incompatible.  Basically, a mess.

> While I haven't focussed on nor explicitly tested, I do believe that this
> also solves problems with global C++ constructor/destructor call orders.

Why? There still is the problem of the AIX kernel runtime loader
ordering dependent shared objects.

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

You have not explained how this has any fix / benefit affecting the
problem, other than separate shared and static libraries.  Forcing
runtime linking seems irrelevant.  It was linking shared before and
linking shared after your patch (with runtime linking) so the net
effect is zero.

Again, runtime linking of all global symbols affects performance and
bloats the TOC, making TOC overflow more likely.

I don't have a fundamental objection to the patch, but you have not
really responded to the potential problems and any motivation for this
feature other than greater SVR4 emulation.  For better or worse, AIX
is not SVR4.  Every library built with this option hurts performance
on AIX and potentially causes mysterious TOC overflow errors, which
confuse users unfamiliar with AIX and whose workarounds hurt
performance even more.

Thanks, David
Michael Haubenwallner Nov. 10, 2014, 5:41 p.m. UTC | #2
Am 2014-11-10 17:06, schrieb David Edelsohn:
> On Mon, Nov 10, 2014 at 4:59 AM, Michael Haubenwallner
> <michael.haubenwallner@ssi-schaefer.com> wrote:
>>
>> 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.
> 
> AIX added ELF-like visibility support to XCOFF, which would be
> preferred.  Except it was not added in a formal release, like AIX 8.1
> and apparently was back-ported to at least AIX 6.1, so its difficult
> to phase in the support. One would need to add a configure test for
> the feature and not all users are upgrading the system. So one cannot
> build and distribute "GCC for AIX 7.1" and know the feature is
> available in the system tools.  GCC builds would be incompatible and
> object files, libraries, executables created by GCC would be
> incompatible.  Basically, a mess.

As I've seen the "weak" information on an older AIX 5.3 TL8 already:
Is this visibility support something different than what "nm -l" or "nm -P" shows?

>> While I haven't focussed on nor explicitly tested, I do believe that this
>> also solves problems with global C++ constructor/destructor call orders.
> 
> Why? There still is the problem of the AIX kernel runtime loader
> ordering dependent shared objects.

Feels like I indeed haven't digged deep enough into that topic yet:
To be ignored here then.

>>> 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.
> 
> You have not explained how this has any fix / benefit affecting the
> problem, other than separate shared and static libraries.  Forcing
> runtime linking seems irrelevant.  It was linking shared before and
> linking shared after your patch (with runtime linking) so the net
> effect is zero.

My main reason here is to allow for *filename*-based sharedlib versioning,
which I haven't been able to achive without import files.
In-archive versioning is a pita from a package manager's point of view.

For a second reason:
Due to its Linux-centric history (well, HP-UX and Solaris before), our
application architecture does rely on runtime linking in some corner cases.
This is why I force that for AIX in our development- and runtime-platform,
which is similar to /opt/freeware/, but based on Gentoo Prefix.

For a third reason (maybe I don't have deep enough insight as well):
If I understand correctly, you switched to build libstdc++ without runtime
linking, because of problems when linking statically against the rtl-enabled
libstdc++, no? For this case, by incident "aix-soname" does prevent shared
objects built with runtime linking from being statically linked.

For another reason: I can imaging to provide an rtl_enable'd libc.so as
well, to allow for easier use of memory debuggers that intercept the
malloc/free &co libc calls... But AFAICT these rely on every sharedlib
to be built with runtime linking enabled.

> Again, runtime linking of all global symbols affects performance and
> bloats the TOC, making TOC overflow more likely.

Well, I don't have need to care for performance that much. So do I force
-mminimal-toc as well, where the only reason I have seen so far to avoid
the -bbigtoc linker flag instead is that gdb has problems with that.

> I don't have a fundamental objection to the patch, but you have not
> really responded to the potential problems and any motivation for this
> feature other than greater SVR4 emulation.  For better or worse, AIX
> is not SVR4.  Every library built with this option hurts performance
> on AIX and potentially causes mysterious TOC overflow errors, which
> confuse users unfamiliar with AIX and whose workarounds hurt
> performance even more.

Looking more like SVR4 is nothing more than a nice side effect when doing
filename-based shlib-versioning this proposed way, not a reason by itself.

Which potential problems do you think of? I fail to find more pointers...

Thanks!
/haubi/
David Edelsohn Nov. 11, 2014, 3:02 p.m. UTC | #3
Michael,

Why does the configure change match with p*-*-aix... instead of power*
or powerpc*?  Yes, it's unique and will match, but why make it as
short as possible, which doesn't match other uses?

In your documentation, how are you distinguishing between Dynamic
Linking and Runtime Linking?

Thanks, David


On Mon, Nov 10, 2014 at 12:41 PM, Michael Haubenwallner
<michael.haubenwallner@ssi-schaefer.com> wrote:
>
>
> Am 2014-11-10 17:06, schrieb David Edelsohn:
>> On Mon, Nov 10, 2014 at 4:59 AM, Michael Haubenwallner
>> <michael.haubenwallner@ssi-schaefer.com> wrote:
>>>
>>> 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.
>>
>> AIX added ELF-like visibility support to XCOFF, which would be
>> preferred.  Except it was not added in a formal release, like AIX 8.1
>> and apparently was back-ported to at least AIX 6.1, so its difficult
>> to phase in the support. One would need to add a configure test for
>> the feature and not all users are upgrading the system. So one cannot
>> build and distribute "GCC for AIX 7.1" and know the feature is
>> available in the system tools.  GCC builds would be incompatible and
>> object files, libraries, executables created by GCC would be
>> incompatible.  Basically, a mess.
>
> As I've seen the "weak" information on an older AIX 5.3 TL8 already:
> Is this visibility support something different than what "nm -l" or "nm -P" shows?
>
>>> While I haven't focussed on nor explicitly tested, I do believe that this
>>> also solves problems with global C++ constructor/destructor call orders.
>>
>> Why? There still is the problem of the AIX kernel runtime loader
>> ordering dependent shared objects.
>
> Feels like I indeed haven't digged deep enough into that topic yet:
> To be ignored here then.
>
>>>> 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.
>>
>> You have not explained how this has any fix / benefit affecting the
>> problem, other than separate shared and static libraries.  Forcing
>> runtime linking seems irrelevant.  It was linking shared before and
>> linking shared after your patch (with runtime linking) so the net
>> effect is zero.
>
> My main reason here is to allow for *filename*-based sharedlib versioning,
> which I haven't been able to achive without import files.
> In-archive versioning is a pita from a package manager's point of view.
>
> For a second reason:
> Due to its Linux-centric history (well, HP-UX and Solaris before), our
> application architecture does rely on runtime linking in some corner cases.
> This is why I force that for AIX in our development- and runtime-platform,
> which is similar to /opt/freeware/, but based on Gentoo Prefix.
>
> For a third reason (maybe I don't have deep enough insight as well):
> If I understand correctly, you switched to build libstdc++ without runtime
> linking, because of problems when linking statically against the rtl-enabled
> libstdc++, no? For this case, by incident "aix-soname" does prevent shared
> objects built with runtime linking from being statically linked.
>
> For another reason: I can imaging to provide an rtl_enable'd libc.so as
> well, to allow for easier use of memory debuggers that intercept the
> malloc/free &co libc calls... But AFAICT these rely on every sharedlib
> to be built with runtime linking enabled.
>
>> Again, runtime linking of all global symbols affects performance and
>> bloats the TOC, making TOC overflow more likely.
>
> Well, I don't have need to care for performance that much. So do I force
> -mminimal-toc as well, where the only reason I have seen so far to avoid
> the -bbigtoc linker flag instead is that gdb has problems with that.
>
>> I don't have a fundamental objection to the patch, but you have not
>> really responded to the potential problems and any motivation for this
>> feature other than greater SVR4 emulation.  For better or worse, AIX
>> is not SVR4.  Every library built with this option hurts performance
>> on AIX and potentially causes mysterious TOC overflow errors, which
>> confuse users unfamiliar with AIX and whose workarounds hurt
>> performance even more.
>
> Looking more like SVR4 is nothing more than a nice side effect when doing
> filename-based shlib-versioning this proposed way, not a reason by itself.
>
> Which potential problems do you think of? I fail to find more pointers...
>
> Thanks!
> /haubi/
diff mbox

Patch

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