https://sourceware.org/bugzilla/show_bug.cgi?id=19567
--- Comment #8 from H.J. Lu <hjl.tools at gmail dot com> --- (In reply to Cary Coutant from comment #7) > > [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. My test here doesn't follow any programming model and is independent of x32 or x86-64: [hjl@gnu-6 pr19567]$ cat x.s .globl _start _start: mov $_start,%rax mov _start,%rax [hjl@gnu-6 pr19567]$ make as -o x.o x.s ld.gold -Ttext-segment 0x80000000 -o x x.o objdump -dw x x: file format elf64-x86-64 Disassembly of section .text: 00000000800000b0 <_start>: 800000b0: 48 c7 c0 b0 00 00 80 mov $0xffffffff800000b0,%rax 800000b7: 48 8b 04 25 b0 00 00 80 mov 0xffffffff800000b0,%rax [hjl@gnu-6 pr19567]$ > 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): Address is truncated to 32 bits. I opened: https://sourceware.org/bugzilla/show_bug.cgi?id=19572 > [../../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 The issue here is the operand of mov is the address/immediate of symbol _start. Gold doesn't handle it properly. > $ ../../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. No, it shouldn't. > 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! -Ttext-segment=0xffffffff80000000 shouldn't be allowed for 32-bit ELF. > 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. No. ld.bfd is correct. -- 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