[PATCH] D14713: [ELF2] - Optimization for R_X86_64_GOTTPOFF relocation.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 18 15:24:10 PST 2015
ruiu added inline comments.
================
Comment at: ELF/Target.cpp:392
@@ +391,3 @@
+ relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA);
+}
+
----------------
I applied you patch to my local repository to see if there's a room to make this simpler, only to find that this wouldn't be significantly simplified. I slightly updated the comments and code though. Please take a look.
// In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
// R_X86_64_TPOFF32 so that R_X86_64_TPOFF32 so that it does not use GOT.
// This function does that. Read "ELF Handling For Thread-Local Storage,
// 5.5 x86-x64 linker optimizations" (http://www.akkadia.org/drepper/tls.pdf)
// by Ulrich Drepper for details.
void X86_64TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufStart,
uint8_t *BufEnd, uint64_t P,
uint64_t SA) const {
// Ulrich's document section 6.5 says that @gottpoff(%rip) must be
// used in MOVQ or ADDQ instructions only.
// "MOVQ foo at GOTTPOFF(%RIP), %REG" is transformed to "MOVQ $foo, %REG".
// "ADDQ foo at GOTTPOFF(%RIP), %REG" is transformed to "LEAQ foo(%REG), %REG"
// (if the register is not RSP) or "ADDQ $foo, %RSP".
// Opcodes info can be found at http://ref.x86asm.net/coder64.html#x48.
if (Loc - 3 < BufStart)
error("TLS relocation optimization failed. Buffer overrun!");
uint8_t *Prefix = Loc - 3;
uint8_t *Inst = Loc - 2;
uint8_t *RegSlot = Loc - 1;
uint8_t Reg = Loc[-1] >> 3;
bool IsMov = *Inst == 0x8b;
bool RspAdd = !IsMov && Reg == 4;
// r12 and rsp registers requires special handling.
// Problem is that for other registers, for example leaq 0xXXXXXXXX(%r11),%r11
// result out is 7 bytes: 4d 8d 9b XX XX XX XX,
// but leaq 0xXXXXXXXX(%r12),%r12 is 8 bytes: 4d 8d a4 24 XX XX XX XX.
// The same true for rsp. So we convert to addq for them, saving 1 byte that
// we dont have.
if (RspAdd)
*Inst = 0x81;
else
*Inst = IsMov ? 0xc7 : 0x8d;
if (*Prefix == 0x4c)
*Prefix = (IsMov || RspAdd) ? 0x49 : 0x4d;
*RegSlot = (IsMov || RspAdd) ? (0xc0 | Reg) : (0x80 | Reg | (Reg << 3));
relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA);
}
http://reviews.llvm.org/D14713
More information about the llvm-commits
mailing list