x86: Disallow ".long foo@PLT - .L4" for PLT32 relocation

Message ID CAMe9rOpzTQfTugXC+QPA_iJ1tr2VmiKpaQboDxzg4MH4r3Q-2Q@mail.gmail.com
State New
Headers
Series x86: Disallow ".long foo@PLT - .L4" for PLT32 relocation |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed

Commit Message

H.J. Lu July 30, 2026, 11:09 p.m. UTC
  Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
PLT32 relocation.

gas/

PR gas/34423
* config/tc-i386.c (cons_slong): New.
(x86_cons): Return BFD_RELOC_X86_64_PC32_TO_PLT32 or
BFD_RELOC_386_PC32_TO_PLT32 only if cons_slong is true.
(signed_cons): Set cons_slong to true before calling cons and
set it to false afterwards.
(tc_gen_reloc): Update BFD_RELOC_X86_64_PC32_TO_PLT32 comments.
* testsuite/gas/i386/ilp32/reloc64.l: Revert commit 53902b30c66.
* testsuite/gas/i386/ilp32/reloc64.s: Likewise.
* testsuite/gas/i386/reloc32.l: Likewise.
* testsuite/gas/i386/reloc32.s: Likewise.
* testsuite/gas/i386/reloc64.l: Likewise.
* testsuite/gas/i386/plt.s: Replace .long with .slong.
* testsuite/gas/i386/x86-64-jump-table.s: Likewise.

ld/

PR gas/34423
* testsuite/ld-x86-64/x86-64-jump-table.s: Replace .long with
.slong.
  

Comments

Jan Beulich July 31, 2026, 8:26 a.m. UTC | #1
On 31.07.2026 01:09, H.J. Lu wrote:
> Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
> PLT32 relocation.

Why would you enforce this also for 32-bit, where the difference between
.slong and .long is entirely benign? The existing cons_sign should be
sufficient to achieve what's needed for 64-bit code.

Jan
  
H.J. Lu July 31, 2026, 8:55 a.m. UTC | #2
On Fri, Jul 31, 2026 at 4:26 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 31.07.2026 01:09, H.J. Lu wrote:
> > Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
> > PLT32 relocation.
>
> Why would you enforce this also for 32-bit, where the difference between
> .slong and .long is entirely benign? The existing cons_sign should be
> sufficient to achieve what's needed for 64-bit code.
>

I compared ".long foo@PLT - .L4":

        .section .rodata
        .p2align 2
.L4:
        .long foo1@PLT - .L4
        .long foo2@PLT - .L4
        .long foo3@PLT - .L4
        .long foo4@PLT - .L4
        .long foo1@PLT - .L5
        .long foo2@PLT - .L5
        .long foo3@PLT - .L5
        .long foo4@PLT - .L5
.L5:

vs ".slong foo@PLT - .L4":
        .section .rodata
        .p2align 2
.L4:
        .slong foo1@PLT - .L4
        .slong foo2@PLT - .L4
        .slong foo3@PLT - .L4
        .slong foo4@PLT - .L4
        .slong foo1@PLT - .L5
        .slong foo2@PLT - .L5
        .slong foo3@PLT - .L5
        .slong foo4@PLT - .L5
.L5:

in 64-bit.   The output object files are identical.  If we don't allow
".long foo@PLT - .L4" in 64-bit, we shouldn't allow it in 32-bit.
  
Jan Beulich July 31, 2026, 9:03 a.m. UTC | #3
On 31.07.2026 10:55, H.J. Lu wrote:
> On Fri, Jul 31, 2026 at 4:26 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 31.07.2026 01:09, H.J. Lu wrote:
>>> Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
>>> PLT32 relocation.
>>
>> Why would you enforce this also for 32-bit, where the difference between
>> .slong and .long is entirely benign? The existing cons_sign should be
>> sufficient to achieve what's needed for 64-bit code.
>>
> 
> I compared ".long foo@PLT - .L4":
> 
>         .section .rodata
>         .p2align 2
> .L4:
>         .long foo1@PLT - .L4
>         .long foo2@PLT - .L4
>         .long foo3@PLT - .L4
>         .long foo4@PLT - .L4
>         .long foo1@PLT - .L5
>         .long foo2@PLT - .L5
>         .long foo3@PLT - .L5
>         .long foo4@PLT - .L5
> .L5:
> 
> vs ".slong foo@PLT - .L4":
>         .section .rodata
>         .p2align 2
> .L4:
>         .slong foo1@PLT - .L4
>         .slong foo2@PLT - .L4
>         .slong foo3@PLT - .L4
>         .slong foo4@PLT - .L4
>         .slong foo1@PLT - .L5
>         .slong foo2@PLT - .L5
>         .slong foo3@PLT - .L5
>         .slong foo4@PLT - .L5
> .L5:
> 
> in 64-bit.   The output object files are identical.  If we don't allow
> ".long foo@PLT - .L4" in 64-bit, we shouldn't allow it in 32-bit.

Why? .slong was introduced because of a peculiarity of x86-64. If that
was straightforward to achieve, it may better not have been exposed to
16- and 32-bit code in the first place. While that ship has sailed,
suddenly making its use mandatory for certain constructs even outside
of 64-bit code feels outright wrong.

Jan
  
H.J. Lu July 31, 2026, 10:47 a.m. UTC | #4
On Fri, Jul 31, 2026 at 5:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 31.07.2026 10:55, H.J. Lu wrote:
> > On Fri, Jul 31, 2026 at 4:26 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 31.07.2026 01:09, H.J. Lu wrote:
> >>> Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
> >>> PLT32 relocation.
> >>
> >> Why would you enforce this also for 32-bit, where the difference between
> >> .slong and .long is entirely benign? The existing cons_sign should be
> >> sufficient to achieve what's needed for 64-bit code.
> >>
> >
> > I compared ".long foo@PLT - .L4":
> >
> >         .section .rodata
> >         .p2align 2
> > .L4:
> >         .long foo1@PLT - .L4
> >         .long foo2@PLT - .L4
> >         .long foo3@PLT - .L4
> >         .long foo4@PLT - .L4
> >         .long foo1@PLT - .L5
> >         .long foo2@PLT - .L5
> >         .long foo3@PLT - .L5
> >         .long foo4@PLT - .L5
> > .L5:
> >
> > vs ".slong foo@PLT - .L4":
> >         .section .rodata
> >         .p2align 2
> > .L4:
> >         .slong foo1@PLT - .L4
> >         .slong foo2@PLT - .L4
> >         .slong foo3@PLT - .L4
> >         .slong foo4@PLT - .L4
> >         .slong foo1@PLT - .L5
> >         .slong foo2@PLT - .L5
> >         .slong foo3@PLT - .L5
> >         .slong foo4@PLT - .L5
> > .L5:
> >
> > in 64-bit.   The output object files are identical.  If we don't allow
> > ".long foo@PLT - .L4" in 64-bit, we shouldn't allow it in 32-bit.
>
> Why? .slong was introduced because of a peculiarity of x86-64. If that
> was straightforward to achieve, it may better not have been exposed to
> 16- and 32-bit code in the first place. While that ship has sailed,
> suddenly making its use mandatory for certain constructs even outside
> of 64-bit code feels outright wrong.
>

