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.
Reviewed-by: Sam James <sam@gentoo.org>
# 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
+endif