[PATCH] sparc: Fix static (non-PIE) executables when PIE is enabled by default

Sam James sam@gentoo.org
Sun Jul 12 20:47:06 GMT 2026


Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:

> For the default --enable-default-pie, $(pic-default) adds -DPIC to
> CPPFLAGS-.o so.  However, -fPIE ($(pie-default)) is only added to
> CFLAGS-.o, which does not affect assembler (.S) sources
>
> On SPARC the GOT register setup in SETUP_PIC_REG references
> _GLOBAL_OFFSET_TABLE_ through %hi/%lo, and the assembler only rewrite
> those into the required PC-relative relocations (R_SPARC_PC22 and
> R_SPARC_PC10) when it is in *PIC* mode; otherwise it emits absolute
> R_SPARC_HI22/R_SPARC_LO10.  With the absolute relocations the
> __sparc_get_pc_thunk sequence adds the run-time PC to an already-absolute
> GOT address, so the computed GOT register is wrong.  In _start this makes
> the address of main come out bogus, and __libc_start_main jumps to an
> unmapped address.
>
> This removes the requirement of the --disable-default-pie for sparc
> to build static binaries correctly.
>
> Checked some tests (mainly the elf/ one) on a sparc64-linux-gnu
> qemu system.
> ---
>  sysdeps/sparc/Makefile | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>

Thanks, this is horrible but familiar (see below wrt copy relocs). I've
started looking at the other problem we discussed on IRC with Andreas
but too hot to do much computer work at the moment.

Reviewed-by: Sam James <sam@gentoo.org>

> diff --git a/sysdeps/sparc/Makefile b/sysdeps/sparc/Makefile
> index 34c51cea6ba..6a58fcfd576 100644
> --- a/sysdeps/sparc/Makefile
> +++ b/sysdeps/sparc/Makefile
> @@ -26,3 +26,14 @@ endif
>  
>  # The assembler on SPARC needs the -fPIC flag even when it's assembler code.
>  ASFLAGS-.os += -fPIC
> +
> +# When PIE is enabled by default, the regular (.o) objects are also built as
> +# PIC, as $(pic-default) adds -DPIC to CPPFLAGS-.o.  That makes the SPARC
> +# assembler sources use the PIC GOT setup sequence, which refers to
> +# # _GLOBAL_OFFSET_TABLE_ through %hi/%lo.  The assembler only turns those into
> +# the required PC-relative relocations (R_SPARC_PC22/PC10) when it is in PIC
> +# mode; without -fPIC it emits absolute R_SPARC_HI22/LO10 instead, so the
> +# run-time GOT register is computed incorrectly.
> +ifeq (yes,$(build-pie-default))
> +ASFLAGS-.o += -fPIC

I think we should be doing this on all arches and it works by chance
without that. It's a bit similar to some of the issues we've seen (not
in glibc, but in gcc and binutils) with mismatches with LTO and copy
relocations if something isn't consistently passed along, because
there's no metadata telling later parts of the toolchain it must be
used, even if it doesn't matter much of the time.

But we can do it for all arches post-release, it's too big of a change
for now IMO (it should be safe but I wouldn't be surprised at all if
problems appeared, so let's not cause issues on !sparc unnecessarily at
this point in the cycle).

> +endif

sam
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 418 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20260712/a562bf37/attachment.sig>


More information about the Libc-alpha mailing list