[PATCH] i386: Issue an error for baseless @GOT relocation with relaxation

Rainer Orth ro@CeBiTec.Uni-Bielefeld.DE
Wed Nov 5 15:31:01 GMT 2025


Hi Jan,

> On 27.10.2025 11:09, H.J. Lu wrote:
>> On Mon, Oct 27, 2025 at 5:52 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>
>>> On 27.10.2025 10:31, H.J. Lu wrote:
>>>> On Mon, Oct 27, 2025 at 4:41 PM Jan Beulich <jbeulich@suse.com> wrote:
>>>>>
>>>>> On 26.10.2025 00:28, H.J. Lu wrote:
>>>>>> When -mrelax-relocations=no is used, don't generate baseless R_386_GOT32X
>>>>>> relocation.  Issue an error instead.
>>>>>>
>>>>>> PR gas/33552
>>>>>> * config/tc-i386.c (output_disp): Issue an error for baseless @GOT
>>>>>> relocation without relaxation in 32-bit.
>>>>>> * testsuite/gas/i386/got-no-relax-error.l: New file.
>>>>>> * testsuite/gas/i386/got-no-relax-error.s: Likewise.
>>>>>> * testsuite/gas/i386/got-no-relax.d: Don't use got.s.  Remove
>>>>>> R_386_GOT32X entries.
>>>>>> * testsuite/gas/i386/i386.exp: Run got-no-relax-error.
>>>>>>
>>>>>
>>>>> Please can you add a reference to the part of the spec that puts in place
>>>>> this restriction?
>>>>
>>>> It is more of an ISA restriction.  In i386 psABI, there are 2 kinds of PLTs,
>>>> one with EBX for PIC and the other without EBX for non-PIC.  The baseless
>>>> @GOT reloc can only be used with non-PIC PLT.
>>>
>>> But the two PLT kinds must be specified somewhere. As must be the relocation
>> 
>> It is in i386 psABI.   They are implemented in elf32-i386.c.
>> 
>>> types. Furthermore, how does the PLT come into play here when we're talking
>>> of a GOT reloc? R_386-GOT32X is G + A - GOT / G + A, i.e. nothing PLT-ish in
>> 
>> jmp *foo@GOT
>> 
>> was added for -fno-plt.  For the same reason as non-PIC PLT, it only works
>> without PIC.
>> 
>>> there. The description in the psABI also clearly mentions forms with and
>>> without base register.
>> 
>> It is covered in:
>> 
>> https://gitlab.com/x86-psABIs/i386-ABI
>
> Hmm, yes, I see the text there was extended at some point. Having a single
> reloc with two different calculations is, however, a no-go. Even more so with
> an arch like x86, where you can't reliably move backwards in the instruction
> byte stream.

apparently this patch has never been tested either natively on Solaris
or with --enable-x86-relax-relocations=no, the only configurations where
it makes a noticeable difference.  When doing one finds that it causes
quite a number of testsuite regressions:

* On both amd64-pc-solaris2.11 and i386-pc-solaris2.11, there's

  FAIL: i386 general
  FAIL: i386 intel (AT&T disassembly)
  FAIL: i386 intel
  FAIL: i386 intel-ok (directive)
  FAIL: i386 intel-ok (cmdline option)
  FAIL: i386 jump
  FAIL: i386 quoted symbols
  FAIL: gas/i386/align-branch-2a
  FAIL: gas/i386/align-branch-2b
  FAIL: gas/i386/align-branch-2c
  FAIL: -mlfence-before-indirect-branch=all
  FAIL: -mlfence-before-indirect-branch=register
  FAIL: -mlfence-before-indirect-branch=memory
  FAIL: i386 gotpc
  FAIL: i386 non-pic tls
  FAIL: Check tls relocation 32 bit-mode
  FAIL: i386 inval-tls
  FAIL: i386 intel-got

  All fail with the new error.

* On i386-pc-solaris2.11, there are also

  FAIL: Run pr2404
  FAIL: Run pr2404n
  FAIL: Run pr33409
  FAIL: --gc-sections with KEEP

  all in generic code.

Even worse, I ran a gcc trunk bootstraps on i386-pc-solaris2.11 with the
patched gas and both Solaris ld and GNU ld.  This breaks bootstrap,
unfortunately: compiling the PIC version of libgomp/barrier.c causes gas
to abort:

/var/tmp//cc.rNzya.s: Assembler messages:
/var/tmp//cc.rNzya.s:33: Internal error in output_disp at /vol/src/gnu/binutils/hg/master/local/gas/config/tc-i386.c:13092.
Please report this bug.

I believe there's a far easier way to address this issue: when one
simply doesn't emit R_386_GOT32X in tc-i386.c (output_disp) without
generate_relax_relocations, gas behaves the same way as before gas 2.26
when R_386_GOT32X support was introduced, namely only ever emitting
R_386_GOT32 instead.  The only other change to gas is to change
gas/testsuite/gas/i386/got-no-relax.d not to expect R_386_GOT32X any
longer.  If one removes the parts that rely on -march=+mpx (which isn't
supported either before gas 2.26 and with Solaris as) and the part
requiring Intel syntax support (which Solaris as lackes), the source for
that test (i386/got.s) can easily be assembled with both gas 2.25
(before R_386_GOT32X was introduced) and Solaris as (which never knew
about R_386_GOT32X).

With this patch I get clean testsuite results on both Solaris/x86 and
Linux/x86_64.  I've also bootstrapped gcc trunk successfully with the
patched gas and both Solaris ld and GNU ld.  Those builds didn't show
any testsuite regressions.

I believe such a change restores gas behaviour to what it was before gas
2.26.

WDYT?

	Rainer


gas: Never emit R_386_GOT32X with -mrelax-relocations=no [PR33552]

To avoid gas generating R_386_GOT32X in some cases even with
-mrelax-relocations=no, this patch only emits that reloc if
generate_relax_relocations is true, changing the gas/i386/got-no-relax.d
testcase to match.

Tested on {i386,amd64}-pc-solaris2.11 and {i686,x86_64}-pc-linux-gnu.
Also with gcc trunk bootstraps on i386-pc-solaris2.11 with both Solaris
ld and GNU ld.

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University


2025-11-05  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gas:
	PR gas/33552
	* config/tc-i386.c (output_disp) [OBJ_ELF]: Don't emit
	R_386_GOT32X unless generate_relax_relocations.
	* testsuite/gas/i386/got-no-relax.d: Only expect R_386_GOT32.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: gas-relax-relocations-no-gotx.patch
Type: text/x-patch
Size: 3639 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20251105/d6931129/attachment.bin>


More information about the Binutils mailing list