Document and fix -r (partial linking)

Message ID 5835862.YDeY9hZc7r@twilight
State New
Headers show
Series
  • Document and fix -r (partial linking)
Related show

Commit Message

Allan Sandfeld Jensen Aug. 1, 2018, 4:14 p.m.
The option has existed and been working for years,
make sure it implies the right extra options, and list
it in the documentation.

2018-08-01 Allan Sandfeld Jensen <allan.jensen@qt.io>

gcc/doc

    * invoke.texi: Document -r

gcc/
    * gcc.c: Correct default specs for -r
---
 gcc/doc/invoke.texi | 7 ++++++-
 gcc/gcc.c           | 6 +++---
 2 files changed, 9 insertions(+), 4 deletions(-)

Comments

Joseph Myers Aug. 1, 2018, 4:32 p.m. | #1
On Wed, 1 Aug 2018, Allan Sandfeld Jensen wrote:

> gcc/

>     * gcc.c: Correct default specs for -r


I don't follow why your changes (which would need describing for each 
individual spec changed) are corrections.

>  /* config.h can define LIB_SPEC to override the default libraries.  */

>  #ifndef LIB_SPEC

> -#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"

> +#define LIB_SPEC "%{!shared|!r:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"

>  #endif


'!' binds more closely than '|' in specs.  That is, !shared|!r means the 
following specs are used unless both -shared and -r are specified, which 
seems nonsensical to me.  I'd expect something more like "shared|r:;" to 
expand to nothing if either -shared or -r is passed and to what follows if 
neither is passed.

And that ignores that this LIB_SPEC value in gcc.c is largely irrelevant, 
as it's generally overridden by targets - and normally for targets using 
ELF shared libraries, for example, -lc *does* have to be used when linking 
with -shared.

I think you're changing the wrong place for this.  If you want -r to be 
usable with GCC without using -nostdlib (which is an interesting 
question), you actually need to change LINK_COMMAND_SPEC (also sometimes 
overridden for targets) to handle -r more like -nostdlib -nostartfiles.

> -#define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} "

> +#define LINK_PIE_SPEC "%{static|shared|r|ar:;" PIE_SPEC ":" LD_PIE_SPEC "} "


What's this "-ar" option you're handling here?

-- 
Joseph S. Myers
joseph@codesourcery.com
Rainer Orth Aug. 1, 2018, 4:39 p.m. | #2
Hi Allan,

> The option has existed and been working for years,

> make sure it implies the right extra options, and list

> it in the documentation.


this is way incomplete: you are only fixing the default versions of the
various specs in gcc.c, while there are many others that also need
fixing in gcc/config.  Without this, the new documentation is completely
misleading.

> 2018-08-01 Allan Sandfeld Jensen <allan.jensen@qt.io>

>

> gcc/doc

>

>     * invoke.texi: Document -r


Lacks which section you are changing.  Besides, this needs to end in a
full stop.

> gcc/

>     * gcc.c: Correct default specs for -r


You need to include which macros you changed in what way.  Best read the
GNU coding standards for the full details.

Don't misunderstand me: I'd very much like to have gcc -r work as it
should, just misleading users into thinking it always does when with
your current patch only few targets work right is ultimtely a
disservice.

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
Allan Sandfeld Jensen Aug. 1, 2018, 5:12 p.m. | #3
On Mittwoch, 1. August 2018 18:32:30 CEST Joseph Myers wrote:
> On Wed, 1 Aug 2018, Allan Sandfeld Jensen wrote:

> > gcc/

> > 

> >     * gcc.c: Correct default specs for -r

> 

> I don't follow why your changes (which would need describing for each

> individual spec changed) are corrections.

> 

> >  /* config.h can define LIB_SPEC to override the default libraries.  */

> >  #ifndef LIB_SPEC

> > 

> > -#define LIB_SPEC "%{!shared:%{g*:-lg}

> > %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" +#define LIB_SPEC

> > "%{!shared|!r:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"> 

> >  #endif

> 

> '!' binds more closely than '|' in specs.  That is, !shared|!r means the

> following specs are used unless both -shared and -r are specified, which

> seems nonsensical to me.  I'd expect something more like "shared|r:;" to

> expand to nothing if either -shared or -r is passed and to what follows if

> neither is passed.

> 

> And that ignores that this LIB_SPEC value in gcc.c is largely irrelevant,

> as it's generally overridden by targets - and normally for targets using

> ELF shared libraries, for example, -lc *does* have to be used when linking

> with -shared.

> 

> I think you're changing the wrong place for this.  If you want -r to be

> usable with GCC without using -nostdlib (which is an interesting

> question), you actually need to change LINK_COMMAND_SPEC (also sometimes

> overridden for targets) to handle -r more like -nostdlib -nostartfiles.

> 

Ok, thanks for the information, I will investigate that. 

> > -#define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} "

> > +#define LINK_PIE_SPEC "%{static|shared|r|ar:;" PIE_SPEC ":" LD_PIE_SPEC

> > "} "

> What's this "-ar" option you're handling here?


Dead code from a previous more ambitious version of the patch. I will remove.

