https://sourceware.org/bugzilla/show_bug.cgi?id=19977

--- Comment #5 from Sourceware Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Maciej W. Rozycki <ma...@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=68f5cb38c27699e9b4840f22596ede96762c4796

commit 68f5cb38c27699e9b4840f22596ede96762c4796
Author: Maciej W. Rozycki <ma...@orcam.me.uk>
Date:   Sat Jul 12 01:25:53 2025 +0100

    PR 19977: MIPS: Add missing pairing for REL PCHI/PCLO relocations

    Just as with all HI/LO 16-bit partial relocations the newly-introduced
    MIPSr6 PC-relative R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations require
    pairing for correct borrow propagation from the low part to the high
    part with REL targets, another case for PR 19977.

    Unlike with absolute relocation, there is a complication here in that
    both parts represent a calculation that is relative to the PC at the
    individual relocation's location rather than both referring to the
    location of the R_MIPS_PCHI16 relocation, normally applied to an AUIPC
    instruction, the location of which is used for the run-time calculation
    executed by hardware.

    To take this semantics into account, the addend of the R_MIPS_PCLO16
    relocation matching a given R_MIPS_PCHI16 relocation is expected to be
    adjusted in the source assembly file for the distance between the two
    relocations in a single pair, so that once both relocations have been
    calculated by the linker, the expression calculated at run time is such
    as if the combined 32-bit immediate was added at the location of the
    AUIPC instruction.

    So for matching R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations into pairs
    GAS needs to check for the distance between the two relocations to be
    equal to the difference between the addends supplied, and then the
    linker has to subtract the low part of the distance between the two
    relocations from the low part in calculating the high part, so as to
    factor in any borrow.

    A further complication is that `_bfd_mips_elf_lo16_reloc' handler is
    supplied with the addend differently depending on whether it has been
    called by GAS via `bfd_install_relocation', or by the generic linker via
    `bfd_perform_relocation'.  In the former case the addend is supplied
    with the relocation itself while in the latter one it comes from the
    field being relocated.

    We currently ignore the addend supplied with the relocation and it works
    for calculating absolute high-part relocations, because the same addend
    has been previously supplied with them when `_bfd_mips_elf_hi16_reloc'
    was called, however this approach does not work for the PC-relative case
    because as noted above the low-part addend is different and we need to
    consistently apply the distance adjustment both with GAS and LD.

    Since the supplied addend and one retrieved from field being relocated
    won't ever be both nonzero, just use the sum of the two values.

    The low-part addend in `mips_elf_add_lo16_rel_addend' always comes from
    the field being relocated, so there's no complication there, we just
    need to apply the same adjustment.

    New linker test cases verify that the same ultimate machine code is
    produced both for ELF and S-record output formats, ensuring that the
    both the MIPS/ELF linker and the generic linker behave in the correct
    way, consistent with each other.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to