diff options
author | Rui Ueyama <ruiu@google.com> | 2016-06-21 05:44:14 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2016-06-21 05:44:14 +0000 |
commit | 1ba5667f43f4d3637a54807ed46a1a1e97092f0e (patch) | |
tree | d3feb03e2711448e9830a19d9375c09debd64c29 | |
parent | 4bc752577471aa4c51501a2e8dcb74a967c820e4 (diff) |
Refactor X86TargetInfo::relaxTlsIeToLe.
`Inst` and `Op` variables are removed since they are not always
point to an instruction nor an operand. For 5-byte MOV instruction,
Op points to an instruction, which is confusing.
git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@273246 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | ELF/Target.cpp | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/ELF/Target.cpp b/ELF/Target.cpp index 3c3fcc370..cf164c8aa 100644 --- a/ELF/Target.cpp +++ b/ELF/Target.cpp @@ -475,34 +475,34 @@ void X86TargetInfo::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, // be used with MOVL or ADDL instructions. // @indntpoff is similar to @gotntpoff, but for use in // position dependent code. - uint8_t *Inst = Loc - 2; - uint8_t *Op = Loc - 1; uint8_t Reg = (Loc[-1] >> 3) & 7; - bool IsMov = *Inst == 0x8b; + if (Type == R_386_TLS_IE) { - // For R_386_TLS_IE relocation we perform the next transformations: - // MOVL foo@INDNTPOFF,%EAX is transformed to MOVL $foo,%EAX - // MOVL foo@INDNTPOFF,%REG is transformed to MOVL $foo,%REG - // ADDL foo@INDNTPOFF,%REG is transformed to ADDL $foo,%REG - // First one is special because when EAX is used the sequence is 5 bytes - // long, otherwise it is 6 bytes. - if (*Op == 0xa1) { - *Op = 0xb8; + if (Loc[-1] == 0xa1) { + // "movl foo@indntpoff,%eax" -> "movl $foo,%eax" + // This case is different from the generic case below because + // this is a 5 byte instruction while below is 6 bytes. + Loc[-1] = 0xb8; + } else if (Loc[-2] == 0x8b) { + // "movl foo@indntpoff,%reg" -> "movl $foo,%reg" + Loc[-2] = 0xc7; + Loc[-1] = 0xc0 | Reg; } else { - *Inst = IsMov ? 0xc7 : 0x81; - *Op = 0xc0 | ((*Op >> 3) & 7); + // "addl foo@indntpoff,%reg" -> "addl $foo,%reg" + Loc[-2] = 0x81; + Loc[-1] = 0xc0 | Reg; } } else { - // R_386_TLS_GOTIE relocation can be optimized to - // R_386_TLS_LE so that it does not use GOT. - // "MOVL foo@GOTTPOFF(%RIP), %REG" is transformed to "MOVL $foo, %REG". - // "ADDL foo@GOTNTPOFF(%RIP), %REG" is transformed to "LEAL foo(%REG), %REG" - // Note: gold converts to ADDL instead of LEAL. - *Inst = IsMov ? 0xc7 : 0x8d; - if (IsMov) - *Op = 0xc0 | ((*Op >> 3) & 7); - else - *Op = 0x80 | Reg | (Reg << 3); + assert(Type == R_386_TLS_GOTIE); + if (Loc[-2] == 0x8b) { + // "movl foo@gottpoff(%rip),%reg" -> "movl $foo,%reg" + Loc[-2] = 0xc7; + Loc[-1] = 0xc0 | Reg; + } else { + // "addl foo@gotntpoff(%rip),%reg" -> "leal foo(%reg),%reg" + Loc[-2] = 0x8d; + Loc[-1] = 0x80 | (Reg << 3) | Reg; + } } relocateOne(Loc, R_386_TLS_LE, Val); } |