`Allan
Allan Sandfeld Jensen Aug. 3, 2018, 11:56 a.m. | #4
On Mittwoch, 1. August 2018 18:32:30 CEST Joseph Myers wrote:
> On Wed, 1 Aug 2018, Allan Sandfeld Jensen wrote:

> > gcc/

> > 

> >     * gcc.c: Correct default specs for -r

> 

> I don't follow why your changes (which would need describing for each

> individual spec changed) are corrections.

> 

> >  /* config.h can define LIB_SPEC to override the default libraries.  */

> >  #ifndef LIB_SPEC

> > 

> > -#define LIB_SPEC "%{!shared:%{g*:-lg}

> > %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" +#define LIB_SPEC

> > "%{!shared|!r:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"> 

> >  #endif

> 

> '!' binds more closely than '|' in specs.  That is, !shared|!r means the

> following specs are used unless both -shared and -r are specified, which

> seems nonsensical to me.  I'd expect something more like "shared|r:;" to

> expand to nothing if either -shared or -r is passed and to what follows if

> neither is passed.

> 

> And that ignores that this LIB_SPEC value in gcc.c is largely irrelevant,

> as it's generally overridden by targets - and normally for targets using

> ELF shared libraries, for example, -lc *does* have to be used when linking

> with -shared.

> 

> I think you're changing the wrong place for this.  If you want -r to be

> usable with GCC without using -nostdlib (which is an interesting

> question), you actually need to change LINK_COMMAND_SPEC (also sometimes

> overridden for targets) to handle -r more like -nostdlib -nostartfiles.

> 

Okay, so like this?
From 9de68f2ef0b77a0c0bcf0d83232e7fc34b006406 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>

Date: Wed, 1 Aug 2018 18:07:05 +0200
Subject: [PATCH] Fix and document -r option

The option has existed and been working for years,
make sure it implies the right extra options, and list
it in the documentation.

2018-07-29 Allan Sandfeld Jensen <allan.jensen@qt.io>

gcc/doc

    * invoke.texi: Document -r

gcc/
    * gcc.c (LINK_COMMAND_SPEC): Handle -r like -nostdlib
    * config/darwin.h (LINK_COMMAND_SPEC): Handle -r like -nostdlib
---
 gcc/config/darwin.h | 8 ++++----
 gcc/doc/invoke.texi | 7 ++++++-
 gcc/gcc.c           | 6 +++---
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 980ad9b4057..6ad657a4958 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -178,20 +178,20 @@ extern GTY(()) int darwin_ms_struct;
    "%X %{s} %{t} %{Z} %{u*} \
     %{e*} %{r} \
     %{o*}%{!o:-o a.out} \
-    %{!nostdlib:%{!nostartfiles:%S}} \
+    %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
     %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): \
       %{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } \
     %{fgnu-tm: \
       %{static|static-libgcc|static-libstdc++|static-libgfortran: libitm.a%s; : -litm } } \
-    %{!nostdlib:%{!nodefaultlibs:\
+    %{!nostdlib:%{!r:%{!nodefaultlibs:\
       %{%:sanitize(address): -lasan } \
       %{%:sanitize(undefined): -lubsan } \
       %(link_ssp) \
       " DARWIN_EXPORT_DYNAMIC " %<rdynamic \
       %(link_gcc_c_sequence) \
-    }}\
-    %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}"
+    }}}\
+    %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*} %{F*} }}}}}}}"
 
 #define DSYMUTIL "\ndsymutil"
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6047d82065a..7da30bd9d99 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -518,7 +518,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Link Options,,Options for Linking}.
 @gccoptlist{@var{object-file-name}  -fuse-ld=@var{linker}  -l@var{library} @gol
 -nostartfiles  -nodefaultlibs  -nolibc  -nostdlib @gol
--pie  -pthread  -rdynamic @gol
+-pie  -pthread  -r  -rdynamic @gol
 -s  -static -static-pie -static-libgcc  -static-libstdc++ @gol
 -static-libasan  -static-libtsan  -static-liblsan  -static-libubsan @gol
 -shared  -shared-libgcc  -symbolic @gol
@@ -12444,6 +12444,11 @@ x86 Cygwin and MinGW targets.  On some targets this option also sets
 flags for the preprocessor, so it should be used consistently for both
 compilation and linking.
 
+@item -r
+@opindex r
+Produce a relocatable object as output. This is also known as partial
+linking.
+
 @item -rdynamic
 @opindex rdynamic
 Pass the flag @option{-export-dynamic} to the ELF linker, on targets
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 780d4859ef3..687903cb1be 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1041,7 +1041,7 @@ proper position among the other output files.  */
     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    "%X %{o*} %{e*} %{N} %{n} %{r}\
-    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \
+    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
     %{static|no-pie|static-pie:} %@{L*} %(mfwrap) %(link_libgcc) " \
     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o "" \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
@@ -1049,8 +1049,8 @@ proper position among the other output files.  */
     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
     %(mflib) " STACK_SPLIT_SPEC "\
     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
-    %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
-    %{!nostdlib:%{!nostartfiles:%E}} %{T*}  \n%(post_link) }}}}}}"
+    %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\
+    %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*}  \n%(post_link) }}}}}}"
 #endif
 
 #ifndef LINK_LIBGCC_SPEC
-- 
2.17.0
Iain Sandoe Aug. 3, 2018, 1:27 p.m. | #5
Hi Allan,

> On 3 Aug 2018, at 12:56, Allan Sandfeld Jensen <linux@carewolf.com> wrote:

> 

> On Mittwoch, 1. August 2018 18:32:30 CEST Joseph Myers wrote:

>> On Wed, 1 Aug 2018, Allan Sandfeld Jensen wrote:

>>> gcc/

> 


> 2018-07-29 Allan Sandfeld Jensen <allan.jensen@qt.io>

> 

> gcc/doc

> 

>    * invoke.texi: Document -r

> 

> gcc/

>    * gcc.c (LINK_COMMAND_SPEC): Handle -r like -nostdlib

>    * config/darwin.h (LINK_COMMAND_SPEC): Handle -r like -nostdlib

> ---

> gcc/config/darwin.h | 8 ++++----

> gcc/doc/invoke.texi | 7 ++++++-

> gcc/gcc.c           | 6 +++---

> 3 files changed, 13 insertions(+), 8 deletions(-)

> 

> diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h

> index 980ad9b4057..6ad657a4958 100644

> --- a/gcc/config/darwin.h

> +++ b/gcc/config/darwin.h

> @@ -178,20 +178,20 @@ extern GTY(()) int darwin_ms_struct;

>    "%X %{s} %{t} %{Z} %{u*} \

>     %{e*} %{r} \

>     %{o*}%{!o:-o a.out} \

> -    %{!nostdlib:%{!nostartfiles:%S}} \

> +    %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \

>     %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \

>     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): \

>       %{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } \

>     %{fgnu-tm: \

>       %{static|static-libgcc|static-libstdc++|static-libgfortran: libitm.a%s; : -litm } } \

> -    %{!nostdlib:%{!nodefaultlibs:\

> +    %{!nostdlib:%{!r:%{!nodefaultlibs:\

>       %{%:sanitize(address): -lasan } \

>       %{%:sanitize(undefined): -lubsan } \

>       %(link_ssp) \

>       " DARWIN_EXPORT_DYNAMIC " %<rdynamic \

>       %(link_gcc_c_sequence) \

> -    }}\

> -    %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}"

> +    }}}\

> +    %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*} %{F*} }}}}}}}"

> 

> #define DSYMUTIL "\ndsymutil”


The Darwin part looks reasonable to me.
Thanks for doing this,
Iain
Allan Sandfeld Jensen Aug. 11, 2018, 9:01 a.m. | #6
On Freitag, 3. August 2018 13:56:12 CEST Allan Sandfeld Jensen wrote:
> On Mittwoch, 1. August 2018 18:32:30 CEST Joseph Myers wrote:

> > On Wed, 1 Aug 2018, Allan Sandfeld Jensen wrote:

> > > gcc/

> > > 

> > >     * gcc.c: Correct default specs for -r

> > 

> > I don't follow why your changes (which would need describing for each

> > individual spec changed) are corrections.

> > 

> > >  /* config.h can define LIB_SPEC to override the default libraries.  */

> > >  #ifndef LIB_SPEC

> > > 

> > > -#define LIB_SPEC "%{!shared:%{g*:-lg}

> > > %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}" +#define LIB_SPEC

> > > "%{!shared|!r:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}">

> > > 

> > >  #endif

> > 

> > '!' binds more closely than '|' in specs.  That is, !shared|!r means the

> > following specs are used unless both -shared and -r are specified, which

> > seems nonsensical to me.  I'd expect something more like "shared|r:;" to

> > expand to nothing if either -shared or -r is passed and to what follows if

> > neither is passed.

> > 

> > And that ignores that this LIB_SPEC value in gcc.c is largely irrelevant,

> > as it's generally overridden by targets - and normally for targets using

> > ELF shared libraries, for example, -lc *does* have to be used when linking

> > with -shared.

> > 

> > I think you're changing the wrong place for this.  If you want -r to be

> > usable with GCC without using -nostdlib (which is an interesting

> > question), you actually need to change LINK_COMMAND_SPEC (also sometimes

> > overridden for targets) to handle -r more like -nostdlib -nostartfiles.

> 

> Okay, so like this?



Any further comments or corrections to updated patch in the parent message?

'Allan
Joseph Myers Aug. 20, 2018, 10:38 p.m. | #7
On Fri, 3 Aug 2018, Allan Sandfeld Jensen wrote:

> > I think you're changing the wrong place for this.  If you want -r to be

> > usable with GCC without using -nostdlib (which is an interesting

> > question), you actually need to change LINK_COMMAND_SPEC (also sometimes

> > overridden for targets) to handle -r more like -nostdlib -nostartfiles.

> > 

> Okay, so like this?


Could you confirm if this has passed a bootstrap and testsuite run, with 
no testsuite regressions compared to GCC without the patch applied?  I 
think it looks mostly OK (modulo ChangeLog rewrites and a missing second 
space after '.' in the manual change) but I'd like to make sure it's 
passed the usual testing before preparing it for commit.

-- 
Joseph S. Myers
joseph@codesourcery.com
Iain Sandoe Aug. 23, 2018, 7:47 a.m. | #8
> On 20 Aug 2018, at 23:38, Joseph Myers <joseph@codesourcery.com> wrote:

> 

> On Fri, 3 Aug 2018, Allan Sandfeld Jensen wrote:

> 

>>> I think you're changing the wrong place for this.  If you want -r to be

>>> usable with GCC without using -nostdlib (which is an interesting

>>> question), you actually need to change LINK_COMMAND_SPEC (also sometimes

>>> overridden for targets) to handle -r more like -nostdlib -nostartfiles.

>>> 

>> Okay, so like this?

> 

> Could you confirm if this has passed a bootstrap and testsuite run, with 

> no testsuite regressions compared to GCC without the patch applied?  I 

> think it looks mostly OK (modulo ChangeLog rewrites and a missing second 

> space after '.' in the manual change) but I'd like to make sure it's 

> passed the usual testing before preparing it for commit.


I have bootstrapped the Darwin part (several times now), I’d say it’s “correct by
examination” and that if there’s test-suite fallout, that indicates a latent problem.
(I don’t think there is - but the Darwin test output is rather noisy at the moment).

But I think gcc/gcc.c patch is incomplete, since it doesn’t account for the
 VTABLE_VERIFICATION_SPEC, SANITIZER_EARLY_SPEC, SANITIZER_SPEC.
 
How have you determined that the patch is doing what you expect?

(it might be nice if there was some specific testsuite entry than makes sure this is
 working so that if people make a mistake in the future, it gets caught).

===

Joseph: As a side-comment, is there a reason that we don’t exclude gomp/itm/fortran/gcov
from the link for -nostdlib / -nodefaultlib?

If we are relying on the lib self-specs for this, then we’re not succeeding since the
one we build at the moment don’t include those clauses.

thanks
Iain
Joseph Myers Aug. 23, 2018, 9:24 p.m. | #9
On Thu, 23 Aug 2018, Iain Sandoe wrote:

> Joseph: As a side-comment, is there a reason that we don’t exclude 

> gomp/itm/fortran/gcov from the link for -nostdlib / -nodefaultlib?

> 

> If we are relying on the lib self-specs for this, then we’re not 

> succeeding since the one we build at the moment don’t include those 

> clauses.


Well, fortran/gfortranspec.c for example has

        case OPT_nostdlib:
        case OPT_nodefaultlibs:
        case OPT_c:
        case OPT_S:
        case OPT_fsyntax_only:
        case OPT_E:
          /* These options disable linking entirely or linking of the
             standard libraries.  */
          library = 0;
          break;

and only uses libgfortran.spec if (library).  So it's certainly meant to 
avoid linking with libgfortran or its dependencies if -nostdlib.

-- 
Joseph S. Myers
joseph@codesourcery.com
Allan Sandfeld Jensen Aug. 26, 2018, 10:34 a.m. | #10
On Dienstag, 21. August 2018 00:38:58 CEST Joseph Myers wrote:
> On Fri, 3 Aug 2018, Allan Sandfeld Jensen wrote:

> > > I think you're changing the wrong place for this.  If you want -r to be

> > > usable with GCC without using -nostdlib (which is an interesting

> > > question), you actually need to change LINK_COMMAND_SPEC (also sometimes

> > > overridden for targets) to handle -r more like -nostdlib -nostartfiles.

> > 

> > Okay, so like this?

> 

> Could you confirm if this has passed a bootstrap and testsuite run, with

> no testsuite regressions compared to GCC without the patch applied?  I

> think it looks mostly OK (modulo ChangeLog rewrites and a missing second

> space after '.' in the manual change) but I'd like to make sure it's

> passed the usual testing before preparing it for commit.


I didn't think of running the tests since it only affects command line 
options, but it did bootstrap, and behave as expected for my specific usecase.

I will update and run the tests when I have time.
Allan Sandfeld Jensen Aug. 26, 2018, 6:17 p.m. | #11
On Donnerstag, 23. August 2018 23:24:02 CEST Joseph Myers wrote:
> On Thu, 23 Aug 2018, Iain Sandoe wrote:

> > Joseph: As a side-comment, is there a reason that we don’t exclude

> > gomp/itm/fortran/gcov from the link for -nostdlib / -nodefaultlib?

> > 

> > If we are relying on the lib self-specs for this, then we’re not

> > succeeding since the one we build at the moment don’t include those

> > clauses.

> 

> Well, fortran/gfortranspec.c for example has

> 

>         case OPT_nostdlib:

>         case OPT_nodefaultlibs:

>         case OPT_c:

>         case OPT_S:

>         case OPT_fsyntax_only:

>         case OPT_E:

>           /* These options disable linking entirely or linking of the

>              standard libraries.  */

>           library = 0;

>           break;

> 

> and only uses libgfortran.spec if (library).  So it's certainly meant to

> avoid linking with libgfortran or its dependencies if -nostdlib.


Patch updated. I specifically edited a number of the existing tests that used 
both -r and -nostdlib and removed -nostdlib so the patch is exercised by 
existing tests. The patch bootstrapped, I didn't notice any relevant failures 
when running the test suite (though I could have missed something, I am never
comfortable reading that output).

'Allan
From 07ed41a9afd107c5d45feb1ead7a74ca735a1bb2 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <carewolf@dragon.local>

Date: Sun, 26 Aug 2018 20:02:54 +0200
Subject: [PATCH] Fix and document -r option

The option has existed and been working for years,
make sure it implies the right extra options, and list
it in the documentation.

2018-08-26 Allan Sandfeld Jensen <allan.jensen@qt.io>

gcc/doc/
    * invoke.texi: Document -r.

gcc/
    * gcc.c (LINK_COMMAND_SPEC): Handle -r like -nostdlib.
    * config/darwin.h (LINK_COMMAND_SPEC): Handle -r like -nostdlib.
    * cp/g++spec.c (lang_specific_driver): Handle -r like -nostdlib.
    * fortran/gfortranspec.c (lang_specific_driver): Handle -r like -nostdlib.
    * go/gospec.c (lang_specific_driver): Handle -r like -nostdlib.

gcc/testsuite/
    * g++.dg/ipa/pr64059.C: Removed now redundant -nostdlib.
    * g++.dg/lto/20081109-1_0.C: Removed now redundant -nostdlib.
    * g++.dg/lto/20090302_0.C: Removed now redundant -nostdlib.
    * g++.dg/lto/pr45621_0.C: Removed now redundant -nostdlib.
    * g++.dg/lto/pr60567_0.C: Removed now redundant -nostdlib.
    * g++.dg/lto/pr62026.C: Removed now redundant -nostdlib.
    * gcc.dg/lto/pr45736_0.c: Removed now redundant -nostdlib.
    * gcc.dg/lto/pr52634_0.c: Removed now redundant -nostdlib.
    * gfortran.dg/lto/20091016-1_0.f90: Removed now redundant -nostdlib.
    * gfortran.dg/lto/pr79108_0.f90: Removed now redundant -nostdlib.

---
 gcc/config/darwin.h                            | 8 ++++----
 gcc/cp/g++spec.c                               | 1 +
 gcc/doc/invoke.texi                            | 7 ++++++-
 gcc/fortran/gfortranspec.c                     | 1 +
 gcc/gcc.c                                      | 6 +++---
 gcc/go/gospec.c                                | 1 +
 gcc/testsuite/g++.dg/ipa/pr64059.C             | 2 +-
 gcc/testsuite/g++.dg/lto/20081109-1_0.C        | 2 +-
 gcc/testsuite/g++.dg/lto/20090302_0.C          | 2 +-
 gcc/testsuite/g++.dg/lto/pr45621_0.C           | 2 +-
 gcc/testsuite/g++.dg/lto/pr60567_0.C           | 2 +-
 gcc/testsuite/g++.dg/lto/pr62026.C             | 2 +-
 gcc/testsuite/gcc.dg/lto/pr45736_0.c           | 2 +-
 gcc/testsuite/gcc.dg/lto/pr52634_0.c           | 2 +-
 gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90 | 2 +-
 gcc/testsuite/gfortran.dg/lto/pr79108_0.f90    | 2 +-
 16 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index cd6d6521658..87f610259c0 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -180,20 +180,20 @@ extern GTY(()) int darwin_ms_struct;
    "%X %{s} %{t} %{Z} %{u*} \
     %{e*} %{r} \
     %{o*}%{!o:-o a.out} \
-    %{!nostdlib:%{!nostartfiles:%S}} \
+    %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
     %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): \
       %{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } \
     %{fgnu-tm: \
       %{static|static-libgcc|static-libstdc++|static-libgfortran: libitm.a%s; : -litm } } \
-    %{!nostdlib:%{!nodefaultlibs:\
+    %{!nostdlib:%{!r:%{!nodefaultlibs:\
       %{%:sanitize(address): -lasan } \
       %{%:sanitize(undefined): -lubsan } \
       %(link_ssp) \
       " DARWIN_EXPORT_DYNAMIC " %<rdynamic \
       %(link_gcc_c_sequence) \
-    }}\
-    %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}"
+    }}}\
+    %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*} %{F*} }}}}}}}"
 
 #define DSYMUTIL "\ndsymutil"
 
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
index 443a1746da3..8c81e0987f7 100644
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -184,6 +184,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 	  break;
 
 	case OPT_c:
+	case OPT_r:
 	case OPT_S:
 	case OPT_E:
 	case OPT_M:
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e4148297a87..cab186d5bf0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -520,7 +520,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Link Options,,Options for Linking}.
 @gccoptlist{@var{object-file-name}  -fuse-ld=@var{linker}  -l@var{library} @gol
 -nostartfiles  -nodefaultlibs  -nolibc  -nostdlib @gol
--pie  -pthread  -rdynamic @gol
+-pie  -pthread  -r  -rdynamic @gol
 -s  -static -static-pie -static-libgcc  -static-libstdc++ @gol
 -static-libasan  -static-libtsan  -static-liblsan  -static-libubsan @gol
 -shared  -shared-libgcc  -symbolic @gol
@@ -12510,6 +12510,11 @@ x86 Cygwin and MinGW targets.  On some targets this option also sets
 flags for the preprocessor, so it should be used consistently for both
 compilation and linking.
 
+@item -r
+@opindex r
+Produce a relocatable object as output. This is also known as partial
+linking.
+
 @item -rdynamic
 @opindex rdynamic
 Pass the flag @option{-export-dynamic} to the ELF linker, on targets
diff --git a/gcc/fortran/gfortranspec.c b/gcc/fortran/gfortranspec.c
index 4ba3a8dba60..7aa2dd78a05 100644
--- a/gcc/fortran/gfortranspec.c
+++ b/gcc/fortran/gfortranspec.c
@@ -243,6 +243,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 	case OPT_nostdlib:
 	case OPT_nodefaultlibs:
 	case OPT_c:
+	case OPT_r:
 	case OPT_S:
 	case OPT_fsyntax_only:
 	case OPT_E:
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 780d4859ef3..687903cb1be 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1041,7 +1041,7 @@ proper position among the other output files.  */
     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    "%X %{o*} %{e*} %{N} %{n} %{r}\
-    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \
+    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
     %{static|no-pie|static-pie:} %@{L*} %(mfwrap) %(link_libgcc) " \
     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o "" \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
@@ -1049,8 +1049,8 @@ proper position among the other output files.  */
     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
     %(mflib) " STACK_SPLIT_SPEC "\
     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
-    %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
-    %{!nostdlib:%{!nostartfiles:%E}} %{T*}  \n%(post_link) }}}}}}"
+    %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\
+    %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*}  \n%(post_link) }}}}}}"
 #endif
 
 #ifndef LINK_LIBGCC_SPEC
diff --git a/gcc/go/gospec.c b/gcc/go/gospec.c
index 7a10997df9b..d265fc986a0 100644
--- a/gcc/go/gospec.c
+++ b/gcc/go/gospec.c
@@ -139,6 +139,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 
       switch (decoded_options[i].opt_index)
 	{
+	case OPT_r:
 	case OPT_nostdlib:
 	case OPT_nodefaultlibs:
 	  library = -1;
diff --git a/gcc/testsuite/g++.dg/ipa/pr64059.C b/gcc/testsuite/g++.dg/ipa/pr64059.C
index 0269b45458d..57011324889 100644
--- a/gcc/testsuite/g++.dg/ipa/pr64059.C
+++ b/gcc/testsuite/g++.dg/ipa/pr64059.C
@@ -1,4 +1,4 @@
-// { dg-options "-r -nostdlib -O2 -flto -fno-devirtualize" }
+// { dg-options "-r -O2 -flto -fno-devirtualize" }
 // { dg-require-effective-target lto }
 
 class A;
diff --git a/gcc/testsuite/g++.dg/lto/20081109-1_0.C b/gcc/testsuite/g++.dg/lto/20081109-1_0.C
index 3b5860011db..db0ba367fe8 100644
--- a/gcc/testsuite/g++.dg/lto/20081109-1_0.C
+++ b/gcc/testsuite/g++.dg/lto/20081109-1_0.C
@@ -1,6 +1,6 @@
 // { dg-lto-do link }
 // { dg-require-effective-target fpic }
 // { dg-lto-options {{-fPIC -flto -flto-partition=1to1}} }
-// { dg-extra-ld-options "-fPIC -flto -flto-partition=1to1 -r -nostdlib -fno-exceptions -flinker-output=nolto-rel" }
+// { dg-extra-ld-options "-fPIC -flto -flto-partition=1to1 -r -fno-exceptions -flinker-output=nolto-rel" }
 void func(); class Foo { };
 void bar() { try { func(); } catch (Foo) { } };
diff --git a/gcc/testsuite/g++.dg/lto/20090302_0.C b/gcc/testsuite/g++.dg/lto/20090302_0.C
index 3a617879e19..23e012704f4 100644
--- a/gcc/testsuite/g++.dg/lto/20090302_0.C
+++ b/gcc/testsuite/g++.dg/lto/20090302_0.C
@@ -1,6 +1,6 @@
 /* { dg-lto-do link } */
 /* { dg-require-effective-target fpic } */
-/* { dg-lto-options {{-fPIC -flto -flto-partition=1to1 -r -nostdlib}} } */
+/* { dg-lto-options {{-fPIC -flto -flto-partition=1to1 -r}} } */
 /* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
 struct Foo {
   bool Mumble();
diff --git a/gcc/testsuite/g++.dg/lto/pr45621_0.C b/gcc/testsuite/g++.dg/lto/pr45621_0.C
index f34b3b70fa7..2055ebfa658 100644
--- a/gcc/testsuite/g++.dg/lto/pr45621_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr45621_0.C
@@ -1,5 +1,5 @@
 // { dg-lto-do assemble }
-// { dg-extra-ld-options "-O2 -fipa-cp-clone -flto -nostdlib -r -flinker-output=nolto-rel" }
+// { dg-extra-ld-options "-O2 -fipa-cp-clone -flto -r -flinker-output=nolto-rel" }
 #include "pr45621.h"
 
 void
diff --git a/gcc/testsuite/g++.dg/lto/pr60567_0.C b/gcc/testsuite/g++.dg/lto/pr60567_0.C
index 966a3c3bc74..175b3aa7a04 100644
--- a/gcc/testsuite/g++.dg/lto/pr60567_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr60567_0.C
@@ -1,7 +1,7 @@
 // PR lto/60567
 // { dg-lto-do link }
 // { dg-lto-options { { -flto -fno-use-linker-plugin } } }
-// { dg-extra-ld-options "-r -nostdlib" }
+// { dg-extra-ld-options "-r" }
 
 #pragma implementation
 struct S {};
diff --git a/gcc/testsuite/g++.dg/lto/pr62026.C b/gcc/testsuite/g++.dg/lto/pr62026.C
index 63766a85b98..0432e907f56 100644
--- a/gcc/testsuite/g++.dg/lto/pr62026.C
+++ b/gcc/testsuite/g++.dg/lto/pr62026.C
@@ -1,5 +1,5 @@
 // { dg-lto-do link }
-// { dg-lto-options {{-flto -O3 -r -nostdlib}} }
+// { dg-lto-options {{-flto -O3 -r}} }
 class C;
 class F {
   virtual C m_fn1();
diff --git a/gcc/testsuite/gcc.dg/lto/pr45736_0.c b/gcc/testsuite/gcc.dg/lto/pr45736_0.c
index d481c453d08..cb7811ba258 100644
--- a/gcc/testsuite/gcc.dg/lto/pr45736_0.c
+++ b/gcc/testsuite/gcc.dg/lto/pr45736_0.c
@@ -1,5 +1,5 @@
 /* { dg-lto-do link } */
-/* { dg-lto-options {{-flto -r -nostdlib -O}} } */
+/* { dg-lto-options {{-flto -r -O}} } */
 /* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
 
 extern void baz (void);
diff --git a/gcc/testsuite/gcc.dg/lto/pr52634_0.c b/gcc/testsuite/gcc.dg/lto/pr52634_0.c
index 7aba0cd3caf..5e14ad9a733 100644
--- a/gcc/testsuite/gcc.dg/lto/pr52634_0.c
+++ b/gcc/testsuite/gcc.dg/lto/pr52634_0.c
@@ -1,7 +1,7 @@
 /* { dg-require-weak "" } */
 /* { dg-require-alias "" } */
 /* { dg-lto-do link } */
-/* { dg-lto-options {{-flto -r -nostdlib -flto-partition=1to1}} */
+/* { dg-lto-options {{-flto -r -flto-partition=1to1}} */
 /* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
 extern int cfliteValueCallBacks;
 void baz (int *);
diff --git a/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90 b/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90
index 5e96e88731f..812ae9b266d 100644
--- a/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90
+++ b/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90
@@ -1,5 +1,5 @@
 ! { dg-lto-do link }
-! { dg-lto-options {{-flto -g -fPIC -r -nostdlib} {-O -flto -g -fPIC -r -nostdlib}} }
+! { dg-lto-options {{-flto -g -fPIC -r} {-O -flto -g -fPIC -r}} }
 ! { dg-extra-ld-options "-flinker-output=nolto-rel" }
 
       FUNCTION makenumberstring(x)
diff --git a/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90 b/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90
index 58412afc3c8..9c878509a83 100644
--- a/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90
+++ b/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90
@@ -1,6 +1,6 @@
 ! { dg-lto-do link }
 ! { dg-lto-options {{ -Ofast -flto --param ggc-min-expand=0 --param ggc-min-heapsize=0 }} }
-! { dg-extra-ld-options "-r -nostdlib" }
+! { dg-extra-ld-options "-r" }
 
 MODULE Errorcheck_mod
 CONTAINS
-- 
2.18.0
Joseph Myers Aug. 27, 2018, 1:37 p.m. | #12
On Sun, 26 Aug 2018, Allan Sandfeld Jensen wrote:

> Patch updated. I specifically edited a number of the existing tests that used 

> both -r and -nostdlib and removed -nostdlib so the patch is exercised by 

> existing tests. The patch bootstrapped, I didn't notice any relevant failures 

> when running the test suite (though I could have missed something, I am never

> comfortable reading that output).


Note that Iain's comments also included that the patch is incomplete 
because of more specs in gcc.c (VTABLE_VERIFICATION_SPEC, 
SANITIZER_EARLY_SPEC, SANITIZER_SPEC) that needs corresponding updates to 
handle -r like -nostdlib.

-- 
Joseph S. Myers
joseph@codesourcery.com
Allan Sandfeld Jensen Sept. 1, 2018, 10:57 a.m. | #13
On Montag, 27. August 2018 15:37:15 CEST Joseph Myers wrote:
> On Sun, 26 Aug 2018, Allan Sandfeld Jensen wrote:

> > Patch updated. I specifically edited a number of the existing tests that

> > used both -r and -nostdlib and removed -nostdlib so the patch is

> > exercised by existing tests. The patch bootstrapped, I didn't notice any

> > relevant failures when running the test suite (though I could have missed

> > something, I am never comfortable reading that output).

> 

> Note that Iain's comments also included that the patch is incomplete

> because of more specs in gcc.c (VTABLE_VERIFICATION_SPEC,

> SANITIZER_EARLY_SPEC, SANITIZER_SPEC) that needs corresponding updates to

> handle -r like -nostdlib.


Okay, I can add that, or whoever commits the patch can add that. We can also 
improve the feature if we discover more places that needs updating. Do you 
want me to post an version updated with with these two places? 

'Allan
Allan Sandfeld Jensen Sept. 1, 2018, 11:05 a.m. | #14
On Montag, 27. August 2018 15:37:15 CEST Joseph Myers wrote:
> On Sun, 26 Aug 2018, Allan Sandfeld Jensen wrote:

> > Patch updated. I specifically edited a number of the existing tests that

> > used both -r and -nostdlib and removed -nostdlib so the patch is

> > exercised by existing tests. The patch bootstrapped, I didn't notice any

> > relevant failures when running the test suite (though I could have missed

> > something, I am never comfortable reading that output).

> 

> Note that Iain's comments also included that the patch is incomplete

> because of more specs in gcc.c (VTABLE_VERIFICATION_SPEC,

> SANITIZER_EARLY_SPEC, SANITIZER_SPEC) that needs corresponding updates to

> handle -r like -nostdlib.


Updated (but tests not rerun)
From 1d164bced7979c94767c260174e3c486d4fc8c5d Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>

Date: Sat, 1 Sep 2018 12:59:14 +0200
Subject: [PATCH] Fix and document -r option

The option has existed and been working for years,
make sure it implies the right extra options, and list
it in the documentation.

2018-09-01 Allan Sandfeld Jensen <allan.jensen@qt.io>

gcc/doc/
    * invoke.texi: Document -r.

gcc/
    * gcc.c (LINK_COMMAND_SPEC): Handle -r like -nostdlib.
    (VTABLE_VERIFICATION_SPEC): Ditto
    (SANITIZER_EARLY_SPEC): Ditto
    (SANITIZER_SPEC): Ditto
    * config/darwin.h (LINK_COMMAND_SPEC): Ditto
    * cp/g++spec.c (lang_specific_driver): Ditto
    * fortran/gfortranspec.c (lang_specific_driver): Ditto
    * go/gospec.c (lang_specific_driver): Ditto

gcc/testsuite/
    * g++.dg/ipa/pr64059.C: Removed now redundant -nostdlib.
    * g++.dg/lto/20081109-1_0.C: Ditto
    * g++.dg/lto/20090302_0.C: Ditto
    * g++.dg/lto/pr45621_0.C: Ditto
    * g++.dg/lto/pr60567_0.C: Ditto
    * g++.dg/lto/pr62026.C: Ditto
    * gcc.dg/lto/pr45736_0.c: Ditto
    * gcc.dg/lto/pr52634_0.c: Ditto
    * gfortran.dg/lto/20091016-1_0.f90: Ditto
    * gfortran.dg/lto/pr79108_0.f90: Ditto
---
 gcc/config/darwin.h                            |  8 ++++----
 gcc/cp/g++spec.c                               |  1 +
 gcc/doc/invoke.texi                            |  7 ++++++-
 gcc/fortran/gfortranspec.c                     |  1 +
 gcc/gcc.c                                      | 18 +++++++++---------
 gcc/go/gospec.c                                |  1 +
 gcc/testsuite/g++.dg/ipa/pr64059.C             |  2 +-
 gcc/testsuite/g++.dg/lto/20081109-1_0.C        |  2 +-
 gcc/testsuite/g++.dg/lto/20090302_0.C          |  2 +-
 gcc/testsuite/g++.dg/lto/pr45621_0.C           |  2 +-
 gcc/testsuite/g++.dg/lto/pr60567_0.C           |  2 +-
 gcc/testsuite/g++.dg/lto/pr62026.C             |  2 +-
 gcc/testsuite/gcc.dg/lto/pr45736_0.c           |  2 +-
 gcc/testsuite/gcc.dg/lto/pr52634_0.c           |  2 +-
 gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90 |  2 +-
 gcc/testsuite/gfortran.dg/lto/pr79108_0.f90    |  2 +-
 16 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index cd6d6521658..87f610259c0 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -180,20 +180,20 @@ extern GTY(()) int darwin_ms_struct;
    "%X %{s} %{t} %{Z} %{u*} \
     %{e*} %{r} \
     %{o*}%{!o:-o a.out} \
-    %{!nostdlib:%{!nostartfiles:%S}} \
+    %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
     %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1): \
       %{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } \
     %{fgnu-tm: \
       %{static|static-libgcc|static-libstdc++|static-libgfortran: libitm.a%s; : -litm } } \
-    %{!nostdlib:%{!nodefaultlibs:\
+    %{!nostdlib:%{!r:%{!nodefaultlibs:\
       %{%:sanitize(address): -lasan } \
       %{%:sanitize(undefined): -lubsan } \
       %(link_ssp) \
       " DARWIN_EXPORT_DYNAMIC " %<rdynamic \
       %(link_gcc_c_sequence) \
-    }}\
-    %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}"
+    }}}\
+    %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*} %{F*} }}}}}}}"
 
 #define DSYMUTIL "\ndsymutil"
 
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
index 443a1746da3..8c81e0987f7 100644
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -184,6 +184,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 	  break;
 
 	case OPT_c:
+	case OPT_r:
 	case OPT_S:
 	case OPT_E:
 	case OPT_M:
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e4148297a87..cab186d5bf0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -520,7 +520,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Link Options,,Options for Linking}.
 @gccoptlist{@var{object-file-name}  -fuse-ld=@var{linker}  -l@var{library} @gol
 -nostartfiles  -nodefaultlibs  -nolibc  -nostdlib @gol
--pie  -pthread  -rdynamic @gol
+-pie  -pthread  -r  -rdynamic @gol
 -s  -static -static-pie -static-libgcc  -static-libstdc++ @gol
 -static-libasan  -static-libtsan  -static-liblsan  -static-libubsan @gol
 -shared  -shared-libgcc  -symbolic @gol
@@ -12510,6 +12510,11 @@ x86 Cygwin and MinGW targets.  On some targets this option also sets
 flags for the preprocessor, so it should be used consistently for both
 compilation and linking.
 
+@item -r
+@opindex r
+Produce a relocatable object as output. This is also known as partial
+linking.
+
 @item -rdynamic
 @opindex rdynamic
 Pass the flag @option{-export-dynamic} to the ELF linker, on targets
diff --git a/gcc/fortran/gfortranspec.c b/gcc/fortran/gfortranspec.c
index 4ba3a8dba60..7aa2dd78a05 100644
--- a/gcc/fortran/gfortranspec.c
+++ b/gcc/fortran/gfortranspec.c
@@ -243,6 +243,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 	case OPT_nostdlib:
 	case OPT_nodefaultlibs:
 	case OPT_c:
+	case OPT_r:
 	case OPT_S:
 	case OPT_fsyntax_only:
 	case OPT_E:
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 780d4859ef3..1460a05a4a7 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -981,20 +981,20 @@ proper position among the other output files.  */
 /* Linker command line options for -fsanitize= early on the command line.  */
 #ifndef SANITIZER_EARLY_SPEC
 #define SANITIZER_EARLY_SPEC "\
-%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
+%{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
     %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
-    %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}"
+    %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}}"
 #endif
 
 /* Linker command line options for -fsanitize= late on the command line.  */
 #ifndef SANITIZER_SPEC
 #define SANITIZER_SPEC "\
-%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
+%{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
     %{static:%ecannot specify -static with -fsanitize=address}}\
     %{%:sanitize(thread):" LIBTSAN_SPEC "\
     %{static:%ecannot specify -static with -fsanitize=thread}}\
     %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
-    %{%:sanitize(leak):" LIBLSAN_SPEC "}}}"
+    %{%:sanitize(leak):" LIBLSAN_SPEC "}}}}"
 #endif
 
 #ifndef POST_LINK_SPEC
@@ -1008,8 +1008,8 @@ proper position among the other output files.  */
 #ifndef VTABLE_VERIFICATION_SPEC
 #if ENABLE_VTABLE_VERIFY
 #define VTABLE_VERIFICATION_SPEC "\
-%{!nostdlib:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
-    %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}"
+%{!nostdlib:%{!r:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
+    %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}}"
 #else
 #define VTABLE_VERIFICATION_SPEC "\
 %{fvtable-verify=none:} \
@@ -1041,7 +1041,7 @@ proper position among the other output files.  */
     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    "%X %{o*} %{e*} %{N} %{n} %{r}\
-    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \
+    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!r:%{!nostartfiles:%S}}} \
     %{static|no-pie|static-pie:} %@{L*} %(mfwrap) %(link_libgcc) " \
     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o "" \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\
@@ -1049,8 +1049,8 @@ proper position among the other output files.  */
     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
     %(mflib) " STACK_SPLIT_SPEC "\
     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
-    %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
-    %{!nostdlib:%{!nostartfiles:%E}} %{T*}  \n%(post_link) }}}}}}"
+    %{!nostdlib:%{!r:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}}\
+    %{!nostdlib:%{!r:%{!nostartfiles:%E}}} %{T*}  \n%(post_link) }}}}}}"
 #endif
 
 #ifndef LINK_LIBGCC_SPEC
diff --git a/gcc/go/gospec.c b/gcc/go/gospec.c
index 7a10997df9b..d265fc986a0 100644
--- a/gcc/go/gospec.c
+++ b/gcc/go/gospec.c
@@ -139,6 +139,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
 
       switch (decoded_options[i].opt_index)
 	{
+	case OPT_r:
 	case OPT_nostdlib:
 	case OPT_nodefaultlibs:
 	  library = -1;
diff --git a/gcc/testsuite/g++.dg/ipa/pr64059.C b/gcc/testsuite/g++.dg/ipa/pr64059.C
index 0269b45458d..57011324889 100644
--- a/gcc/testsuite/g++.dg/ipa/pr64059.C
+++ b/gcc/testsuite/g++.dg/ipa/pr64059.C
@@ -1,4 +1,4 @@
-// { dg-options "-r -nostdlib -O2 -flto -fno-devirtualize" }
+// { dg-options "-r -O2 -flto -fno-devirtualize" }
 // { dg-require-effective-target lto }
 
 class A;
diff --git a/gcc/testsuite/g++.dg/lto/20081109-1_0.C b/gcc/testsuite/g++.dg/lto/20081109-1_0.C
index 3b5860011db..db0ba367fe8 100644
--- a/gcc/testsuite/g++.dg/lto/20081109-1_0.C
+++ b/gcc/testsuite/g++.dg/lto/20081109-1_0.C
@@ -1,6 +1,6 @@
 // { dg-lto-do link }
 // { dg-require-effective-target fpic }
 // { dg-lto-options {{-fPIC -flto -flto-partition=1to1}} }
-// { dg-extra-ld-options "-fPIC -flto -flto-partition=1to1 -r -nostdlib -fno-exceptions -flinker-output=nolto-rel" }
+// { dg-extra-ld-options "-fPIC -flto -flto-partition=1to1 -r -fno-exceptions -flinker-output=nolto-rel" }
 void func(); class Foo { };
 void bar() { try { func(); } catch (Foo) { } };
diff --git a/gcc/testsuite/g++.dg/lto/20090302_0.C b/gcc/testsuite/g++.dg/lto/20090302_0.C
index 3a617879e19..23e012704f4 100644
--- a/gcc/testsuite/g++.dg/lto/20090302_0.C
+++ b/gcc/testsuite/g++.dg/lto/20090302_0.C
@@ -1,6 +1,6 @@
 /* { dg-lto-do link } */
 /* { dg-require-effective-target fpic } */
-/* { dg-lto-options {{-fPIC -flto -flto-partition=1to1 -r -nostdlib}} } */
+/* { dg-lto-options {{-fPIC -flto -flto-partition=1to1 -r}} } */
 /* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
 struct Foo {
   bool Mumble();
diff --git a/gcc/testsuite/g++.dg/lto/pr45621_0.C b/gcc/testsuite/g++.dg/lto/pr45621_0.C
index f34b3b70fa7..2055ebfa658 100644
--- a/gcc/testsuite/g++.dg/lto/pr45621_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr45621_0.C
@@ -1,5 +1,5 @@
 // { dg-lto-do assemble }
-// { dg-extra-ld-options "-O2 -fipa-cp-clone -flto -nostdlib -r -flinker-output=nolto-rel" }
+// { dg-extra-ld-options "-O2 -fipa-cp-clone -flto -r -flinker-output=nolto-rel" }
 #include "pr45621.h"
 
 void
diff --git a/gcc/testsuite/g++.dg/lto/pr60567_0.C b/gcc/testsuite/g++.dg/lto/pr60567_0.C
index 966a3c3bc74..175b3aa7a04 100644
--- a/gcc/testsuite/g++.dg/lto/pr60567_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr60567_0.C
@@ -1,7 +1,7 @@
 // PR lto/60567
 // { dg-lto-do link }
 // { dg-lto-options { { -flto -fno-use-linker-plugin } } }
-// { dg-extra-ld-options "-r -nostdlib" }
+// { dg-extra-ld-options "-r" }
 
 #pragma implementation
 struct S {};
diff --git a/gcc/testsuite/g++.dg/lto/pr62026.C b/gcc/testsuite/g++.dg/lto/pr62026.C
index 63766a85b98..0432e907f56 100644
--- a/gcc/testsuite/g++.dg/lto/pr62026.C
+++ b/gcc/testsuite/g++.dg/lto/pr62026.C
@@ -1,5 +1,5 @@
 // { dg-lto-do link }
-// { dg-lto-options {{-flto -O3 -r -nostdlib}} }
+// { dg-lto-options {{-flto -O3 -r}} }
 class C;
 class F {
   virtual C m_fn1();
diff --git a/gcc/testsuite/gcc.dg/lto/pr45736_0.c b/gcc/testsuite/gcc.dg/lto/pr45736_0.c
index d481c453d08..cb7811ba258 100644
--- a/gcc/testsuite/gcc.dg/lto/pr45736_0.c
+++ b/gcc/testsuite/gcc.dg/lto/pr45736_0.c
@@ -1,5 +1,5 @@
 /* { dg-lto-do link } */
-/* { dg-lto-options {{-flto -r -nostdlib -O}} } */
+/* { dg-lto-options {{-flto -r -O}} } */
 /* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
 
 extern void baz (void);
diff --git a/gcc/testsuite/gcc.dg/lto/pr52634_0.c b/gcc/testsuite/gcc.dg/lto/pr52634_0.c
index 7aba0cd3caf..5e14ad9a733 100644
--- a/gcc/testsuite/gcc.dg/lto/pr52634_0.c
+++ b/gcc/testsuite/gcc.dg/lto/pr52634_0.c
@@ -1,7 +1,7 @@
 /* { dg-require-weak "" } */
 /* { dg-require-alias "" } */
 /* { dg-lto-do link } */
-/* { dg-lto-options {{-flto -r -nostdlib -flto-partition=1to1}} */
+/* { dg-lto-options {{-flto -r -flto-partition=1to1}} */
 /* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
 extern int cfliteValueCallBacks;
 void baz (int *);
diff --git a/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90 b/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90
index 5e96e88731f..812ae9b266d 100644
--- a/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90
+++ b/gcc/testsuite/gfortran.dg/lto/20091016-1_0.f90
@@ -1,5 +1,5 @@
 ! { dg-lto-do link }
-! { dg-lto-options {{-flto -g -fPIC -r -nostdlib} {-O -flto -g -fPIC -r -nostdlib}} }
+! { dg-lto-options {{-flto -g -fPIC -r} {-O -flto -g -fPIC -r}} }
 ! { dg-extra-ld-options "-flinker-output=nolto-rel" }
 
       FUNCTION makenumberstring(x)
diff --git a/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90 b/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90
index 58412afc3c8..9c878509a83 100644
--- a/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90
+++ b/gcc/testsuite/gfortran.dg/lto/pr79108_0.f90
@@ -1,6 +1,6 @@
 ! { dg-lto-do link }
 ! { dg-lto-options {{ -Ofast -flto --param ggc-min-expand=0 --param ggc-min-heapsize=0 }} }
-! { dg-extra-ld-options "-r -nostdlib" }
+! { dg-extra-ld-options "-r" }
 
 MODULE Errorcheck_mod
 CONTAINS
-- 
2.17.1
Joseph Myers Sept. 20, 2018, 7:38 p.m. | #15
On Sat, 1 Sep 2018, Allan Sandfeld Jensen wrote:

> On Montag, 27. August 2018 15:37:15 CEST Joseph Myers wrote:

> > On Sun, 26 Aug 2018, Allan Sandfeld Jensen wrote:

> > > Patch updated. I specifically edited a number of the existing tests that

> > > used both -r and -nostdlib and removed -nostdlib so the patch is

> > > exercised by existing tests. The patch bootstrapped, I didn't notice any

> > > relevant failures when running the test suite (though I could have missed

> > > something, I am never comfortable reading that output).

> > 

> > Note that Iain's comments also included that the patch is incomplete

> > because of more specs in gcc.c (VTABLE_VERIFICATION_SPEC,

> > SANITIZER_EARLY_SPEC, SANITIZER_SPEC) that needs corresponding updates to

> > handle -r like -nostdlib.

> 

> Updated (but tests not rerun)


Thanks, I've now committed the patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

Patch

From 638966e6c7e072ca46c6af0664fbd57bedbfff80 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Wed, 1 Aug 2018 18:07:05 +0200
Subject: [PATCH] Fix and document -r option

The option has existed and been working for years,
make sure it implies the right extra options, and list
it in the documentation.

2018-07-29 Allan Sandfeld Jensen <allan.jensen@qt.io>

gcc/doc

    * invoke.texi: Document -r

gcc/
    * gcc.c: Correct default specs for -r
---
 gcc/doc/invoke.texi | 7 ++++++-
 gcc/gcc.c           | 6 +++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6047d82065a..7da30bd9d99 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -518,7 +518,7 @@  Objective-C and Objective-C++ Dialects}.
 @xref{Link Options,,Options for Linking}.
 @gccoptlist{@var{object-file-name}  -fuse-ld=@var{linker}  -l@var{library} @gol
 -nostartfiles  -nodefaultlibs  -nolibc  -nostdlib @gol
--pie  -pthread  -rdynamic @gol
+-pie  -pthread  -r  -rdynamic @gol
 -s  -static -static-pie -static-libgcc  -static-libstdc++ @gol
 -static-libasan  -static-libtsan  -static-liblsan  -static-libubsan @gol
 -shared  -shared-libgcc  -symbolic @gol
@@ -12444,6 +12444,11 @@  x86 Cygwin and MinGW targets.  On some targets this option also sets
 flags for the preprocessor, so it should be used consistently for both
 compilation and linking.
 
+@item -r
+@opindex r
+Produce a relocatable object as output. This is also known as partial
+linking.
+
 @item -rdynamic
 @opindex rdynamic
 Pass the flag @option{-export-dynamic} to the ELF linker, on targets
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 780d4859ef3..858a5600c14 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -675,7 +675,7 @@  proper position among the other output files.  */
 
 /* config.h can define LIB_SPEC to override the default libraries.  */
 #ifndef LIB_SPEC
-#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
+#define LIB_SPEC "%{!shared|!r:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
 #endif
 
 /* When using -fsplit-stack we need to wrap pthread_create, in order
@@ -797,7 +797,7 @@  proper position among the other output files.  */
 /* config.h can define STARTFILE_SPEC to override the default crt0 files.  */
 #ifndef STARTFILE_SPEC
 #define STARTFILE_SPEC  \
-  "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
+  "%{!shared|!r:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}"
 #endif
 
 /* config.h can define ENDFILE_SPEC to override the default crtn files.  */
@@ -936,7 +936,7 @@  proper position among the other output files.  */
 #else
 #define LD_PIE_SPEC ""
 #endif
-#define LINK_PIE_SPEC "%{static|shared|r:;" PIE_SPEC ":" LD_PIE_SPEC "} "
+#define LINK_PIE_SPEC "%{static|shared|r|ar:;" PIE_SPEC ":" LD_PIE_SPEC "} "
 #endif
 
 #ifndef LINK_BUILDID_SPEC
-- 
2.17.0