What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
The possible reason could be wrong code.  You don't like it
doesn't count.
  
Jan Beulich July 31, 2026, 10:55 a.m. UTC | #5
On 31.07.2026 12:47, H.J. Lu wrote:
> On Fri, Jul 31, 2026 at 5:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 31.07.2026 10:55, H.J. Lu wrote:
>>> On Fri, Jul 31, 2026 at 4:26 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 31.07.2026 01:09, H.J. Lu wrote:
>>>>> Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
>>>>> PLT32 relocation.
>>>>
>>>> Why would you enforce this also for 32-bit, where the difference between
>>>> .slong and .long is entirely benign? The existing cons_sign should be
>>>> sufficient to achieve what's needed for 64-bit code.
>>>>
>>>
>>> I compared ".long foo@PLT - .L4":
>>>
>>>         .section .rodata
>>>         .p2align 2
>>> .L4:
>>>         .long foo1@PLT - .L4
>>>         .long foo2@PLT - .L4
>>>         .long foo3@PLT - .L4
>>>         .long foo4@PLT - .L4
>>>         .long foo1@PLT - .L5
>>>         .long foo2@PLT - .L5
>>>         .long foo3@PLT - .L5
>>>         .long foo4@PLT - .L5
>>> .L5:
>>>
>>> vs ".slong foo@PLT - .L4":
>>>         .section .rodata
>>>         .p2align 2
>>> .L4:
>>>         .slong foo1@PLT - .L4
>>>         .slong foo2@PLT - .L4
>>>         .slong foo3@PLT - .L4
>>>         .slong foo4@PLT - .L4
>>>         .slong foo1@PLT - .L5
>>>         .slong foo2@PLT - .L5
>>>         .slong foo3@PLT - .L5
>>>         .slong foo4@PLT - .L5
>>> .L5:
>>>
>>> in 64-bit.   The output object files are identical.  If we don't allow
>>> ".long foo@PLT - .L4" in 64-bit, we shouldn't allow it in 32-bit.
>>
>> Why? .slong was introduced because of a peculiarity of x86-64. If that
>> was straightforward to achieve, it may better not have been exposed to
>> 16- and 32-bit code in the first place. While that ship has sailed,
>> suddenly making its use mandatory for certain constructs even outside
>> of 64-bit code feels outright wrong.
> 
> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
> The possible reason could be wrong code.  You don't like it
> doesn't count.

It's not a matter of liking it (or not). The distinction between both is
what relocation is (supposed to be) used when one is needed. .long should
only ever use zero-extending ones; .slong was added such that want for a
sign-extending one can be expressed. Without distinct directives, the
assembler has to guess, and such guessing can only go wrong. I'm pretty
certain this isn't properly dealt with everywhere, but when adding new
functionality we shouldn't extend existing flaws.

Jan
  
H.J. Lu July 31, 2026, 9:03 p.m. UTC | #6
On Fri, Jul 31, 2026 at 6:55 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 31.07.2026 12:47, H.J. Lu wrote:
> > On Fri, Jul 31, 2026 at 5:03 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 31.07.2026 10:55, H.J. Lu wrote:
> >>> On Fri, Jul 31, 2026 at 4:26 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 31.07.2026 01:09, H.J. Lu wrote:
> >>>>> Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
> >>>>> PLT32 relocation.
> >>>>
> >>>> Why would you enforce this also for 32-bit, where the difference between
> >>>> .slong and .long is entirely benign? The existing cons_sign should be
> >>>> sufficient to achieve what's needed for 64-bit code.
> >>>>
> >>>
> >>> I compared ".long foo@PLT - .L4":
> >>>
> >>>         .section .rodata
> >>>         .p2align 2
> >>> .L4:
> >>>         .long foo1@PLT - .L4
> >>>         .long foo2@PLT - .L4
> >>>         .long foo3@PLT - .L4
> >>>         .long foo4@PLT - .L4
> >>>         .long foo1@PLT - .L5
> >>>         .long foo2@PLT - .L5
> >>>         .long foo3@PLT - .L5
> >>>         .long foo4@PLT - .L5
> >>> .L5:
> >>>
> >>> vs ".slong foo@PLT - .L4":
> >>>         .section .rodata
> >>>         .p2align 2
> >>> .L4:
> >>>         .slong foo1@PLT - .L4
> >>>         .slong foo2@PLT - .L4
> >>>         .slong foo3@PLT - .L4
> >>>         .slong foo4@PLT - .L4
> >>>         .slong foo1@PLT - .L5
> >>>         .slong foo2@PLT - .L5
> >>>         .slong foo3@PLT - .L5
> >>>         .slong foo4@PLT - .L5
> >>> .L5:
> >>>
> >>> in 64-bit.   The output object files are identical.  If we don't allow
> >>> ".long foo@PLT - .L4" in 64-bit, we shouldn't allow it in 32-bit.
> >>
> >> Why? .slong was introduced because of a peculiarity of x86-64. If that
> >> was straightforward to achieve, it may better not have been exposed to
> >> 16- and 32-bit code in the first place. While that ship has sailed,
> >> suddenly making its use mandatory for certain constructs even outside
> >> of 64-bit code feels outright wrong.
> >
> > What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
> > The possible reason could be wrong code.  You don't like it
> > doesn't count.
>
> It's not a matter of liking it (or not). The distinction between both is
> what relocation is (supposed to be) used when one is needed. .long should
> only ever use zero-extending ones; .slong was added such that want for a
> sign-extending one can be expressed. Without distinct directives, the
> assembler has to guess, and such guessing can only go wrong. I'm pretty
> certain this isn't properly dealt with everywhere, but when adding new
> functionality we shouldn't extend existing flaws.
>
> Jan

Given that there are no issues with ".long foo - .L4",
".long foo1@PLT - .L4" should have no issues at all.
If you believe that it isn't true, please show me a case.
  
Maciej W. Rozycki Aug. 1, 2026, 1:47 p.m. UTC | #7
On Sat, 1 Aug 2026, H.J. Lu wrote:

