https://sourceware.org/bugzilla/show_bug.cgi?id=19567
--- Comment #7 from Cary Coutant <ccoutant at gmail dot com> --- > [hjl@gnu-6 pr19567]$ cat x.s > .globl _start > _start: > mov $_start,%rax > mov _start,%rax > [hjl@gnu-6 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. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils