[PATCH] meson: remove -no-pie linker flag

Paolo Bonzini posted 1 patch 11 months, 2 weeks ago
Failed in applying to current master (apply log)
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Thomas Huth <thuth@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
meson.build | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
[PATCH] meson: remove -no-pie linker flag
Posted by Paolo Bonzini 11 months, 2 weeks ago
The large comment in the patch says it all; the -no-pie flag is broken and
this is why it was not included in QEMU_LDFLAGS before commit a988b4c5614
("build: move remaining compiler flag tests to meson", 2023-05-18).

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1664
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 meson.build | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/meson.build b/meson.build
index 0a5cdefd4d3d..6733b2917081 100644
--- a/meson.build
+++ b/meson.build
@@ -267,10 +267,15 @@ endif
 # has explicitly disabled PIE we need to extend our cflags.
 if not get_option('b_pie')
   qemu_common_flags += cc.get_supported_arguments('-fno-pie')
-  if not get_option('prefer_static')
-    # No PIE is implied by -static which we added above.
-    qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
-  endif
+  # What about linker flags?  For a static build, no PIE is implied by -static
+  # which we added above.  For dynamic linking, adding -no-pie is messy because
+  # it overrides -shared: the linker then wants to build an executable instead
+  # of a shared library and the build fails.  Before moving this code to Meson,
+  # we went through a dozen different commits affecting the usage of -no-pie,
+  # ultimately settling for a completely broken one that added -no-pie to the
+  # compiler flags together with -fno-pie... except that -no-pie is a linker
+  # flag that has no effect on the compiler command line.  So, don't add
+  # -no-pie anywhere and cross fingers.
 endif
 
 if not get_option('stack_protector').disabled()
-- 
2.40.1
Re: [PATCH] meson: remove -no-pie linker flag
Posted by Daniel P. Berrangé 11 months, 2 weeks ago
On Mon, May 22, 2023 at 10:08:16AM +0200, Paolo Bonzini wrote:
> The large comment in the patch says it all; the -no-pie flag is broken and
> this is why it was not included in QEMU_LDFLAGS before commit a988b4c5614
> ("build: move remaining compiler flag tests to meson", 2023-05-18).
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1664
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  meson.build | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index 0a5cdefd4d3d..6733b2917081 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -267,10 +267,15 @@ endif
>  # has explicitly disabled PIE we need to extend our cflags.
>  if not get_option('b_pie')
>    qemu_common_flags += cc.get_supported_arguments('-fno-pie')
> -  if not get_option('prefer_static')
> -    # No PIE is implied by -static which we added above.
> -    qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
> -  endif
> +  # What about linker flags?  For a static build, no PIE is implied by -static
> +  # which we added above.  For dynamic linking, adding -no-pie is messy because
> +  # it overrides -shared: the linker then wants to build an executable instead
> +  # of a shared library and the build fails.  Before moving this code to Meson,
> +  # we went through a dozen different commits affecting the usage of -no-pie,
> +  # ultimately settling for a completely broken one that added -no-pie to the
> +  # compiler flags together with -fno-pie... except that -no-pie is a linker
> +  # flag that has no effect on the compiler command line.  So, don't add
> +  # -no-pie anywhere and cross fingers.
>  endif

I'm curious why we need to do anything ?  I would have thought that meson
should handle 'b_pie' itself, passing the right args to $CC that it feels
are appropriate. I don't recall seeing other apps using meson trying to
handle b_pie logic - what's special about QEMU ? IOW, is it possible to
delete this entire b_pie condition and thus avoid worrying about this
problem ?

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
Re: [PATCH] meson: remove -no-pie linker flag
Posted by Paolo Bonzini 11 months, 2 weeks ago
On Tue, May 23, 2023 at 10:00 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
> I'm curious why we need to do anything ?  I would have thought that meson
> should handle 'b_pie' itself, passing the right args to $CC that it feels
> are appropriate. I don't recall seeing other apps using meson trying to
> handle b_pie logic - what's special about QEMU ? IOW, is it possible to
> delete this entire b_pie condition and thus avoid worrying about this
> problem ?