> > >> Why? .slong was introduced because of a peculiarity of x86-64. If that
> > >> was straightforward to achieve, it may better not have been exposed to
> > >> 16- and 32-bit code in the first place. While that ship has sailed,
> > >> suddenly making its use mandatory for certain constructs even outside
> > >> of 64-bit code feels outright wrong.
> > > 
> > > What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
> > > The possible reason could be wrong code.  You don't like it
> > > doesn't count.
> >
> > It's not a matter of liking it (or not). The distinction between both is
> > what relocation is (supposed to be) used when one is needed. .long should
> > only ever use zero-extending ones; .slong was added such that want for a
> > sign-extending one can be expressed. Without distinct directives, the
> > assembler has to guess, and such guessing can only go wrong. I'm pretty
> > certain this isn't properly dealt with everywhere, but when adding new
> > functionality we shouldn't extend existing flaws.
> >
> > Jan
> 
> Given that there are no issues with ".long foo - .L4",
> ".long foo1@PLT - .L4" should have no issues at all.
> If you believe that it isn't true, please show me a case.

 I gather this is about the overflow case, handled differently depending 
on the signedness or the lack of, of the datum relocated by the static 
linker or dynamic loader as appropriate.

 Jan, please correct me if I'm wrong since commit d182319b0955 has no 
change description and there's no documentation for `.slong' in the GAS 
manual either.  What are the x86 psABI ELF relocation types corresponding 
to `.long' and `.slong' respectively in this context?

  Maciej
  
Jan Beulich Aug. 3, 2026, 6:44 a.m. UTC | #8
On 01.08.2026 15:47, Maciej W. Rozycki wrote:
> On Sat, 1 Aug 2026, H.J. Lu wrote:
> 
>>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
>>>>> was straightforward to achieve, it may better not have been exposed to
>>>>> 16- and 32-bit code in the first place. While that ship has sailed,
>>>>> suddenly making its use mandatory for certain constructs even outside
>>>>> of 64-bit code feels outright wrong.
>>>>
>>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
>>>> The possible reason could be wrong code.  You don't like it
>>>> doesn't count.
>>>
>>> It's not a matter of liking it (or not). The distinction between both is
>>> what relocation is (supposed to be) used when one is needed. .long should
>>> only ever use zero-extending ones; .slong was added such that want for a
>>> sign-extending one can be expressed. Without distinct directives, the
>>> assembler has to guess, and such guessing can only go wrong. I'm pretty
>>> certain this isn't properly dealt with everywhere, but when adding new
>>> functionality we shouldn't extend existing flaws.
>>
>> Given that there are no issues with ".long foo - .L4",
>> ".long foo1@PLT - .L4" should have no issues at all.
>> If you believe that it isn't true, please show me a case.
> 
>  I gather this is about the overflow case, handled differently depending 
> on the signedness or the lack of, of the datum relocated by the static 
> linker or dynamic loader as appropriate.
> 
>  Jan, please correct me if I'm wrong since commit d182319b0955 has no 
> change description and there's no documentation for `.slong' in the GAS 
> manual either.  What are the x86 psABI ELF relocation types corresponding 
> to `.long' and `.slong' respectively in this context?

For .long there simply is no correct relocation type to use for PLT (and,
fwiw, simple PC-relative) expressions. The correct type to use is
R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).

For the simple PC-rel case we simply cannot require use of .slong, as we've
been accepting .long (then guessing that .slong was meant). Else we'd very
likely break existing code. Since @PLT was rejected so far when used with
.long and .slong, doing better here is imo very desirable (if not
imperative).

Jan
  
Jan Beulich Aug. 3, 2026, 6:48 a.m. UTC | #9
On 31.07.2026 23:03, H.J. Lu wrote:
> On Fri, Jul 31, 2026 at 6:55 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 31.07.2026 12:47, H.J. Lu wrote:
>>> On Fri, Jul 31, 2026 at 5:03 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 31.07.2026 10:55, H.J. Lu wrote:
>>>>> On Fri, Jul 31, 2026 at 4:26 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>>>
>>>>>> On 31.07.2026 01:09, H.J. Lu wrote:
>>>>>>> Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
>>>>>>> PLT32 relocation.
>>>>>>
>>>>>> Why would you enforce this also for 32-bit, where the difference between
>>>>>> .slong and .long is entirely benign? The existing cons_sign should be
>>>>>> sufficient to achieve what's needed for 64-bit code.
>>>>>>
>>>>>
>>>>> I compared ".long foo@PLT - .L4":
>>>>>
>>>>>         .section .rodata
>>>>>         .p2align 2
>>>>> .L4:
>>>>>         .long foo1@PLT - .L4
>>>>>         .long foo2@PLT - .L4
>>>>>         .long foo3@PLT - .L4
>>>>>         .long foo4@PLT - .L4
>>>>>         .long foo1@PLT - .L5
>>>>>         .long foo2@PLT - .L5
>>>>>         .long foo3@PLT - .L5
>>>>>         .long foo4@PLT - .L5
>>>>> .L5:
>>>>>
>>>>> vs ".slong foo@PLT - .L4":
>>>>>         .section .rodata
>>>>>         .p2align 2
>>>>> .L4:
>>>>>         .slong foo1@PLT - .L4
>>>>>         .slong foo2@PLT - .L4
>>>>>         .slong foo3@PLT - .L4
>>>>>         .slong foo4@PLT - .L4
>>>>>         .slong foo1@PLT - .L5
>>>>>         .slong foo2@PLT - .L5
>>>>>         .slong foo3@PLT - .L5
>>>>>         .slong foo4@PLT - .L5
>>>>> .L5:
>>>>>
>>>>> in 64-bit.   The output object files are identical.  If we don't allow
>>>>> ".long foo@PLT - .L4" in 64-bit, we shouldn't allow it in 32-bit.
>>>>
>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
>>>> was straightforward to achieve, it may better not have been exposed to
>>>> 16- and 32-bit code in the first place. While that ship has sailed,
>>>> suddenly making its use mandatory for certain constructs even outside
>>>> of 64-bit code feels outright wrong.
>>>
>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
>>> The possible reason could be wrong code.  You don't like it
>>> doesn't count.
>>
>> It's not a matter of liking it (or not). The distinction between both is
>> what relocation is (supposed to be) used when one is needed. .long should
>> only ever use zero-extending ones; .slong was added such that want for a
>> sign-extending one can be expressed. Without distinct directives, the
>> assembler has to guess, and such guessing can only go wrong. I'm pretty
>> certain this isn't properly dealt with everywhere, but when adding new
>> functionality we shouldn't extend existing flaws.
> 
> Given that there are no issues with ".long foo - .L4",
> ".long foo1@PLT - .L4" should have no issues at all.
> If you believe that it isn't true, please show me a case.

