A start.o compiled from start.S with -DPIC and no -DSHARED is used by
both crt1.o and rcrt1.o. So the LoongArch static PIE patch
unintentionally introduced PC-relative addressing for main and
__libc_start_main into crt1.o.
While the latest Binutils (trunk, which will be released as 2.40)
supports the PC-relative relocs against an external function by creating
a PLT entry, the 2.39 release branch doesn't (and won't) support this.
An error is raised:
"PLT stub does not represent and symbol not defined."
So, we need the following changes:
1. Check if ld supports the PC-relative relocs against an external
function. If it's not supported, we deem static PIE unsupported.
2. Change start.S. If static PIE is supported, use PC-relative
addressing for main and __libc_start_main and rely on the linker to
create PLT entries. Otherwise, restore the old behavior (using GOT
to address these functions).
An alternative would be adding a new "static-pie-start.S", and some
custom logic into Makefile to build rcrt1.o with it. And, restore
start.S to the state before static PIE change so crt1.o won't contain
PC-relative relocs against external symbols. But I can't see any
benefit of this alternative, so I'd just keep it simple.
Tested by building glibc with the following configurations:
1. Binutils trunk + GCC trunk. Static PIE enabled. All tests
passed.
2. Binutils 2.39 branch + GCC trunk. Static PIE disabled. Tests
related to ifunc failed (it's a known issue). All other tests
passed.
3. Binutils 2.39 branch + GCC 12 branch, cross compilation with
build-many-glibcs.py from x86_64-linux-gnu. Static PIE disabled.
Build succeeded.
If the compiler is new enough, enable static PIE support. In the static
PIE version of _start (in rcrt1.o), use la.pcrel instead of la.got
because in a static PIE we cannot use GOT entries until the dynamic
relocations for GOT are resolved.
The start code can get linked into dynamic linked executables where
LGPL would require shipping the source or linkable binaries when the
executable is distributed.
On some targets the license exception was missing in start.S (which
is compiled into crt1.o and Scrt1.o which may end up linked into PDE
and PIE binaries).
I did not review what other code may end up in executables, just
fixed the start.S license inconsistency across targets.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>