[PATCH] D20622: [ELF] - Added support for jmp/call relaxations when R_X86_64_GOTPCRELX/R_X86_64_REX_GOTPCRELX are used.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Wed May 25 09:57:45 PDT 2016
This revision was automatically updated to reflect the committed changes.
grimar marked 2 inline comments as done.
Closed by commit rL270721: [ELF] - Added support for jmp/call relaxations when… (authored by grimar).
Changed prior to commit:
http://reviews.llvm.org/D20622?vs=58442&id=58446#toc
Repository:
rL LLVM
http://reviews.llvm.org/D20622
Files:
lld/trunk/ELF/Target.cpp
lld/trunk/test/ELF/gotpc-relax.s
Index: lld/trunk/ELF/Target.cpp
===================================================================
--- lld/trunk/ELF/Target.cpp
+++ lld/trunk/ELF/Target.cpp
@@ -740,14 +740,42 @@
uint64_t Offset) const {
if (Type != R_X86_64_GOTPCRELX && Type != R_X86_64_REX_GOTPCRELX)
return false;
-
- // Converting mov foo at GOTPCREL(%rip), %reg to lea foo(%rip), %reg
- // is the only supported relaxation for now.
- return (Offset >= 2 && Data[Offset - 2] == 0x8b);
+ const uint8_t Op = Data[Offset - 2];
+ const uint8_t ModRm = Data[Offset - 1];
+ // Relax mov.
+ if (Op == 0x8b)
+ return true;
+ // Relax call and jmp.
+ return Op == 0xff && (ModRm == 0x15 || ModRm == 0x25);
}
void X86_64TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
- Loc[-2] = 0x8d;
+ const uint8_t Op = Loc[-2];
+ const uint8_t ModRm = Loc[-1];
+
+ // Convert mov foo at GOTPCREL(%rip), %reg to lea foo(%rip), %reg.
+ if (Op == 0x8b) {
+ *(Loc - 2) = 0x8d;
+ relocateOne(Loc, R_X86_64_PC32, Val);
+ return;
+ }
+
+ assert(Op == 0xff);
+ if (ModRm == 0x15) {
+ // ABI says we can convert call *foo at GOTPCREL(%rip) to nop call foo.
+ // Instead we convert to addr32 call foo, where addr32 is instruction
+ // prefix. That makes result expression to be a single instruction.
+ *(Loc - 2) = 0x67; // addr32 prefix
+ *(Loc - 1) = 0xe8; // call
+ } else {
+ assert(ModRm == 0x25);
+ // Convert jmp *foo at GOTPCREL(%rip) to jmp foo nop.
+ // jmp doesn't return, so it is fine to use nop here, it is just a stub.
+ *(Loc - 2) = 0xe9; // jmp
+ *(Loc + 3) = 0x90; // nop
+ Loc -= 1;
+ Val += 1;
+ }
relocateOne(Loc, R_X86_64_PC32, Val);
}
Index: lld/trunk/test/ELF/gotpc-relax.s
===================================================================
--- lld/trunk/test/ELF/gotpc-relax.s
+++ lld/trunk/test/ELF/gotpc-relax.s
@@ -32,8 +32,22 @@
# DISASM-NEXT: 1103f: 8d 05 bc ff ff ff leal -68(%rip), %eax
# DISASM-NEXT: 11045: 8b 05 b5 0f 00 00 movl 4021(%rip), %eax
# DISASM-NEXT: 1104b: 8b 05 af 0f 00 00 movl 4015(%rip), %eax
-# DISASM-NEXT: 11051: ff 15 b1 0f 00 00 callq *4017(%rip)
-# DISASM-NEXT: 11057: ff 25 a3 0f 00 00 jmpq *4003(%rip)
+# DISASM-NEXT: 11051: 67 e8 a9 ff ff ff callq -87 <foo>
+# DISASM-NEXT: 11057: 67 e8 a3 ff ff ff callq -93 <foo>
+# DISASM-NEXT: 1105d: 67 e8 9e ff ff ff callq -98 <hid>
+# DISASM-NEXT: 11063: 67 e8 98 ff ff ff callq -104 <hid>
+# DISASM-NEXT: 11069: ff 15 91 0f 00 00 callq *3985(%rip)
+# DISASM-NEXT: 1106f: ff 15 8b 0f 00 00 callq *3979(%rip)
+# DISASM-NEXT: 11075: e9 86 ff ff ff jmp -122 <foo>
+# DISASM-NEXT: 1107a: 90 nop
+# DISASM-NEXT: 1107b: e9 80 ff ff ff jmp -128 <foo>
+# DISASM-NEXT: 11080: 90 nop
+# DISASM-NEXT: 11081: e9 7b ff ff ff jmp -133 <hid>
+# DISASM-NEXT: 11086: 90 nop
+# DISASM-NEXT: 11087: e9 75 ff ff ff jmp -139 <hid>
+# DISASM-NEXT: 1108c: 90 nop
+# DISASM-NEXT: 1108d: ff 25 6d 0f 00 00 jmpq *3949(%rip)
+# DISASM-NEXT: 11093: ff 25 67 0f 00 00 jmpq *3943(%rip)
.text
.globl foo
@@ -70,7 +84,15 @@
movl ifunc at GOTPCREL(%rip), %eax
movl ifunc at GOTPCREL(%rip), %eax
-## We check few other possible instructions
-## to see that they are not "relaxed" by mistake to lea.
call *foo at GOTPCREL(%rip)
+ call *foo at GOTPCREL(%rip)
+ call *hid at GOTPCREL(%rip)
+ call *hid at GOTPCREL(%rip)
+ call *ifunc at GOTPCREL(%rip)
+ call *ifunc at GOTPCREL(%rip)
+ jmp *foo at GOTPCREL(%rip)
+ jmp *foo at GOTPCREL(%rip)
+ jmp *hid at GOTPCREL(%rip)
+ jmp *hid at GOTPCREL(%rip)
+ jmp *ifunc at GOTPCREL(%rip)
jmp *ifunc at GOTPCREL(%rip)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20622.58446.patch
Type: text/x-patch
Size: 3701 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160525/a9ade02b/attachment.bin>
More information about the llvm-commits
mailing list