https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126712
Bug ID: 126712
Summary: MIPS NewABI GP setup with local function aliases
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: d
Assignee: ibuclaw at gdcproject dot org
Reporter: kirill at korins dot ky
Target Milestone: ---
The MIPS N32/N64 NewABI loadgp sequence derives $gp from the function
address supplied in $25 and a %gp_rel relocation; conceptually, it
computes
$gp = $25 + GP - S
where S is the relocation symbol. GCC uses the public function symbol as
S, although $25 identifies the function body actually entered. When code
enters a local alias while its weak public symbol is interposed, $25 and
S denote different addresses; the linker correctly resolves S to the
interposing definition, but the resulting $gp addresses the wrong GOT
region and subsequent GOT loads use invalid values.
The correction emits a unique local label at the actual function entry
and uses its locally binding SYMBOL_REF as S; the label cannot be
interposed and has exactly the address supplied in $25, so the NewABI
invariant holds for public symbols, weak symbols, and local aliases. The
assembler prologue must emit this label because shrink wrapping can move
an RTL prologue away from the function entry; the public symbol, alias
relationships, and loadgp instruction sequence remain unchanged.
Here a minimized d-reproducer of the issue which was discovered when
working on porting/bootstraping D lang at 16.1.0 at OpenBSD.