The issue is that Meson only has "enable PIE" or "leave PIE to the
compiler default", while QEMU also has "disable PIE"---which is the
messy one.

Paolo
Re: [PATCH] meson: remove -no-pie linker flag
Posted by Daniel P. Berrangé 11 months, 2 weeks ago
On Tue, May 23, 2023 at 10:02:51AM +0200, Paolo Bonzini wrote:
> On Tue, May 23, 2023 at 10:00 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
> > I'm curious why we need to do anything ?  I would have thought that meson
> > should handle 'b_pie' itself, passing the right args to $CC that it feels
> > are appropriate. I don't recall seeing other apps using meson trying to
> > handle b_pie logic - what's special about QEMU ? IOW, is it possible to
> > delete this entire b_pie condition and thus avoid worrying about this
> > problem ?
> 
> The issue is that Meson only has "enable PIE" or "leave PIE to the
> compiler default", while QEMU also has "disable PIE"---which is the
> messy one.

Does QEMU actually need "disable PIE" ? It existed in configure of
course, is there a reason we need to continue to support it in meson ?

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Re: [PATCH] meson: remove -no-pie linker flag
Posted by Richard Henderson 11 months, 2 weeks ago
On 5/23/23 01:18, Daniel P. Berrangé wrote:
> On Tue, May 23, 2023 at 10:02:51AM +0200, Paolo Bonzini wrote:
>> On Tue, May 23, 2023 at 10:00 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
>>> I'm curious why we need to do anything ?  I would have thought that meson
>>> should handle 'b_pie' itself, passing the right args to $CC that it feels
>>> are appropriate. I don't recall seeing other apps using meson trying to
>>> handle b_pie logic - what's special about QEMU ? IOW, is it possible to
>>> delete this entire b_pie condition and thus avoid worrying about this
>>> problem ?
>>
>> The issue is that Meson only has "enable PIE" or "leave PIE to the
>> compiler default", while QEMU also has "disable PIE"---which is the
>> messy one.
> 
> Does QEMU actually need "disable PIE" ? It existed in configure of
> course, is there a reason we need to continue to support it in meson ?

We need it for aarch64 runner, because the OS built glibc static libraries with -fpie 
instead of -fPIE, and we get a relocation overflow at link time.

Upstream glibc has been fixed, but there has been no update to ubuntu packages.


r~


Re: [PATCH] meson: remove -no-pie linker flag
Posted by Paolo Bonzini 11 months, 2 weeks ago
On Tue, May 23, 2023 at 10:18 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
> > The issue is that Meson only has "enable PIE" or "leave PIE to the
> > compiler default", while QEMU also has "disable PIE"---which is the
> > messy one.
>
> Does QEMU actually need "disable PIE" ? It existed in configure of
> course, is there a reason we need to continue to support it in meson ?

We have "disable PIE" support because PIE has a performance cost,
though that's mostly for 32-bit x86 processors. Other ISAs have
instructions that help (like x86-64's RIP-relative addressing,
aarch64's adr/adrp, or RISC-V's auipc) and then position-independent
code becomes the natural one anyway.

However, I am inclined to keep it also because "--disable-pie uses the
compiler default, and who knows what your distro did" is less obvious
than "--disable-pie disables PIE".

Paolo
Re: [PATCH] meson: remove -no-pie linker flag
Posted by Volker Rümelin 11 months, 2 weeks ago
Am 22.05.23 um 10:08 schrieb Paolo Bonzini:
> The large comment in the patch says it all; the -no-pie flag is broken and
> this is why it was not included in QEMU_LDFLAGS before commit a988b4c5614
> ("build: move remaining compiler flag tests to meson", 2023-05-18).
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1664
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   meson.build | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/meson.build b/meson.build
> index 0a5cdefd4d3d..6733b2917081 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -267,10 +267,15 @@ endif
>   # has explicitly disabled PIE we need to extend our cflags.
>   if not get_option('b_pie')
>     qemu_common_flags += cc.get_supported_arguments('-fno-pie')
> -  if not get_option('prefer_static')
> -    # No PIE is implied by -static which we added above.
> -    qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
> -  endif
> +  # What about linker flags?  For a static build, no PIE is implied by -static
> +  # which we added above.  For dynamic linking, adding -no-pie is messy because
> +  # it overrides -shared: the linker then wants to build an executable instead
> +  # of a shared library and the build fails.  Before moving this code to Meson,
> +  # we went through a dozen different commits affecting the usage of -no-pie,
> +  # ultimately settling for a completely broken one that added -no-pie to the
> +  # compiler flags together with -fno-pie... except that -no-pie is a linker
> +  # flag that has no effect on the compiler command line.  So, don't add
> +  # -no-pie anywhere and cross fingers.
>   endif
>   
>   if not get_option('stack_protector').disabled()