WDYM by "there are no issues"? There is a very obvious issue: It is wrong
to assemble without error. Hence "please show me a case" is an impossible
thing to ask for. Any possible use is wrong (until such time that a
suitable relocation type is added, which very likely is "never").

The very, very farthest I might go to make a compromise would be for the
diagnostic to be a warning in place of an error. Yet that would still feel
wrong to me.

Jan
  
H.J. Lu Aug. 3, 2026, 7:22 a.m. UTC | #10
On Mon, Aug 3, 2026 at 2:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 01.08.2026 15:47, Maciej W. Rozycki wrote:
> > On Sat, 1 Aug 2026, H.J. Lu wrote:
> >
> >>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
> >>>>> was straightforward to achieve, it may better not have been exposed to
> >>>>> 16- and 32-bit code in the first place. While that ship has sailed,
> >>>>> suddenly making its use mandatory for certain constructs even outside
> >>>>> of 64-bit code feels outright wrong.
> >>>>
> >>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
> >>>> The possible reason could be wrong code.  You don't like it
> >>>> doesn't count.
> >>>
> >>> It's not a matter of liking it (or not). The distinction between both is
> >>> what relocation is (supposed to be) used when one is needed. .long should
> >>> only ever use zero-extending ones; .slong was added such that want for a
> >>> sign-extending one can be expressed. Without distinct directives, the
> >>> assembler has to guess, and such guessing can only go wrong. I'm pretty
> >>> certain this isn't properly dealt with everywhere, but when adding new
> >>> functionality we shouldn't extend existing flaws.
> >>
> >> Given that there are no issues with ".long foo - .L4",
> >> ".long foo1@PLT - .L4" should have no issues at all.
> >> If you believe that it isn't true, please show me a case.
> >
> >  I gather this is about the overflow case, handled differently depending
> > on the signedness or the lack of, of the datum relocated by the static
> > linker or dynamic loader as appropriate.
> >
> >  Jan, please correct me if I'm wrong since commit d182319b0955 has no
> > change description and there's no documentation for `.slong' in the GAS
> > manual either.  What are the x86 psABI ELF relocation types corresponding
> > to `.long' and `.slong' respectively in this context?
>
> For .long there simply is no correct relocation type to use for PLT (and,
> fwiw, simple PC-relative) expressions. The correct type to use is
> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).
>
> For the simple PC-rel case we simply cannot require use of .slong, as we've
> been accepting .long (then guessing that .slong was meant). Else we'd very
> likely break existing code. Since @PLT was rejected so far when used with
> .long and .slong, doing better here is imo very desirable (if not
> imperative).
>

Because assembler has been correctly generating R_X86_64_PC32 for
".long foo - .L4", it is perfectly correct to generate R_X86_64_PLT32 for
".long foo@PLT - .L4".


--
H.J.
  
Jan Beulich Aug. 3, 2026, 7:35 a.m. UTC | #11
On 03.08.2026 09:22, H.J. Lu wrote:
> On Mon, Aug 3, 2026 at 2:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 01.08.2026 15:47, Maciej W. Rozycki wrote:
>>> On Sat, 1 Aug 2026, H.J. Lu wrote:
>>>
>>>>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
>>>>>>> was straightforward to achieve, it may better not have been exposed to
>>>>>>> 16- and 32-bit code in the first place. While that ship has sailed,
>>>>>>> suddenly making its use mandatory for certain constructs even outside
>>>>>>> of 64-bit code feels outright wrong.
>>>>>>
>>>>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
>>>>>> The possible reason could be wrong code.  You don't like it
>>>>>> doesn't count.
>>>>>
>>>>> It's not a matter of liking it (or not). The distinction between both is
>>>>> what relocation is (supposed to be) used when one is needed. .long should
>>>>> only ever use zero-extending ones; .slong was added such that want for a
>>>>> sign-extending one can be expressed. Without distinct directives, the
>>>>> assembler has to guess, and such guessing can only go wrong. I'm pretty
>>>>> certain this isn't properly dealt with everywhere, but when adding new
>>>>> functionality we shouldn't extend existing flaws.
>>>>
>>>> Given that there are no issues with ".long foo - .L4",
>>>> ".long foo1@PLT - .L4" should have no issues at all.
>>>> If you believe that it isn't true, please show me a case.
>>>
>>>  I gather this is about the overflow case, handled differently depending
>>> on the signedness or the lack of, of the datum relocated by the static
>>> linker or dynamic loader as appropriate.
>>>
>>>  Jan, please correct me if I'm wrong since commit d182319b0955 has no
>>> change description and there's no documentation for `.slong' in the GAS
>>> manual either.  What are the x86 psABI ELF relocation types corresponding
>>> to `.long' and `.slong' respectively in this context?
>>
>> For .long there simply is no correct relocation type to use for PLT (and,
>> fwiw, simple PC-relative) expressions. The correct type to use is
>> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).
>>
>> For the simple PC-rel case we simply cannot require use of .slong, as we've
>> been accepting .long (then guessing that .slong was meant). Else we'd very
>> likely break existing code. Since @PLT was rejected so far when used with
>> .long and .slong, doing better here is imo very desirable (if not
>> imperative).
>>
> 
> Because assembler has been correctly generating R_X86_64_PC32 for
> ".long foo - .L4",

What, again, does "correctly" mean here? We need to retain this incorrect
behavior, yes, but that doesn't mean we should extend it to other constructs.

Jan

> it is perfectly correct to generate R_X86_64_PLT32 for
> ".long foo@PLT - .L4".
> 
> 
> --
> H.J.
  
Jan Beulich Aug. 3, 2026, 7:35 a.m. UTC | #12
On 03.08.2026 09:22, H.J. Lu wrote:
> On Mon, Aug 3, 2026 at 2:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 01.08.2026 15:47, Maciej W. Rozycki wrote:
>>> On Sat, 1 Aug 2026, H.J. Lu wrote:
>>>
>>>>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
>>>>>>> was straightforward to achieve, it may better not have been exposed to
>>>>>>> 16- and 32-bit code in the first place. While that ship has sailed,
>>>>>>> suddenly making its use mandatory for certain constructs even outside
>>>>>>> of 64-bit code feels outright wrong.
>>>>>>
>>>>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
>>>>>> The possible reason could be wrong code.  You don't like it
>>>>>> doesn't count.
>>>>>
>>>>> It's not a matter of liking it (or not). The distinction between both is
>>>>> what relocation is (supposed to be) used when one is needed. .long should
>>>>> only ever use zero-extending ones; .slong was added such that want for a
>>>>> sign-extending one can be expressed. Without distinct directives, the
>>>>> assembler has to guess, and such guessing can only go wrong. I'm pretty
>>>>> certain this isn't properly dealt with everywhere, but when adding new
>>>>> functionality we shouldn't extend existing flaws.
>>>>
>>>> Given that there are no issues with ".long foo - .L4",
>>>> ".long foo1@PLT - .L4" should have no issues at all.
>>>> If you believe that it isn't true, please show me a case.
>>>
>>>  I gather this is about the overflow case, handled differently depending
>>> on the signedness or the lack of, of the datum relocated by the static
>>> linker or dynamic loader as appropriate.
>>>
>>>  Jan, please correct me if I'm wrong since commit d182319b0955 has no
>>> change description and there's no documentation for `.slong' in the GAS
>>> manual either.  What are the x86 psABI ELF relocation types corresponding
>>> to `.long' and `.slong' respectively in this context?
>>
>> For .long there simply is no correct relocation type to use for PLT (and,
>> fwiw, simple PC-relative) expressions. The correct type to use is
>> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).
>>
>> For the simple PC-rel case we simply cannot require use of .slong, as we've
>> been accepting .long (then guessing that .slong was meant). Else we'd very
>> likely break existing code. Since @PLT was rejected so far when used with
>> .long and .slong, doing better here is imo very desirable (if not
>> imperative).
>>
> 
> Because assembler has been correctly generating R_X86_64_PC32 for
> ".long foo - .L4",

