diff options
Diffstat (limited to 'lld/ELF/Arch/X86_64.cpp')
| -rw-r--r-- | lld/ELF/Arch/X86_64.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp index 514ddc5ec8b0..40436752399b 100644 --- a/lld/ELF/Arch/X86_64.cpp +++ b/lld/ELF/Arch/X86_64.cpp @@ -78,7 +78,6 @@ static const std::vector<std::vector<uint8_t>> nopInstructions = { X86_64::X86_64() { copyRel = R_X86_64_COPY; gotRel = R_X86_64_GLOB_DAT; - noneRel = R_X86_64_NONE; pltRel = R_X86_64_JUMP_SLOT; relativeRel = R_X86_64_RELATIVE; iRelativeRel = R_X86_64_IRELATIVE; @@ -87,6 +86,7 @@ X86_64::X86_64() { tlsGotRel = R_X86_64_TPOFF64; tlsModuleIndexRel = R_X86_64_DTPMOD64; tlsOffsetRel = R_X86_64_DTPOFF64; + gotBaseSymInGotPlt = true; gotEntrySize = 8; pltHeaderSize = 16; pltEntrySize = 16; @@ -356,6 +356,8 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s, return R_GOT_PC; case R_X86_64_GOTOFF64: return R_GOTPLTREL; + case R_X86_64_PLTOFF64: + return R_PLT_GOTPLT; case R_X86_64_GOTPC32: case R_X86_64_GOTPC64: return R_GOTPLTONLY_PC; @@ -718,9 +720,12 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_X86_64_GOT64: case R_X86_64_GOTOFF64: case R_X86_64_GOTPC64: + case R_X86_64_PLTOFF64: case R_X86_64_IRELATIVE: case R_X86_64_RELATIVE: return read64le(buf); + case R_X86_64_TLSDESC: + return read64le(buf + 8); case R_X86_64_JUMP_SLOT: case R_X86_64_NONE: // These relocations are defined as not having an implicit addend. @@ -779,8 +784,13 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { case R_X86_64_GOT64: case R_X86_64_GOTOFF64: case R_X86_64_GOTPC64: + case R_X86_64_PLTOFF64: write64le(loc, val); break; + case R_X86_64_TLSDESC: + // The addend is stored in the second 64-bit word. + write64le(loc + 8, val); + break; default: llvm_unreachable("unknown relocation"); } @@ -792,8 +802,8 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend, // with addend != -4. Such an instruction does not load the full GOT entry, so // we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), %rax // (addend=0) loads the high 32 bits of the GOT entry. - if ((type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX) || - addend != -4) + if (!config->relax || addend != -4 || + (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX)) return R_GOT_PC; const uint8_t op = loc[-2]; const uint8_t modRm = loc[-1]; |
