x86-64 push / jmp / mov of undefined label results in bad relocation for position-independent code
Bruno Loff
bruno.loff@gmail.com
Tue Aug 22 11:25:00 GMT 2017
More information about the Binutils mailing list
Tue Aug 22 11:25:00 GMT 2017
- Previous message (by thread): [PATCH] RISC-V: Mark "c.nop" as an alias
- Next message (by thread): x86-64 push / jmp / mov of undefined label results in bad relocation for position-independent code
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Dear all, I am having the following problem with gnu assembler: When compiling an x86-64 assembly file which contains a `push`, `jmp` or `mov` instruction having an undefined label as an operand, `as` generates a relocation of type `R_X86_64_32S`, which is only 32bit long, i.e., it is too short for position-independent code (since such code might be loaded onto a position outside the 32-bit address space). Unsurprisingly, if I try to link such a code as a shared library, `ld` will complain: ld: tmp.o: relocation R_X86_64_32S against undefined symbol `mylabel' can not be used when making a shared object; recompile with -fPIC ld: final link failed: Nonrepresentable section on output Below this email I pasted a minimal example for you to verify this for yourself, with the corresponding `objdump` and `ld` output. I am doing a programming project that instruments gcc-compiled code, and one of the things the instrumented code does is to jump to a label belonging to the instrumentation code (for management purposes; registers are saved etc, and the instrumented code will be resumed later). I would like to ask two things: 1. Is there a workaround that enforces the right type of relocation? Maybe there is some command-line option or directive or whatever that will do the trick? 2. Otherwise, what would be the right way of fixing this? Should a new command-line option be used? Should I add a new i386 instruction prefix (along the lines of addr32/addr16 etc)? I would be leaning on the latter. I have never touched the gnu `as` code, so some pointers on what code/manual/article to read first would be most welcome. Thank you for all your work, Bruno Loff Here are the contents of tmp.s .text .globl main .extern mylabel // makes no difference (which is according to docs) .type main, @function main: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 // Actual program starts here movq mylabel, %rax pushq mylabel popq %rax jmpq *mylabel // Actual program ends here nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc After doing `as tmp.s -o tmp.o`, and then `objdump -drz tmp.o`, we see: tmp.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 8b 04 25 00 00 00 mov 0x0,%rax b: 00 8: R_X86_64_32S mylabel c: ff 34 25 00 00 00 00 pushq 0x0 f: R_X86_64_32S mylabel 13: 58 pop %rax 14: ff 24 25 00 00 00 00 jmpq *0x0 17: R_X86_64_32S mylabel 1b: 90 nop 1c: 5d pop %rbp 1d: c3 retq As you may see above, the relocation type is too short (only 32 bits are reserved for the address, but the label could in principle be pointing outside the 32-bit address space). Then doing `ld -shared tmp2.o` results in the following error message: ld: tmp.o: relocation R_X86_64_32S against undefined symbol `mylabel' can not be used when making a shared object; recompile with -fPIC ld: final link failed: Nonrepresentable section on output
- Previous message (by thread): [PATCH] RISC-V: Mark "c.nop" as an alias
- Next message (by thread): x86-64 push / jmp / mov of undefined label results in bad relocation for position-independent code
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list