summaryrefslogtreecommitdiff
path: root/lld/ELF/Arch/X86_64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Arch/X86_64.cpp')
-rw-r--r--lld/ELF/Arch/X86_64.cpp16
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];