summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Relocations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Relocations.cpp')
-rw-r--r--lld/ELF/Relocations.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 92f2e200db11..55274344f881 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -995,7 +995,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
if (e == R_GOT || e == R_PLT)
return target->usesOnlyLowPageBits(type) || !config->isPic;
- if (sym.isPreemptible)
+ // R_AARCH64_AUTH_ABS64 requires a dynamic relocation.
+ if (sym.isPreemptible || e == R_AARCH64_AUTH)
return false;
if (!config->isPic)
return true;
@@ -1141,12 +1142,26 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
(rel == target->symbolicRel && !sym.isPreemptible)) {
addRelativeReloc<true>(*sec, offset, sym, addend, expr, type);
return;
- } else if (rel != 0) {
+ }
+ if (rel != 0) {
if (config->emachine == EM_MIPS && rel == target->symbolicRel)
rel = target->relativeRel;
std::lock_guard<std::mutex> lock(relocMutex);
- sec->getPartition().relaDyn->addSymbolReloc(rel, *sec, offset, sym,
- addend, type);
+ Partition &part = sec->getPartition();
+ if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
+ // For a preemptible symbol, we can't use a relative relocation. For an
+ // undefined symbol, we can't compute offset at link-time and use a
+ // relative relocation. Use a symbolic relocation instead.
+ if (sym.isPreemptible) {
+ part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
+ } else {
+ part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
+ DynamicReloc::AddendOnlyWithTargetVA, sym,
+ addend, R_ABS});
+ }
+ return;
+ }
+ part.relaDyn->addSymbolReloc(rel, *sec, offset, sym, addend, type);
// MIPS ABI turns using of GOT and dynamic relocations inside out.
// While regular ABI uses dynamic relocations to fill up GOT entries
@@ -1171,7 +1186,10 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
// When producing an executable, we can perform copy relocations (for
// STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.
- if (!config->shared && sym.isShared()) {
+ // Copy relocations/canonical PLT entries are unsupported for
+ // R_AARCH64_AUTH_ABS64.
+ if (!config->shared && sym.isShared() &&
+ !(config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
if (!canDefineSymbolInExecutable(sym)) {
errorOrWarn("cannot preempt symbol: " + toString(sym) +
getLocation(*sec, sym, offset));