[PATCH v2] x86: Generate PLT32 relocation for ".long foo@PLT - .L4"
Fangrui Song
i@maskray.me
Mon Jul 27 07:04:47 GMT 2026
On Sun, Jul 26, 2026 at 8:51 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Sat, Jul 25, 2026 at 10:35 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > Add BFD_RELOC_X86_64_PLT32 and use it to generate R_X86_64_PLT32 for
> > directives like ".long foo@PLT - .L4" so that PLT entries are used to
> > resolve the PC32 relocation against function symbols for such directives.
> >
> > bfd/
> >
> > PR gas/34423
> > * elf64-x86-64.c (x86_64_reloc_map): Add BFD_RELOC_X86_64_PLT32.
> > * reloc.c (bfd_reloc_code_real): Add BFD_RELOC_X86_64_PLT32.
> > * bfd-in2.h: Regenerated.
> > * libbfd.h: Likewise.
> >
> > gas/
> >
> > PR gas/34423
> > * config/tc-i386.c (x86_cons): Return BFD_RELOC_X86_64_PLT32 for
> > directives like ".long foo@PLT - .L4".
> > (tc_gen_reloc): Generate R_X86_64_PLT32 for BFD_RELOC_X86_64_PLT32
> > with addend computed like R_X86_64_PC32.
> > * testsuite/gas/i386/reloc64.l: Updated.
> > * testsuite/gas/i386/reloc64.s: Replace ".long xtrn@plt - ." with
> > ".long xtrn@plt - _start".
> > * testsuite/gas/i386/ilp32/reloc64.l: Updated.
> > * testsuite/gas/i386/ilp32/reloc64.s: Replace ".long xtrn@plt - ."
> > with ".long xtrn@plt - ptr".
> > * testsuite/gas/i386/x86-64-jump-table.d: New file.
> > * testsuite/gas/i386/x86-64-jump-table.d: Likewise.
> > * testsuite/gas/i386/x86-64-jump-table.s: Likewise.
> > * testsuite/gas/i386/x86-64.exp: Run x86-64-jump-table.
> > * testsuite/gas/i386/ilp32/x86-64-jump-table.d: New file.
> >
> > ld/
> >
> > PR gas/34423
> > * testsuite/ld-x86-64/pr34423.c: New file.
> > * testsuite/ld-x86-64/x86-64-jump-table.s: Likewise.
> > * testsuite/ld-x86-64/x86-64.exp: Run gas/34423 tests.
> >
>
> Add i386 support like LLVM assembler in the v2 patch.
>
>
> --
> H.J.
> ---
> LLVM assembler supports directives like ".long foo@PLT - .L4" for i386
> and x86-64. Implement the same feature to generate PLT32 relocation
> for directives like ".long foo@PLT - .L4" so that PLT entries are used
> to resolve the PC32 relocation against function symbols.
>
> bfd/
>
> PR gas/34423
> * elf32-i386.c (elf_i386_reloc_type_lookup): Handle
> BFD_RELOC_386_PC32_TO_PLT32.
> * elf64-x86-64.c (x86_64_reloc_map): Add
> BFD_RELOC_X86_64_PC32_TO_PLT32.
> * reloc.c (bfd_reloc_code_real): Add BFD_RELOC_386_PC32_TO_PLT32
> and BFD_RELOC_X86_64_PC32_TO_PLT32.
> * bfd-in2.h: Regenerated.
> * libbfd.h: Likewise.
>
> gas/
>
> PR gas/34423
> * config/tc-i386.c (x86_cons): Return
> BFD_RELOC_X86_64_PC32_TO_PLT32 or BFD_RELOC_386_PC32_TO_PLT32
> for directives like ".long foo@PLT - .L4".
> (md_apply_fix): Compute addend for BFD_RELOC_386_PC32_TO_PLT32.
> (tc_gen_reloc): Handle BFD_RELOC_X86_64_PC32_TO_PLT32 and
> BFD_RELOC_386_PC32_TO_PLT32. Compute addend like
> BFD_RELOC_32_PCREL for BFD_RELOC_X86_64_PC32_TO_PLT32.
> * testsuite/gas/i386/i386.exp: Run plt test.
> * testsuite/gas/i386/ilp32/reloc64.l: Updated.
> * testsuite/gas/i386/ilp32/reloc64.s: Replace ".long xtrn@plt - ."
> with ".long xtrn@plt - ptr".
> * testsuite/gas/i386/ilp32/x86-64-jump-table.d: New file.
> * testsuite/gas/i386/plt.d: New file.
> * testsuite/gas/i386/plt.s: Likewise.
> * testsuite/gas/i386/reloc32.s: Replace ".long xtrn@plt - ."
> with ".long xtrn@plt - ptr".
> * testsuite/gas/i386/reloc64.l: Updated.
> * testsuite/gas/i386/reloc64.s: Replace ".long xtrn@plt - ." with
> ".long xtrn@plt - _start".
> * testsuite/gas/i386/x86-64-jump-table.d: New file.
> * testsuite/gas/i386/x86-64-jump-table.d: Likewise.
> * testsuite/gas/i386/x86-64-jump-table.s: Likewise.
> * testsuite/gas/i386/x86-64.exp: Run x86-64-jump-table.
>
> ld/
>
> PR gas/34423
> * testsuite/ld-x86-64/pr34423.c: New file.
> * testsuite/ld-x86-64/x86-64-jump-table.s: Likewise.
> * testsuite/ld-x86-64/x86-64.exp: Run gas/34423 tests.
Note, the fact that LLVM integrated assembler's x86 port supports
`.long foo@plt - .` is not really an official decision.
Having a subtrahend in the expression is awkward to support in assemblers.
In LLVM's aarch64 and riscv ports %pltpcrel(foo) is used.
https://maskray.me/blog/2025-03-16-relocation-generation-in-assemblers
AArch64 uses :specifier:expr, yet PAuth ABI (.quad (g + 7)@AUTH(ia,0))
cannot use : after data directives due to parsing ambiguity.
R_AARCH64_PLT32, R_AARCH64_GOTPCREL32, and R_AARCH64_FUNCINIT were
fixed in llvm/llvm-project#155776 to use %pltpcrel(foo) and
%gotpcrel(foo) instead of the unofficial foo@plt - . / foo@gotpcrel
forms.
More information about the Binutils
mailing list