Message ID | 20221005170851.2350343-1-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | csu: Fix static when PIE is enabled but static PIE is not supported (BZ #29575) | expand |
On 2022-10-05 13:08, Adhemerval Zanella wrote: > On architectures where static PIE is not supported, both libc and > static binaries are built still with -fPIE and -DPIC. It leads to > wrong code for some architectures (for instance sparc). > > This patch only enables -DPIC for .o files iff static-pie is also > supported. Since the same rule is used for both libc.a objects and > installed binaries, the -fno-pie is added if static-pie is not > supported (with a strategy similar to how stack protector is > disabled for some architectures). > > Checked on x86_64-linux-gnu (with and without --disable-static-pie) > and I also checked on sparc64-linux-gnu to verify that static binaries > are not broken and both binaries and tests continue to be built > for PIE. > --- It should be --disable-default-pie. Can you please check again and confirm? Thanks, Sid > Makeconfig | 15 +++++++++++++++ > Makerules | 7 +++++++ > csu/Makefile | 4 ++++ > stdio-common/Makefile | 4 ++-- > 4 files changed, 28 insertions(+), 2 deletions(-) > > diff --git a/Makeconfig b/Makeconfig > index 842f49eb58..4b0d9003cd 100644 > --- a/Makeconfig > +++ b/Makeconfig > @@ -404,6 +404,9 @@ else > # for PIE to support exception. > static-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text > endif # have-static-pie > +else > +no-static-pie = $(no-pie-ccflag) > +no-pic-flag = -UPIC > endif # enable-static-pie > endif # build-pie-default > > @@ -901,6 +904,18 @@ define elide-stack-protector > $(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector)) > endef > > +# If static-pie is not supported, add the compiler option to avoid building it > +# for pie and to remove the PIC define. The first argument is the extension > +# (.o, .os, .oS) and the second is a list of routines that this path should be > +# applied to. > +define elide-pie > +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-static-pie)) > +endef > +# Smae as elide-pie, but remove the PIC flag. s/Smae/Same/ > +define elide-pic-flag > +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-pic-flag)) > +endef > + > # The program that makes Emacs-style TAGS files. > ETAGS := etags > > diff --git a/Makerules b/Makerules > index 09c0cf8357..0fcaf565eb 100644 > --- a/Makerules > +++ b/Makerules > @@ -1239,6 +1239,13 @@ tests += $(foreach t,$(tests-time64),$(t)) > xtests += $(foreach t,$(xtests-time64),$(t)) > endif > > +# Disable static-pie for libc.a if target does not support it. > +CFLAGS-.o += $(call elide-pie,.o,$(routines)) > +CFLAGS-.op += $(call elide-pie,.op,$(routines)) > +# And also remove the PIC flag. > +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(routines)) > +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(routines)) All static routines. OK. > + > # The only difference between MODULE_NAME=testsuite and MODULE_NAME=nonlib is > # that almost all internal declarations from config.h, libc-symbols.h, and > # include/*.h are not available to 'testsuite' code, but are to 'nonlib' code. > diff --git a/csu/Makefile b/csu/Makefile > index f71a5eb6c6..62a819608f 100644 > --- a/csu/Makefile > +++ b/csu/Makefile > @@ -66,6 +66,10 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(filter-out \ > $(ssp-safe.os), \ > $(routines) $(extra-no-ssp))) > > +# Remove PIC flag for init objects. > +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(basename $(extra-objs))) > +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(basename $(extra-objs))) > + crt* too. OK. > ifeq (yes,$(build-shared)) > extra-objs += S$(start-installed-name) gmon-start.os > ifneq ($(start-installed-name),$(static-start-installed-name)) > diff --git a/stdio-common/Makefile b/stdio-common/Makefile > index 9c98c02884..6eee9ba73c 100644 > --- a/stdio-common/Makefile > +++ b/stdio-common/Makefile > @@ -265,7 +265,7 @@ $(objpfx)errlist-data-aux-shared.S: errlist-data-gen.c > > $(objpfx)errlist-data-aux.S: errlist-data-gen.c > $(make-target-directory) > - $(compile-command.c) $(pie-default) $(no-stack-protector) -S > + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S > > ifndef no_deps > -include $(objpfx)errlist-data-aux.S.d $(objpfx)errlist-data-aux-shared.S.d > @@ -280,7 +280,7 @@ $(objpfx)siglist-aux-shared.S: siglist-gen.c > > $(objpfx)siglist-aux.S: siglist-gen.c > $(make-target-directory) > - $(compile-command.c) $(pie-default) $(no-stack-protector) -S > + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S > > ifndef no_deps > -include $(objpfx)siglist-aux.S.d $(objpfx)siglist-aux-shared.S.d
On 05/10/22 16:04, Siddhesh Poyarekar wrote: > > > On 2022-10-05 13:08, Adhemerval Zanella wrote: >> On architectures where static PIE is not supported, both libc and >> static binaries are built still with -fPIE and -DPIC. It leads to >> wrong code for some architectures (for instance sparc). >> >> This patch only enables -DPIC for .o files iff static-pie is also >> supported. Since the same rule is used for both libc.a objects and >> installed binaries, the -fno-pie is added if static-pie is not >> supported (with a strategy similar to how stack protector is >> disabled for some architectures). >> >> Checked on x86_64-linux-gnu (with and without --disable-static-pie) >> and I also checked on sparc64-linux-gnu to verify that static binaries >> are not broken and both binaries and tests continue to be built >> for PIE. >> --- > > It should be --disable-default-pie. Can you please check again and confirm? My mistake, I did use --disable-default-pie (the config.make files on sparc64 build differs for build-pie-default). > > Thanks, > Sid > >> Makeconfig | 15 +++++++++++++++ >> Makerules | 7 +++++++ >> csu/Makefile | 4 ++++ >> stdio-common/Makefile | 4 ++-- >> 4 files changed, 28 insertions(+), 2 deletions(-) >> >> diff --git a/Makeconfig b/Makeconfig >> index 842f49eb58..4b0d9003cd 100644 >> --- a/Makeconfig >> +++ b/Makeconfig >> @@ -404,6 +404,9 @@ else >> # for PIE to support exception. >> static-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text >> endif # have-static-pie >> +else >> +no-static-pie = $(no-pie-ccflag) >> +no-pic-flag = -UPIC >> endif # enable-static-pie >> endif # build-pie-default >> @@ -901,6 +904,18 @@ define elide-stack-protector >> $(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector)) >> endef >> +# If static-pie is not supported, add the compiler option to avoid building it >> +# for pie and to remove the PIC define. The first argument is the extension >> +# (.o, .os, .oS) and the second is a list of routines that this path should be >> +# applied to. >> +define elide-pie >> +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-static-pie)) >> +endef >> +# Smae as elide-pie, but remove the PIC flag. > > s/Smae/Same/ > Ack. >> +define elide-pic-flag >> +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-pic-flag)) >> +endef >> + >> # The program that makes Emacs-style TAGS files. >> ETAGS := etags >> diff --git a/Makerules b/Makerules >> index 09c0cf8357..0fcaf565eb 100644 >> --- a/Makerules >> +++ b/Makerules >> @@ -1239,6 +1239,13 @@ tests += $(foreach t,$(tests-time64),$(t)) >> xtests += $(foreach t,$(xtests-time64),$(t)) >> endif >> +# Disable static-pie for libc.a if target does not support it. >> +CFLAGS-.o += $(call elide-pie,.o,$(routines)) >> +CFLAGS-.op += $(call elide-pie,.op,$(routines)) >> +# And also remove the PIC flag. >> +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(routines)) >> +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(routines)) > > All static routines. OK. > >> + >> # The only difference between MODULE_NAME=testsuite and MODULE_NAME=nonlib is >> # that almost all internal declarations from config.h, libc-symbols.h, and >> # include/*.h are not available to 'testsuite' code, but are to 'nonlib' code. >> diff --git a/csu/Makefile b/csu/Makefile >> index f71a5eb6c6..62a819608f 100644 >> --- a/csu/Makefile >> +++ b/csu/Makefile >> @@ -66,6 +66,10 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(filter-out \ >> $(ssp-safe.os), \ >> $(routines) $(extra-no-ssp))) >> +# Remove PIC flag for init objects. >> +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(basename $(extra-objs))) >> +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(basename $(extra-objs))) >> + > > crt* too. OK. > >> ifeq (yes,$(build-shared)) >> extra-objs += S$(start-installed-name) gmon-start.os >> ifneq ($(start-installed-name),$(static-start-installed-name)) >> diff --git a/stdio-common/Makefile b/stdio-common/Makefile >> index 9c98c02884..6eee9ba73c 100644 >> --- a/stdio-common/Makefile >> +++ b/stdio-common/Makefile >> @@ -265,7 +265,7 @@ $(objpfx)errlist-data-aux-shared.S: errlist-data-gen.c >> $(objpfx)errlist-data-aux.S: errlist-data-gen.c >> $(make-target-directory) >> - $(compile-command.c) $(pie-default) $(no-stack-protector) -S >> + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S >> ifndef no_deps >> -include $(objpfx)errlist-data-aux.S.d $(objpfx)errlist-data-aux-shared.S.d >> @@ -280,7 +280,7 @@ $(objpfx)siglist-aux-shared.S: siglist-gen.c >> $(objpfx)siglist-aux.S: siglist-gen.c >> $(make-target-directory) >> - $(compile-command.c) $(pie-default) $(no-stack-protector) -S >> + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S >> ifndef no_deps >> -include $(objpfx)siglist-aux.S.d $(objpfx)siglist-aux-shared.S.d
On 2022-10-06 14:09, Adhemerval Zanella Netto wrote: > > > On 05/10/22 16:04, Siddhesh Poyarekar wrote: >> >> >> On 2022-10-05 13:08, Adhemerval Zanella wrote: >>> On architectures where static PIE is not supported, both libc and >>> static binaries are built still with -fPIE and -DPIC. It leads to >>> wrong code for some architectures (for instance sparc). >>> >>> This patch only enables -DPIC for .o files iff static-pie is also >>> supported. Since the same rule is used for both libc.a objects and >>> installed binaries, the -fno-pie is added if static-pie is not >>> supported (with a strategy similar to how stack protector is >>> disabled for some architectures). >>> >>> Checked on x86_64-linux-gnu (with and without --disable-static-pie) >>> and I also checked on sparc64-linux-gnu to verify that static binaries >>> are not broken and both binaries and tests continue to be built >>> for PIE. >>> --- >> >> It should be --disable-default-pie. Can you please check again and confirm? > > My mistake, I did use --disable-default-pie (the config.make files on > sparc64 build differs for build-pie-default). OK then it looks good with the typo fixed. Thanks, Sid > >> >> Thanks, >> Sid >> >>> Makeconfig | 15 +++++++++++++++ >>> Makerules | 7 +++++++ >>> csu/Makefile | 4 ++++ >>> stdio-common/Makefile | 4 ++-- >>> 4 files changed, 28 insertions(+), 2 deletions(-) >>> >>> diff --git a/Makeconfig b/Makeconfig >>> index 842f49eb58..4b0d9003cd 100644 >>> --- a/Makeconfig >>> +++ b/Makeconfig >>> @@ -404,6 +404,9 @@ else >>> # for PIE to support exception. >>> static-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text >>> endif # have-static-pie >>> +else >>> +no-static-pie = $(no-pie-ccflag) >>> +no-pic-flag = -UPIC >>> endif # enable-static-pie >>> endif # build-pie-default >>> @@ -901,6 +904,18 @@ define elide-stack-protector >>> $(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector)) >>> endef >>> +# If static-pie is not supported, add the compiler option to avoid building it >>> +# for pie and to remove the PIC define. The first argument is the extension >>> +# (.o, .os, .oS) and the second is a list of routines that this path should be >>> +# applied to. >>> +define elide-pie >>> +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-static-pie)) >>> +endef >>> +# Smae as elide-pie, but remove the PIC flag. >> >> s/Smae/Same/ >> > > Ack. > >>> +define elide-pic-flag >>> +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-pic-flag)) >>> +endef >>> + >>> # The program that makes Emacs-style TAGS files. >>> ETAGS := etags >>> diff --git a/Makerules b/Makerules >>> index 09c0cf8357..0fcaf565eb 100644 >>> --- a/Makerules >>> +++ b/Makerules >>> @@ -1239,6 +1239,13 @@ tests += $(foreach t,$(tests-time64),$(t)) >>> xtests += $(foreach t,$(xtests-time64),$(t)) >>> endif >>> +# Disable static-pie for libc.a if target does not support it. >>> +CFLAGS-.o += $(call elide-pie,.o,$(routines)) >>> +CFLAGS-.op += $(call elide-pie,.op,$(routines)) >>> +# And also remove the PIC flag. >>> +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(routines)) >>> +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(routines)) >> >> All static routines. OK. >> >>> + >>> # The only difference between MODULE_NAME=testsuite and MODULE_NAME=nonlib is >>> # that almost all internal declarations from config.h, libc-symbols.h, and >>> # include/*.h are not available to 'testsuite' code, but are to 'nonlib' code. >>> diff --git a/csu/Makefile b/csu/Makefile >>> index f71a5eb6c6..62a819608f 100644 >>> --- a/csu/Makefile >>> +++ b/csu/Makefile >>> @@ -66,6 +66,10 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(filter-out \ >>> $(ssp-safe.os), \ >>> $(routines) $(extra-no-ssp))) >>> +# Remove PIC flag for init objects. >>> +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(basename $(extra-objs))) >>> +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(basename $(extra-objs))) >>> + >> >> crt* too. OK. >> >>> ifeq (yes,$(build-shared)) >>> extra-objs += S$(start-installed-name) gmon-start.os >>> ifneq ($(start-installed-name),$(static-start-installed-name)) >>> diff --git a/stdio-common/Makefile b/stdio-common/Makefile >>> index 9c98c02884..6eee9ba73c 100644 >>> --- a/stdio-common/Makefile >>> +++ b/stdio-common/Makefile >>> @@ -265,7 +265,7 @@ $(objpfx)errlist-data-aux-shared.S: errlist-data-gen.c >>> $(objpfx)errlist-data-aux.S: errlist-data-gen.c >>> $(make-target-directory) >>> - $(compile-command.c) $(pie-default) $(no-stack-protector) -S >>> + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S >>> ifndef no_deps >>> -include $(objpfx)errlist-data-aux.S.d $(objpfx)errlist-data-aux-shared.S.d >>> @@ -280,7 +280,7 @@ $(objpfx)siglist-aux-shared.S: siglist-gen.c >>> $(objpfx)siglist-aux.S: siglist-gen.c >>> $(make-target-directory) >>> - $(compile-command.c) $(pie-default) $(no-stack-protector) -S >>> + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S >>> ifndef no_deps >>> -include $(objpfx)siglist-aux.S.d $(objpfx)siglist-aux-shared.S.d >
On 06/10/22 15:21, Siddhesh Poyarekar wrote: > On 2022-10-06 14:09, Adhemerval Zanella Netto wrote: >> >> >> On 05/10/22 16:04, Siddhesh Poyarekar wrote: >>> >>> >>> On 2022-10-05 13:08, Adhemerval Zanella wrote: >>>> On architectures where static PIE is not supported, both libc and >>>> static binaries are built still with -fPIE and -DPIC. It leads to >>>> wrong code for some architectures (for instance sparc). >>>> >>>> This patch only enables -DPIC for .o files iff static-pie is also >>>> supported. Since the same rule is used for both libc.a objects and >>>> installed binaries, the -fno-pie is added if static-pie is not >>>> supported (with a strategy similar to how stack protector is >>>> disabled for some architectures). >>>> >>>> Checked on x86_64-linux-gnu (with and without --disable-static-pie) >>>> and I also checked on sparc64-linux-gnu to verify that static binaries >>>> are not broken and both binaries and tests continue to be built >>>> for PIE. >>>> --- >>> >>> It should be --disable-default-pie. Can you please check again and confirm? >> >> My mistake, I did use --disable-default-pie (the config.make files on >> sparc64 build differs for build-pie-default). > > OK then it looks good with the typo fixed. > > Thanks, > Sid Sigh... it is not correct if gcc has --enable-default-pie.
Hello! On 10/5/22 19:08, Adhemerval Zanella wrote: > On architectures where static PIE is not supported, both libc and > static binaries are built still with -fPIE and -DPIC. It leads to > wrong code for some architectures (for instance sparc). Just noticed today that this issue affects the sh4 architecture as well [1]. Adrian > [1] https://sourceware.org/bugzilla/show_bug.cgi?id=29575#c4
diff --git a/Makeconfig b/Makeconfig index 842f49eb58..4b0d9003cd 100644 --- a/Makeconfig +++ b/Makeconfig @@ -404,6 +404,9 @@ else # for PIE to support exception. static-pie-ldflag = -Wl,-pie,--no-dynamic-linker,--eh-frame-hdr,-z,text endif # have-static-pie +else +no-static-pie = $(no-pie-ccflag) +no-pic-flag = -UPIC endif # enable-static-pie endif # build-pie-default @@ -901,6 +904,18 @@ define elide-stack-protector $(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector)) endef +# If static-pie is not supported, add the compiler option to avoid building it +# for pie and to remove the PIC define. The first argument is the extension +# (.o, .os, .oS) and the second is a list of routines that this path should be +# applied to. +define elide-pie +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-static-pie)) +endef +# Smae as elide-pie, but remove the PIC flag. +define elide-pic-flag +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-pic-flag)) +endef + # The program that makes Emacs-style TAGS files. ETAGS := etags diff --git a/Makerules b/Makerules index 09c0cf8357..0fcaf565eb 100644 --- a/Makerules +++ b/Makerules @@ -1239,6 +1239,13 @@ tests += $(foreach t,$(tests-time64),$(t)) xtests += $(foreach t,$(xtests-time64),$(t)) endif +# Disable static-pie for libc.a if target does not support it. +CFLAGS-.o += $(call elide-pie,.o,$(routines)) +CFLAGS-.op += $(call elide-pie,.op,$(routines)) +# And also remove the PIC flag. +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(routines)) +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(routines)) + # The only difference between MODULE_NAME=testsuite and MODULE_NAME=nonlib is # that almost all internal declarations from config.h, libc-symbols.h, and # include/*.h are not available to 'testsuite' code, but are to 'nonlib' code. diff --git a/csu/Makefile b/csu/Makefile index f71a5eb6c6..62a819608f 100644 --- a/csu/Makefile +++ b/csu/Makefile @@ -66,6 +66,10 @@ CFLAGS-.os += $(call elide-stack-protector,.os,$(filter-out \ $(ssp-safe.os), \ $(routines) $(extra-no-ssp))) +# Remove PIC flag for init objects. +CPPFLAGS-.o += $(call elide-pic-flag,.o,$(basename $(extra-objs))) +CPPFLAGS-.op += $(call elide-pic-flag,.op,$(basename $(extra-objs))) + ifeq (yes,$(build-shared)) extra-objs += S$(start-installed-name) gmon-start.os ifneq ($(start-installed-name),$(static-start-installed-name)) diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 9c98c02884..6eee9ba73c 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -265,7 +265,7 @@ $(objpfx)errlist-data-aux-shared.S: errlist-data-gen.c $(objpfx)errlist-data-aux.S: errlist-data-gen.c $(make-target-directory) - $(compile-command.c) $(pie-default) $(no-stack-protector) -S + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S ifndef no_deps -include $(objpfx)errlist-data-aux.S.d $(objpfx)errlist-data-aux-shared.S.d @@ -280,7 +280,7 @@ $(objpfx)siglist-aux-shared.S: siglist-gen.c $(objpfx)siglist-aux.S: siglist-gen.c $(make-target-directory) - $(compile-command.c) $(pie-default) $(no-stack-protector) -S + $(compile-command.c) $(pic-cppflags) $(pic-ccflag) $(no-stack-protector) -S ifndef no_deps -include $(objpfx)siglist-aux.S.d $(objpfx)siglist-aux-shared.S.d