LoongArch static executables: fix .got.plt dislocation
Correctly calculates .got.plt entry addresses for static LoongArch executables, fixing a latent bug exposed in version 2.47.
This commit addresses an issue in LoongArch ELF object file generation where the address calculation for .got.plt entries in static Position-Dependent Executables (PDEs) was incorrect. The code mistakenly always accounted for two .got.plt entries reserved for ld.so, which are absent in static PDEs. This resulted in a dislocation of all .got.plt entries by two slots. The fix unifies code paths for related relocations to use a correct subroutine, resolving latent issues in ifunc handling and ensuring correct .got.plt addressing for static builds.
In Details
The R_LARCH_GOT* relocation handling in bfd/elfnn-loongarch.c incorrectly assumed the presence of ld.so entries in the .got.plt section for static PDEs. This caused a two-slot offset error. Prior to binutils 2.47, R_LARCH_GOT* relocations used pointer_equality_needed, directing them to the PLT stub instead of .got.plt, masking the error. This change corrects the address calculation and unifies handling for R_LARCH_GOT{64*,{,_PC}_LO12}, R_LARCH_GOT{PC_,}HI20, and R_LARCH_SOP_PUSH_GPREL to use a robust subroutine, fixing latent issues with ifuncs and custom linker scripts.
- .got.plt
- A section in ELF executables that holds addresses of functions and data used in dynamic linking, specifically for Procedure Linkage Table (PLT) entries that require global offset table (GOT) lookups.
- Static PDE
- Static Position-Dependent Executable. A statically linked executable that may still rely on position-dependent addressing, which is less common than dynamically linked PDEs or Position-Independent Executables (PIEs).
- Ifunc
- Indirect Function. A mechanism in ELF that allows the dynamic linker to resolve a function call to different implementations at runtime, often based on hardware capabilities.
- Relocation
- Information in an object file that describes how to modify parts of the code or data when linking, typically to resolve addresses of external symbols or relative offsets.