[PATCH v2 2/2] s390: Prevent GOT access rewrite for misaligned symbols
Ilya Leoshkevich
iii@linux.ibm.com
Fri May 16 16:54:59 GMT 2025
On Fri, 2025-05-16 at 17:24 +0200, Jens Remus wrote:
> Dereferences of GOT slots with lgrl or lg for global symbols are
> rewritten to larl to get get rid of the extra memory access. However
> this is invalid for:
>
> - symbols marked for absolute addressing
> - symbols at odd addresses (larl can handle only even addresses)
>
> Commit e6213e09ed0e ("S/390: Prevent GOT access rewrite for certain
> symbols") added checks for the above. But instead of checking the
> address of a symbol for being halfword aligned, it tries to deduce
> this from whether the symbol value and section the symbol is defined
> in are halfword aligned. The way it is done has two issues:
>
> 1. The use of bfd_section_from_elf_index to obtain the section the
> symbol is defined in may not return the one that remains in the
> output. For instance for COMDAT sections getting deduplicated
> the section retrieved using bfd_section_from_elf_index may not be
> the same as h->root.u.def.section. If COMDAT sections of same
> group signature have different alignment properties the wrong
> one may be checked. This may then lead to an erroneous rewrite
> of lgrl %rX, sym@GOTENT to larl %rX, sym, although the symbol in
> the remaining section is not properly aligned, triggering an
> "relocation for misaligned symbol" error at link-time.
>
> This may for instance occur when mixing C++ modules compiled with
> GCC and Clang, as GCC emits a 2-byte alignment and Clang a 1-byte
> alignment for COMDAT sections containing type information:
>
> $ cat sample.cpp
> #include <typeinfo>
> struct A {};
> const std::type_info &q() { return typeid(A); }
>
> $ g++ -c sample.cpp -o sample_gcc.o
> $ clang++ -c sample.cpp -o sample_clang.o
> $ readelf -WS sample_gcc.o sample_clang.o
>
> Produces (reformatted and reduced):
> File Name Off Size ES Flg Lk Inf Al
> sample_gcc.o .rodata._ZTS1A 000080 000004 00 AG 0 0 2
> sample_clang.o .rodata._ZTS1A 000058 000003 00 AG 0 0 1
>
> 2. The symbol may end up at an even address, if both the symbol value
> and the section defining the symbol are 1-byte aligned. While
> this
> does not trigger an error, it fails an opportunity to rewrite a
> GOT
> access.
>
> In a Linux Kernel build this causes ~15k GOT accesses using lgrl
> to
> be skipped to be rewritten to larl.
>
> Resolve both issues by simply checking whether the symbol address is
> halfword aligned. Do not check the symbol value nor section defining
> the symbol for halfword alignment.
>
> While at it simplify the test whether the symbol is absolute by using
> the helper bfd_is_abs_symbol.
>
> bfd/
> PR ld/32969
> * elf64-s390.c (elf_s390_relocate_section): Only rewrite
> lgrl/lg from GOT to larl if symbol address is halfword
> aligned.
> Use bfd_is_abs_symbol to test whether symbol is absolute.
>
> ld/testsuite/
> PR ld/32969
> * ld-s390/s390.exp (pr32969_64-1, pr32969_64-2): Add tests
> for
> rewrite of GOT access when COMDAT section deduplication is
> involved.
> * ld-s390/pr32969_64-1.dd: New test for rewrite of GOT
> access
> when COMDAT section deduplication is involved.
> * ld-s390/pr32969_64-2.dd: Likewise.
> * ld-s390/pr32969a.s: Likewise.
> * ld-s390/pr32969b.s: Likewise.
> * ld-s390/pr32969c.s: Likewise.
>
> Bug: https://sourceware.org/PR32969
> Fixes: e6213e09ed0e ("S/390: Prevent GOT access rewrite for certain
> symbols")
> Reported-by: Ilya Leoshkevich <iii@linux.ibm.com>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Thanks for the fix!
Would it make sense to move the simplification into a separate patch?
More information about the Binutils
mailing list