What, again, does "correctly" mean here? We need to retain this incorrect
behavior, yes, but that doesn't mean we should extend it to other constructs.

Jan

> it is perfectly correct to generate R_X86_64_PLT32 for
> ".long foo@PLT - .L4".
> 
> 
> --
> H.J.
  
H.J. Lu Aug. 3, 2026, 8:52 a.m. UTC | #13
On Mon, Aug 3, 2026 at 3:35 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 03.08.2026 09:22, H.J. Lu wrote:
> > On Mon, Aug 3, 2026 at 2:44 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 01.08.2026 15:47, Maciej W. Rozycki wrote:
> >>> On Sat, 1 Aug 2026, H.J. Lu wrote:
> >>>
> >>>>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
> >>>>>>> was straightforward to achieve, it may better not have been exposed to
> >>>>>>> 16- and 32-bit code in the first place. While that ship has sailed,
> >>>>>>> suddenly making its use mandatory for certain constructs even outside
> >>>>>>> of 64-bit code feels outright wrong.
> >>>>>>
> >>>>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
> >>>>>> The possible reason could be wrong code.  You don't like it
> >>>>>> doesn't count.
> >>>>>
> >>>>> It's not a matter of liking it (or not). The distinction between both is
> >>>>> what relocation is (supposed to be) used when one is needed. .long should
> >>>>> only ever use zero-extending ones; .slong was added such that want for a
> >>>>> sign-extending one can be expressed. Without distinct directives, the
> >>>>> assembler has to guess, and such guessing can only go wrong. I'm pretty
> >>>>> certain this isn't properly dealt with everywhere, but when adding new
> >>>>> functionality we shouldn't extend existing flaws.
> >>>>
> >>>> Given that there are no issues with ".long foo - .L4",
> >>>> ".long foo1@PLT - .L4" should have no issues at all.
> >>>> If you believe that it isn't true, please show me a case.
> >>>
> >>>  I gather this is about the overflow case, handled differently depending
> >>> on the signedness or the lack of, of the datum relocated by the static
> >>> linker or dynamic loader as appropriate.
> >>>
> >>>  Jan, please correct me if I'm wrong since commit d182319b0955 has no
> >>> change description and there's no documentation for `.slong' in the GAS
> >>> manual either.  What are the x86 psABI ELF relocation types corresponding
> >>> to `.long' and `.slong' respectively in this context?
> >>
> >> For .long there simply is no correct relocation type to use for PLT (and,
> >> fwiw, simple PC-relative) expressions. The correct type to use is
> >> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).
> >>
> >> For the simple PC-rel case we simply cannot require use of .slong, as we've
> >> been accepting .long (then guessing that .slong was meant). Else we'd very
> >> likely break existing code. Since @PLT was rejected so far when used with
> >> .long and .slong, doing better here is imo very desirable (if not
> >> imperative).
> >>
> >
> > Because assembler has been correctly generating R_X86_64_PC32 for
> > ".long foo - .L4",
>
> What, again, does "correctly" mean here? We need to retain this incorrect
> behavior, yes, but that doesn't mean we should extend it to other constructs.

Call it "incorrect behavior"  is your opinion.  I certainly disagree.
Given that it
has been used this way from day one, it is the correct behavior for x86-64.
  
Jan Beulich Aug. 3, 2026, 9:01 a.m. UTC | #14
On 03.08.2026 10:52, H.J. Lu wrote:
> On Mon, Aug 3, 2026 at 3:35 PM Jan Beulich <jbeulich@suse.com> wrote:
>>
>> On 03.08.2026 09:22, H.J. Lu wrote:
>>> On Mon, Aug 3, 2026 at 2:44 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>
>>>> On 01.08.2026 15:47, Maciej W. Rozycki wrote:
>>>>> On Sat, 1 Aug 2026, H.J. Lu wrote:
>>>>>
>>>>>>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
>>>>>>>>> was straightforward to achieve, it may better not have been exposed to
>>>>>>>>> 16- and 32-bit code in the first place. While that ship has sailed,
>>>>>>>>> suddenly making its use mandatory for certain constructs even outside
>>>>>>>>> of 64-bit code feels outright wrong.
>>>>>>>>
>>>>>>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
>>>>>>>> The possible reason could be wrong code.  You don't like it
>>>>>>>> doesn't count.
>>>>>>>
>>>>>>> It's not a matter of liking it (or not). The distinction between both is
>>>>>>> what relocation is (supposed to be) used when one is needed. .long should
>>>>>>> only ever use zero-extending ones; .slong was added such that want for a
>>>>>>> sign-extending one can be expressed. Without distinct directives, the
>>>>>>> assembler has to guess, and such guessing can only go wrong. I'm pretty
>>>>>>> certain this isn't properly dealt with everywhere, but when adding new
>>>>>>> functionality we shouldn't extend existing flaws.
>>>>>>
>>>>>> Given that there are no issues with ".long foo - .L4",
>>>>>> ".long foo1@PLT - .L4" should have no issues at all.
>>>>>> If you believe that it isn't true, please show me a case.
>>>>>
>>>>>  I gather this is about the overflow case, handled differently depending
>>>>> on the signedness or the lack of, of the datum relocated by the static
>>>>> linker or dynamic loader as appropriate.
>>>>>
>>>>>  Jan, please correct me if I'm wrong since commit d182319b0955 has no
>>>>> change description and there's no documentation for `.slong' in the GAS
>>>>> manual either.  What are the x86 psABI ELF relocation types corresponding
>>>>> to `.long' and `.slong' respectively in this context?
>>>>
>>>> For .long there simply is no correct relocation type to use for PLT (and,
>>>> fwiw, simple PC-relative) expressions. The correct type to use is
>>>> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).
>>>>
>>>> For the simple PC-rel case we simply cannot require use of .slong, as we've
>>>> been accepting .long (then guessing that .slong was meant). Else we'd very
>>>> likely break existing code. Since @PLT was rejected so far when used with
>>>> .long and .slong, doing better here is imo very desirable (if not
>>>> imperative).
>>>>
>>>
>>> Because assembler has been correctly generating R_X86_64_PC32 for
>>> ".long foo - .L4",
>>
>> What, again, does "correctly" mean here? We need to retain this incorrect
>> behavior, yes, but that doesn't mean we should extend it to other constructs.
> 
> Call it "incorrect behavior"  is your opinion.  I certainly disagree.
> Given that it
> has been used this way from day one, it is the correct behavior for x86-64.

