[PATCH] D30699: [ELF] - Stop producing broken output for R_386_GOT32X relocation.

H.J. Lu via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 31 07:54:17 PDT 2017


On Fri, Mar 31, 2017 at 7:05 AM, Rafael Espíndola
<rafael.espindola at gmail.com> wrote:
> OK, I think the summary from the llvm point of view is
>
> * MC has to be changed to produce R_386_GOT32X for "mov _start at GOT,
> %eax" regardless of command line options since the current ABI changed
> the meaning of that expression. This tempts me to just drop the
> -relax-relocations option. I will open a bug about this.

That is what gas does.

> * R_386_GOT32X is not just a R_386_GOT32 that can be relaxed. They
> compute different expressions. R_386_GOT32 should stay as always
> computing R_GOT_FROM_END, R_386_GOT32X will compute R_GOT_FROM_END or
> R_GOT depending on where it is used.

[hjl at gnu-6 tmp]$ cat y.s
.text
.globl _start
_start:
cmp %eax, _start at GOT
[hjl at gnu-6 tmp]$ gcc -m32 -c y.s
[hjl at gnu-6 tmp]$ objdump -dwr y.o

y.o:     file format elf32-i386


Disassembly of section .text:

00000000 <_start>:
   0: 39 05 00 00 00 00     cmp    %eax,0x0 2: R_386_GOT32 _start
[hjl at gnu-6 tmp]$ ld -m elf_i386 y.o
[hjl at gnu-6 tmp]$ objdump -dw a.out

a.out:     file format elf32-i386


Disassembly of section .text:

08048094 <_start>:
 8048094: 39 05 fc 9f 04 08     cmp    %eax,0x8049ffc
[hjl at gnu-6 tmp]$

In this case, R_386_GOT32 is computed as G + A, not G + A - GOT.

H.J.
> Cheers,
> Rafael
>
>
> On 30 March 2017 at 19:12, H.J. Lu <hjl.tools at gmail.com> wrote:
>> On Thu, Mar 30, 2017 at 3:13 PM, H.J. Lu <hjl.tools at gmail.com> wrote:
>>> On Thu, Mar 30, 2017 at 3:01 PM, Rafael Espíndola
>>> <rafael.espindola at gmail.com> wrote:
>>>> On 30 March 2017 at 17:59, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>>> On Thu, Mar 30, 2017 at 2:52 PM, Rafael Espíndola
>>>>> <rafael.espindola at gmail.com> wrote:
>>>>>> On 30 March 2017 at 17:45, H.J. Lu <hjl.tools at gmail.com> wrote:
>>>>>>> On Thu, Mar 30, 2017 at 2:40 PM, Rafael Espíndola
>>>>>>> <rafael.espindola at gmail.com> wrote:
>>>>>>>>>> 08048074 <_start>:
>>>>>>>>>>  8048074: c7 c0 74 80 04 08     mov    $0x8048074,%eax
>>>>>>>>>>
>>>>>>>>>> as the GOT entry for _start contains the address of _start.
>>>>>>>>>
>>>>>>>>> Even with trunk I get
>>>>>>>>>
>>>>>>>>> 08048094 <_start>:
>>>>>>>>>  8048094:       a1 fc ff ff ff          mov    0xfffffffc,%eax
>>>>>>>>
>>>>>>>> And I still get -4 with the head of the binutils-2_28-branch branch.
>>>>>>>>
>>>>>>>
>>>>>>> The updated i386 psABI requires to encode "mov _start at GOT, %eax" with
>>>>>>> 0x8b opcode with R_386_GOT32X instead of 0xa1 opcode.
>>>>>>
>>>>>> What about files produced by old assemblers?
>>>>>
>>>>> For the older .o files, G + A - GOT is used.
>>>>
>>>> Which is incorrect?
>>>>
>>>> The current ABI also lists  R_386_GOT32 with the same expression as
>>>> R_386_GOT32X. When is a R_386_GOT32 required to be evaluated as G + A?
>>>>
>>>
>>> And it also says 0x8b opcode should be used.  For R_386_GOT32 without
>>> a base register on a1 opcode, it is undefined.
>>>
>>
>> mov foo at GOT, %eax
>> mov %eax, foo at GOT
>>
>> are special.   If
>>
>> mov %eax, foo at GOT (0x89 opcode or 0xa2 opcode)
>>
>> used, program behavior becomes random.
>>
>> mov foo at GOT, %eax  (0xa0 opcode)
>>
>> weren't used in the old programs since old linker will generate G + A - GOT,
>> which makes program behavior random.  The new assembler should always
>> generate 0x8b opcode for
>>
>> mov foo at GOT, %eax
>>
>> with R_386_GOT32X.
>>
>> It is hard to define a reasonable computation for
>>
>> mov foo at GOT, %eax  (0xa0 opcode)
>>
>> with R_386_GOT32 without introducing more linker complexity.
>>
>>
>> --
>> H.J.



-- 
H.J.


More information about the llvm-commits mailing list