bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/19567] Symbol_value::value doesn't support x32 overflow check


From: ccoutant at gmail dot com
Subject: [Bug gold/19567] Symbol_value::value doesn't support x32 overflow check
Date: Fri, 05 Feb 2016 00:37:23 +0000

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

--- Comment #7 from Cary Coutant <ccoutant at gmail dot com> ---
> address@hidden pr19567]$ cat x.s 
>     .globl _start
> _start:
>     mov $_start,%rax
>     mov _start,%rax
> address@hidden pr19567]$ make
> as --x32 -o x.o x.s
> ld.gold -m elf32_x86_64 -Ttext-segment 0x80000000 -o x x.o
> objdump -dw x
> 
> x:     file format elf32-x86-64
> 
> 
> Disassembly of section .text:
> 
> 80000074 <_start>:
> 80000074:     48 c7 c0 74 00 00 80    mov    $0xffffffff80000074,%rax
> 8000007b:     48 8b 04 25 74 00 00 80         mov    0xffffffff80000074,%rax

This looks correct to me (and also highly artificial). According to the psABI,
x32 uses an address space running from 0 to 0x7effffff (the small code model);
from 0x80000000 and up is considered the "negative half" of the address space
(the kernel code model). According to that, you're actually placing the text
segment at a negative address, and the mov instruction is generating the
correct 64-bit value.

Linking with -Ttext-segment 0x80000000 and with -Ttext-segment
0xffffffff80000000 produces the same results, as far as I can tell (as it
should, since we're dealing with a 32-bit address space):

[../../ld-new == gold]
$ ../../ld-new -m elf32_x86_64 -Ttext-segment=0x80000000 x.o
$ readelf -sW a.out

Symbol table '.symtab' contains 5 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 80000074     0 NOTYPE  GLOBAL DEFAULT    1 _start
     2: 80001000     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
     3: 80001000     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     4: 80001000     0 NOTYPE  GLOBAL DEFAULT  ABS _end
$ objdump -d a.out

a.out:     file format elf32-x86-64


Disassembly of section .text:

80000074 <_start>:
80000074:       48 c7 c0 74 00 00 80    mov    $0xffffffff80000074,%rax
8000007b:       48 8b 04 25 74 00 00    mov    0xffffffff80000074,%rax
80000082:       80 
$ ../../ld-new -m elf32_x86_64 -Ttext-segment=0xffffffff80000000 x.o
$ readelf -sW a.out

Symbol table '.symtab' contains 5 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 80000074     0 NOTYPE  GLOBAL DEFAULT    1 _start
     2: 80001000     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
     3: 80001000     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     4: 80001000     0 NOTYPE  GLOBAL DEFAULT  ABS _end
$ objdump -d a.out

a.out:     file format elf32-x86-64


Disassembly of section .text:

80000074 <_start>:
80000074:       48 c7 c0 74 00 00 80    mov    $0xffffffff80000074,%rax
8000007b:       48 8b 04 25 74 00 00    mov    0xffffffff80000074,%rax
80000082:       80 


On the other hand, using movabs:

$ ../../ld-new -m elf32_x86_64 -Ttext-segment=0x80000000 z.o
$ objdump -d a.out

a.out:     file format elf32-x86-64


Disassembly of section .text:

80000074 <_start>:
80000074:       48 b8 74 00 00 80 00    movabs $0x80000074,%rax
8000007b:       00 00 00 
8000007e:       48 a1 74 00 00 80 00    movabs 0x80000074,%rax
80000085:       00 00 00 

Here, 0x80000074 should have been sign-extended when we applied the
relocations.

Now using Gnu ld:

$ ld -m elf32_x86_64 -Ttext-segment=0x80000000 z.o
$ objdump -d a.out

a.out:     file format elf32-x86-64


Disassembly of section .text:

80000054 <_start>:
80000054:       48 b8 54 00 00 80 00    movabs $0x80000054,%rax
8000005b:       00 00 00 
8000005e:       48 a1 54 00 00 80 00    movabs 0x80000054,%rax
80000065:       00 00 00 

$ ld -m elf32_x86_64 -Ttext-segment=0xffffffff80000000 z.o
$ objdump -d a.out

a.out:     file format elf32-x86-64


Disassembly of section .text:

80000054 <_start>:
80000054:       48 b8 54 00 00 80 ff    movabs $0xffffffff80000054,%rax
8000005b:       ff ff ff 
8000005e:       48 a1 54 00 00 80 ff    movabs 0xffffffff80000054,%rax
80000065:       ff ff ff 

This is an ELF32 file. In both cases, the segment headers are the same:

Elf file type is EXEC (Executable file)
Entry point 0x80000054
There are 1 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x80000000 0x80000000 0x00068 0x00068 R E 0x200000

Will the program be loaded at 0x80000000 or at 0xffffffff8000000? It's got to
be one or the other, but ld gave us two different results!

As I read the psABI, the program should be loaded in negative address space, so
the movabs instructions are being relocated wrong in the
-Ttext-segment=0x80000000 case.

I also think that Gnu ld is wrong in complaining about the "32S" relocations.

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]