QEMU builds again on Windows with MSYS2 mingw64.

I also tried to build QEMU on Windows with libslirp from the subproject 
folder. The issue reported in 
https://gitlab.com/qemu-project/qemu/-/issues/1664 is fixed, but it now 
fails with a different error. This is a libslirp bug. See 
https://gitlab.freedesktop.org/slirp/libslirp/-/issues/68. The revision 
in subprojects/slirp.wrap should be at least 
fc5eaaf6f68d5cff76468c63984c33c4fb51506d.

Building QEMU on my Linux system works fine.

Tested-by: Volker Rümelin <vr_qemu@t-online.de>

Re: [PATCH] meson: remove -no-pie linker flag
Posted by Richard Henderson 11 months, 2 weeks ago
On 5/22/23 01:08, Paolo Bonzini wrote:
> The large comment in the patch says it all; the -no-pie flag is broken and
> this is why it was not included in QEMU_LDFLAGS before commit a988b4c5614
> ("build: move remaining compiler flag tests to meson", 2023-05-18).

It's not nearly as simple as that.

> +  # What about linker flags?  For a static build, no PIE is implied by -static
> +  # which we added above.  For dynamic linking, adding -no-pie is messy because
> +  # it overrides -shared: the linker then wants to build an executable instead
> +  # of a shared library and the build fails.  Before moving this code to Meson,
> +  # we went through a dozen different commits affecting the usage of -no-pie,
> +  # ultimately settling for a completely broken one that added -no-pie to the
> +  # compiler flags together with -fno-pie... except that -no-pie is a linker
> +  # flag that has no effect on the compiler command line.

-no-pie is a linker flag, but distro folk that didn't quite know what they were doing made 
local changes to gcc's specs file.  So it *is* a compiler command-line flag, but only for 
some builds of gcc.

We can't just remove -no-pie, we need to probe for it as cc.get_supported_arguments 
instead of cc.get_supported_link_arguments.

Or something.  It's a mess, for sure.


r~
Re: [PATCH] meson: remove -no-pie linker flag
Posted by Michael Tokarev 11 months, 2 weeks ago
22.05.2023 18:54, Richard Henderson wrote:
..
> -no-pie is a linker flag, but distro folk that didn't quite know what they were doing made local changes to gcc's specs file.  So it *is* a compiler 
> command-line flag, but only for some builds of gcc.

Which distros is that? Debian?
Patching gcc spec file like this - if that's true - is a way to disaster,
and should be stopped.

Thanks,

/mjt
> We can't just remove -no-pie, we need to probe for it as cc.get_supported_arguments instead of cc.get_supported_link_arguments.
> 
> Or something.  It's a mess, for sure.
> 
> 
> r~
> 
> 


Re: [PATCH] meson: remove -no-pie linker flag
Posted by Richard Henderson 11 months, 2 weeks ago
On 5/22/23 01:08, Paolo Bonzini wrote:
> The large comment in the patch says it all; the -no-pie flag is broken and
> this is why it was not included in QEMU_LDFLAGS before commit a988b4c5614
> ("build: move remaining compiler flag tests to meson", 2023-05-18).
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1664
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   meson.build | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index 0a5cdefd4d3d..6733b2917081 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -267,10 +267,15 @@ endif
>   # has explicitly disabled PIE we need to extend our cflags.
>   if not get_option('b_pie')
>     qemu_common_flags += cc.get_supported_arguments('-fno-pie')
> -  if not get_option('prefer_static')
> -    # No PIE is implied by -static which we added above.
> -    qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
> -  endif
> +  # What about linker flags?  For a static build, no PIE is implied by -static
> +  # which we added above.