How can it be correct if it would break if a suitable relocation was introduced?
Just because it has been this way from the start of x86-64 doesn't mean it was
right. There are many things which needed correction later one One of them being
the original lack of .slong.

Jan
  
H.J. Lu Aug. 3, 2026, 9:16 a.m. UTC | #15
On Mon, Aug 3, 2026 at 5:01 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 03.08.2026 10:52, H.J. Lu wrote:
> > On Mon, Aug 3, 2026 at 3:35 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>
> >> On 03.08.2026 09:22, H.J. Lu wrote:
> >>> On Mon, Aug 3, 2026 at 2:44 PM Jan Beulich <jbeulich@suse.com> wrote:
> >>>>
> >>>> On 01.08.2026 15:47, Maciej W. Rozycki wrote:
> >>>>> On Sat, 1 Aug 2026, H.J. Lu wrote:
> >>>>>
> >>>>>>>>> Why? .slong was introduced because of a peculiarity of x86-64. If that
> >>>>>>>>> was straightforward to achieve, it may better not have been exposed to
> >>>>>>>>> 16- and 32-bit code in the first place. While that ship has sailed,
> >>>>>>>>> suddenly making its use mandatory for certain constructs even outside
> >>>>>>>>> of 64-bit code feels outright wrong.
> >>>>>>>>
> >>>>>>>> What is wrong with using " .long foo4@PLT - .L4" in 64-bit?
> >>>>>>>> The possible reason could be wrong code.  You don't like it
> >>>>>>>> doesn't count.
> >>>>>>>
> >>>>>>> It's not a matter of liking it (or not). The distinction between both is
> >>>>>>> what relocation is (supposed to be) used when one is needed. .long should
> >>>>>>> only ever use zero-extending ones; .slong was added such that want for a
> >>>>>>> sign-extending one can be expressed. Without distinct directives, the
> >>>>>>> assembler has to guess, and such guessing can only go wrong. I'm pretty
> >>>>>>> certain this isn't properly dealt with everywhere, but when adding new
> >>>>>>> functionality we shouldn't extend existing flaws.
> >>>>>>
> >>>>>> Given that there are no issues with ".long foo - .L4",
> >>>>>> ".long foo1@PLT - .L4" should have no issues at all.
> >>>>>> If you believe that it isn't true, please show me a case.
> >>>>>
> >>>>>  I gather this is about the overflow case, handled differently depending
> >>>>> on the signedness or the lack of, of the datum relocated by the static
> >>>>> linker or dynamic loader as appropriate.
> >>>>>
> >>>>>  Jan, please correct me if I'm wrong since commit d182319b0955 has no
> >>>>> change description and there's no documentation for `.slong' in the GAS
> >>>>> manual either.  What are the x86 psABI ELF relocation types corresponding
> >>>>> to `.long' and `.slong' respectively in this context?
> >>>>
> >>>> For .long there simply is no correct relocation type to use for PLT (and,
> >>>> fwiw, simple PC-relative) expressions. The correct type to use is
> >>>> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).
> >>>>
> >>>> For the simple PC-rel case we simply cannot require use of .slong, as we've
> >>>> been accepting .long (then guessing that .slong was meant). Else we'd very
> >>>> likely break existing code. Since @PLT was rejected so far when used with
> >>>> .long and .slong, doing better here is imo very desirable (if not
> >>>> imperative).
> >>>>
> >>>
> >>> Because assembler has been correctly generating R_X86_64_PC32 for
> >>> ".long foo - .L4",
> >>
> >> What, again, does "correctly" mean here? We need to retain this incorrect
> >> behavior, yes, but that doesn't mean we should extend it to other constructs.
> >
> > Call it "incorrect behavior"  is your opinion.  I certainly disagree.
> > Given that it
> > has been used this way from day one, it is the correct behavior for x86-64.
>
> How can it be correct if it would break if a suitable relocation was introduced?
> Just because it has been this way from the start of x86-64 doesn't mean it was
> right. There are many things which needed correction later one One of them being
> the original lack of .slong.

That is purely your opinion.   I don't think correction is needed on this.
  
Maciej W. Rozycki Aug. 3, 2026, 5:46 p.m. UTC | #16
On Mon, 3 Aug 2026, H.J. Lu wrote:

> > >>>>>  Jan, please correct me if I'm wrong since commit d182319b0955 has no
> > >>>>> change description and there's no documentation for `.slong' in the GAS
> > >>>>> manual either.  What are the x86 psABI ELF relocation types corresponding
> > >>>>> to `.long' and `.slong' respectively in this context?
> > >>>>
> > >>>> For .long there simply is no correct relocation type to use for PLT (and,
> > >>>> fwiw, simple PC-relative) expressions. The correct type to use is
> > >>>> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).

 Would you please provide me with the calculation R_X86_64_PLT32 stands 
for and what the calculation required would be for `.long' should we have 
an actual relocation representing this operation?  Also what is the linker 
expected by the psABI to do on an overflow condition?

> > >>>> For the simple PC-rel case we simply cannot require use of .slong, as we've
> > >>>> been accepting .long (then guessing that .slong was meant). Else we'd very
> > >>>> likely break existing code. Since @PLT was rejected so far when used with
> > >>>> .long and .slong, doing better here is imo very desirable (if not
> > >>>> imperative).

 Ack, understood, although would perhaps an assembly warning be in order?  
Does this case typically come from handwritten assembly or one of compiled 
origin?

> > How can it be correct if it would break if a suitable relocation was introduced?
> > Just because it has been this way from the start of x86-64 doesn't mean it was
> > right. There are many things which needed correction later one One of them being
> > the original lack of .slong.
> 
> That is purely your opinion.   I don't think correction is needed on this.

 I don't find it a matter of anyone's opinion.  Relocations are deferred 
calculation operators for expressions that cannot be resolved at assembly 
time and these operators need to match the calculation requested at the 
assembly level.

 I gather the difference between `.long' and `.slong' here is analogous to 
