[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