Is it though?  That was the major problem at the time: it wasn't.

IIRC, debian has enabled link-pie-by-default, so '-static' meant '-static-pie'.  Moreover, 
not all of their static libraries were built -fpie, which led to link errors.

Trying both now, e.g. '--static --disable-system --disable-tools --disable-docs',
a link line contains

... -Wl,--as-needed -Wl,--no-undefined -pie -Wl,--whole-archive libhwcore.fa ...
                                        ^^^^

Where does that come from, and why isn't -no-pie the antidote?


r~
Re: [PATCH] meson: remove -no-pie linker flag
Posted by Paolo Bonzini 11 months, 2 weeks ago
On Mon, May 22, 2023 at 4:39 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
> > +  # What about linker flags?  For a static build, no PIE is implied by -static
> > +  # which we added above.
>
> Is it though?  That was the major problem at the time: it wasn't.

It's what configure was doing:

if test "$static" = "yes"; then
  if test "$pie" != "no" && compile_prog "-Werror -fPIE -DPIE"
"-static-pie"; then
    CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS"
    pie="yes"
  elif test "$pie" = "yes"; then
    error_exit "-static-pie not available due to missing toolchain support"
  else
    pie="no"
    QEMU_CFLAGS="-fno-pie $QEMU_CFLAGS"
  fi
elif test "$pie" = "no"; then
  if compile_prog "-Werror -fno-pie" "-no-pie"; then
    CONFIGURE_CFLAGS="-fno-pie $CONFIGURE_CFLAGS"
    CONFIGURE_LDFLAGS="-no-pie $CONFIGURE_LDFLAGS"
    QEMU_CFLAGS="-fno-pie -no-pie $QEMU_CFLAGS"
   fi
fi

Note that the code to use -no-pie is only used if test "$static" = no.

> Trying both now, e.g. '--static --disable-system --disable-tools --disable-docs',
> a link line contains
>
> ... -Wl,--as-needed -Wl,--no-undefined -pie -Wl,--whole-archive libhwcore.fa ...
>                                         ^^^^
>
> Where does that come from, and why isn't -no-pie the antidote?

That comes from Meson's -Db_pie=true, but it is followed by
-static-pie later in the command line so all is good.

In other words, whatever we add second in the command line wins and
that is good for executables; but it is a problem when -no-pie
overrides -shared, thus messing up compilation of any shared library.

Paolo
Re: [PATCH] meson: remove -no-pie linker flag
Posted by Philippe Mathieu-Daudé 11 months, 2 weeks ago
On 22/5/23 10:08, Paolo Bonzini wrote:
> The large comment in the patch says it all; the -no-pie flag is broken and
> this is why it was not included in QEMU_LDFLAGS before commit a988b4c5614
> ("build: move remaining compiler flag tests to meson", 2023-05-18).
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1664
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   meson.build | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index 0a5cdefd4d3d..6733b2917081 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -267,10 +267,15 @@ endif
>   # has explicitly disabled PIE we need to extend our cflags.
>   if not get_option('b_pie')
>     qemu_common_flags += cc.get_supported_arguments('-fno-pie')
> -  if not get_option('prefer_static')
> -    # No PIE is implied by -static which we added above.
> -    qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
> -  endif
> +  # What about linker flags?  For a static build, no PIE is implied by -static
> +  # which we added above.  For dynamic linking, adding -no-pie is messy because
> +  # it overrides -shared: the linker then wants to build an executable instead
> +  # of a shared library and the build fails.  Before moving this code to Meson,
> +  # we went through a dozen different commits affecting the usage of -no-pie,
> +  # ultimately settling for a completely broken one that added -no-pie to the
> +  # compiler flags together with -fno-pie... except that -no-pie is a linker
> +  # flag that has no effect on the compiler command line.  So, don't add
> +  # -no-pie anywhere and cross fingers.
>   endif
>   
>   if not get_option('stack_protector').disabled()

This removes this annoying warning with Clang on Aarch64:

clang: warning: argument unused during compilation: '-no-pie' 
[-Wunused-command-line-argument]

Not tested on mingw64, but at least on Darwin:

Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>