MOVZX vs MOVSX (speaking in terms of machine operations) combined with a 
further calculation (to be hopefully clarified by Jan) implied by the use 
of a PLT reference as per the psABI.  It seems to me that expressing both 
calculations with just one relocation operation is self-contradictory.

 Am I missing something here?

  Maciej
  
Jan Beulich Aug. 4, 2026, 7:59 a.m. UTC | #17
On 03.08.2026 19:46, Maciej W. Rozycki wrote:
> On Mon, 3 Aug 2026, H.J. Lu wrote:
> 
>>>>>>>>  Jan, please correct me if I'm wrong since commit d182319b0955 has no
>>>>>>>> change description and there's no documentation for `.slong' in the GAS
>>>>>>>> manual either.  What are the x86 psABI ELF relocation types corresponding
>>>>>>>> to `.long' and `.slong' respectively in this context?
>>>>>>>
>>>>>>> For .long there simply is no correct relocation type to use for PLT (and,
>>>>>>> fwiw, simple PC-relative) expressions. The correct type to use is
>>>>>>> R_X86_64_PLT32 (and R_X86_64_PC32 for the simple PC-rel case).
> 
>  Would you please provide me with the calculation R_X86_64_PLT32 stands 
> for and what the calculation required would be for `.long' should we have 
> an actual relocation representing this operation?

L + A - P

with the usual meaning of

L - address of PLT entry for the referenced symbol
A - addend
P - address of the storage unit being relocated

>  Also what is the linker 
> expected by the psABI to do on an overflow condition?

Since the result has to be a valid (64-bit) address, sign-extension is
necessary, and hence the overflow condition has to match that (starting
from the 32-bit input field).

>>>>>>> For the simple PC-rel case we simply cannot require use of .slong, as we've
>>>>>>> been accepting .long (then guessing that .slong was meant). Else we'd very
>>>>>>> likely break existing code. Since @PLT was rejected so far when used with
>>>>>>> .long and .slong, doing better here is imo very desirable (if not
>>>>>>> imperative).
> 
>  Ack, understood, although would perhaps an assembly warning be in order?  
> Does this case typically come from handwritten assembly or one of compiled 
> origin?

Both, hence imo a warning is out of question.

Jan
  

Patch

From ee1a066d1b41d82c2e6a67fc749fef7c2e8868bf Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 31 Jul 2026 07:00:52 +0800
Subject: [PATCH] x86: Disallow ".long foo@PLT - .L4" for PLT32 relocation

Disallow ".long foo@PLT - .L4" and only allow ".slong foo@PLT - .L4" for
PLT32 relocation.

gas/

	PR gas/34423
	* config/tc-i386.c (cons_slong): New.
	(x86_cons): Return BFD_RELOC_X86_64_PC32_TO_PLT32 or
	BFD_RELOC_386_PC32_TO_PLT32 only if cons_slong is true.
	(signed_cons): Set cons_slong to true before calling cons and
	set it to false afterwards.
	(tc_gen_reloc): Update BFD_RELOC_X86_64_PC32_TO_PLT32 comments.
	* testsuite/gas/i386/ilp32/reloc64.l: Revert commit 53902b30c66.
	* testsuite/gas/i386/ilp32/reloc64.s: Likewise.
	* testsuite/gas/i386/reloc32.l: Likewise.
	* testsuite/gas/i386/reloc32.s: Likewise.
	* testsuite/gas/i386/reloc64.l: Likewise.
	* testsuite/gas/i386/plt.s: Replace .long with .slong.
	* testsuite/gas/i386/x86-64-jump-table.s: Likewise.

ld/

	PR gas/34423
	* testsuite/ld-x86-64/x86-64-jump-table.s: Replace .long with
	.slong.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 gas/config/tc-i386.c                       | 12 +++++++++---
 gas/testsuite/gas/i386/ilp32/reloc64.l     |  3 ++-
 gas/testsuite/gas/i386/ilp32/reloc64.s     |  2 +-
 gas/testsuite/gas/i386/plt.s               |  8 ++++----
 gas/testsuite/gas/i386/reloc32.l           |  4 ++--
 gas/testsuite/gas/i386/reloc32.s           |  2 +-
 gas/testsuite/gas/i386/reloc64.l           |  3 ++-
 gas/testsuite/gas/i386/reloc64.s           |  2 +-
 gas/testsuite/gas/i386/x86-64-jump-table.s | 10 +++++-----
 ld/testsuite/ld-x86-64/x86-64-jump-table.s | 10 +++++-----
 10 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 67badd29298..b61e1eb49e6 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -13374,6 +13374,10 @@  output_imm (fragS *insn_start_frag, offsetT insn_start_off)
    reloc is needed.  We use this hook to get the correct .got reloc.  */
 static int cons_sign = -1;
 
+/* This hook is used by x86_cons to allow ".slong foo@PLT - .L4", but
+   not ".long foo@PLT - .L4".  */
+static bool cons_slong = false;
+
 void
 x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
 		  expressionS *exp, bfd_reloc_code_real_type r)
@@ -13553,10 +13557,10 @@  x86_cons (expressionS *exp, int size)
 		    || got_reloc == BFD_RELOC_32_PLT_PCREL)
 		   && exp->X_op != O_symbol)
 	    {
-	    /* Allow directives like ".long foo@PLT - .L4".
+	    /* Allow directives like ".slong foo@PLT - .L4".
 	       BFD_RELOC_X86_64_PC32_TO_PLT32 has an explicit addend and
 	       BFD_RELOC_386_PC32_TO_PLT32 has an implicit addend.  */
-	      if (size == 4 && exp->X_op == O_subtract)
+	      if (cons_slong && size == 4 && exp->X_op == O_subtract)
 		got_reloc = (object_64bit
 			     ? BFD_RELOC_X86_64_PC32_TO_PLT32
 			     : BFD_RELOC_386_PC32_TO_PLT32);
@@ -13592,7 +13596,9 @@  signed_cons (int size)
 {
   if (object_64bit)
     cons_sign = 1;
+  cons_slong = true;
   cons (size);
+  cons_slong = false;
   cons_sign = -1;
 }
 
@@ -18770,7 +18776,7 @@  tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 	    rel->addend = fixp->fx_offset - fixp->fx_size;
 	    break;
 	  case BFD_RELOC_X86_64_PC32_TO_PLT32:
-	    /* This came from a directive like ".long foo@PLT - .L4".
+	    /* This came from a directive like ".slong foo@PLT - .L4".
 	       Generate R_X86_64_PLT32 with addend computed like
 	       R_X86_64_PC32 so that PLT entry is used to resolve
 	       this PC32 relocation.   */
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.l b/gas/testsuite/gas/i386/ilp32/reloc64.l
index 08c2702cdb7..14a111d763f 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.l
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.l
@@ -103,6 +103,8 @@ 
 .*:176:  Info: .*
 .*:3: Error: .*
 .*:177:  Info: .*
+.*:3: Error: .*
+.*:190:  Info: .*
 .*:193: Error: .* too large for field of 4 bytes at .*
 .*:194: Error: .* too large for field of 4 bytes at .*
 .*:195: Error: .* too large for field of 4 bytes at .*
@@ -111,7 +113,6 @@ 
 .*:197: Error: .* too large for field of 1 byte at .*
 .*:198: Error: .* too large for field of 2 bytes at .*
 .*:198: Error: .* too large for field of 1 byte at .*
-.*:190: Error: can't resolve xtrn - _start
 .*:201: Error: .* too large for field of 4 bytes at .*
 .*:202: Error: .* too large for field of 2 bytes at .*
 .*:203: Error: .* too large for field of 2 bytes at .*
diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.s b/gas/testsuite/gas/i386/ilp32/reloc64.s
index a4ccdb29916..db2d2acdf5d 100644
--- a/gas/testsuite/gas/i386/ilp32/reloc64.s
+++ b/gas/testsuite/gas/i386/ilp32/reloc64.s
@@ -187,7 +187,7 @@  bad	.byte	xtrn@tpoff
 	.quad	xtrn - 0x80000000
 	.long	xtrn@got - 4
 	.long	xtrn@got + 4
-bad	.long	xtrn@plt - _start
+bad	.long	xtrn@plt - .
 
 	.text
 bad	add	$x+0x123456789, %rax
diff --git a/gas/testsuite/gas/i386/plt.s b/gas/testsuite/gas/i386/plt.s
index c854c3fe739..5274b6c5a5f 100644
--- a/gas/testsuite/gas/i386/plt.s
+++ b/gas/testsuite/gas/i386/plt.s
@@ -1,7 +1,7 @@ 
 
 	.section .rodata
 .L4:
-        .long	foo1@PLT - .L4
-        .long	foo2@PLT - .L4
-        .long	foo3@PLT - .L4
-        .long	foo4@PLT - .L4
+        .slong	foo1@PLT - .L4
+        .slong	foo2@PLT - .L4
+        .slong	foo3@PLT - .L4
+        .slong	foo4@PLT - .L4
diff --git a/gas/testsuite/gas/i386/reloc32.l b/gas/testsuite/gas/i386/reloc32.l
index 31c71a0be28..71c65212dc9 100644
--- a/gas/testsuite/gas/i386/reloc32.l
+++ b/gas/testsuite/gas/i386/reloc32.l
@@ -131,6 +131,6 @@ 
 .*:160:  Info: .*
 .*:3: Error: .*
 .*:161:  Info: .*
-.*:56: Error: .*
-.*:164: Error: .*
+.*:3: Error: .*
+.*:164:  Info: .*
 #pass
diff --git a/gas/testsuite/gas/i386/reloc32.s b/gas/testsuite/gas/i386/reloc32.s
index 0ba69eae4d0..5616cd57e3f 100644
--- a/gas/testsuite/gas/i386/reloc32.s
+++ b/gas/testsuite/gas/i386/reloc32.s
@@ -161,7 +161,7 @@  bad	.byte	xtrn@ntpoff
 bad	.byte	xtrn@tpoff
 	.long	xtrn@got + 4
 	.long	xtrn@got - 4
-bad	.long	xtrn@plt - _start
+bad	.long	xtrn@plt - .
 
 	.text
 	movl	$ptr@PLT, %eax
diff --git a/gas/testsuite/gas/i386/reloc64.l b/gas/testsuite/gas/i386/reloc64.l
index d84d9042958..c60c45d139a 100644
--- a/gas/testsuite/gas/i386/reloc64.l
+++ b/gas/testsuite/gas/i386/reloc64.l
@@ -163,4 +163,5 @@ 
 .*:219:  Info: .*
 .*:3: Error: .*
 .*:220:  Info: .*
-.*:227: Error: can't resolve xtrn - ptr
+.*:3: Error: .*
+.*:227:  Info: .*
diff --git a/gas/testsuite/gas/i386/reloc64.s b/gas/testsuite/gas/i386/reloc64.s
index f248964813f..5c0f4136a09 100644
--- a/gas/testsuite/gas/i386/reloc64.s
+++ b/gas/testsuite/gas/i386/reloc64.s
@@ -224,7 +224,7 @@  bad	.byte	xtrn@gotplt
 	mov	xtrn(,%ebx), %eax
 	vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
 	addr32 vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
-bad	.long	xtrn@plt - ptr
+bad	.long	xtrn@plt - .
 
 	.text
 	movabs	$ptr@GOT, %rax
diff --git a/gas/testsuite/gas/i386/x86-64-jump-table.s b/gas/testsuite/gas/i386/x86-64-jump-table.s
index aefffad8f65..f9957630b38 100644
--- a/gas/testsuite/gas/i386/x86-64-jump-table.s
+++ b/gas/testsuite/gas/i386/x86-64-jump-table.s
@@ -23,9 +23,9 @@  foo:
         .section	.rodata
         .p2align 2
 .L4:
-        .long	bar0@plt-.L4
-        .long	bar1@PLT-.L4
-        .long	.Lbar2-.L4
-        .long	bar3@PLT-.L4
-        .long	bar4@plt-.L4
+        .slong	bar0@plt-.L4
+        .slong	bar1@PLT-.L4
+        .slong	.Lbar2-.L4
+        .slong	bar3@PLT-.L4
+        .slong	bar4@plt-.L4
         .section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/x86-64-jump-table.s b/ld/testsuite/ld-x86-64/x86-64-jump-table.s
index bd06f714469..84049d879bf 100644
--- a/ld/testsuite/ld-x86-64/x86-64-jump-table.s
+++ b/ld/testsuite/ld-x86-64/x86-64-jump-table.s
@@ -22,9 +22,9 @@  foo:
         .section	.rodata
         .p2align 2
 .L4:
-        .long	bar0@plt-.L4
-        .long	bar1@PLT-.L4
-        .long	.Lbar2-.L4
-        .long	bar3@PLT-.L4
-        .long	bar4@plt-.L4
+        .slong	bar0@plt-.L4
+        .slong	bar1@PLT-.L4
+        .slong	.Lbar2-.L4
+        .slong	bar3@PLT-.L4
+        .slong	bar4@plt-.L4
         .section	.note.GNU-stack,"",@progbits
-- 
2.55.0