diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 285b268f91b9f..ac05e61d8200f 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -451,8 +451,6 @@ class RelocationScanner { template RelType getMipsN32RelType(RelTy *&rel) const; template int64_t computeMipsAddend(const RelTy &rel, RelExpr expr, bool isLocal) const; - template - int64_t computeAddend(const RelTy &rel, RelExpr expr, bool isLocal) const; bool isStaticLinkTimeConstant(RelExpr e, RelType type, const Symbol &sym, uint64_t relOff) const; void processAux(RelExpr expr, RelType type, uint64_t offset, Symbol &sym, @@ -497,30 +495,6 @@ int64_t RelocationScanner::computeMipsAddend(const RelTy &rel, RelExpr expr, return 0; } -// Returns an addend of a given relocation. If it is RELA, an addend -// is in a relocation itself. If it is REL, we need to read it from an -// input section. -template -int64_t RelocationScanner::computeAddend(const RelTy &rel, RelExpr expr, - bool isLocal) const { - int64_t addend; - RelType type = rel.getType(config->isMips64EL); - - if (RelTy::IsRela) { - addend = getAddend(rel); - } else { - const uint8_t *buf = sec->rawData.data(); - addend = target->getImplicitAddend(buf + rel.r_offset, type); - } - - if (config->emachine == EM_PPC64 && config->isPic && type == R_PPC64_TOC) - addend += getPPC64TocBase(); - if (config->emachine == EM_MIPS) - addend += computeMipsAddend(rel, expr, isLocal); - - return addend; -} - // Custom error message if Sym is defined in a discarded section. template static std::string maybeReportDiscarded(Undefined &sym) { @@ -1363,35 +1337,36 @@ template void RelocationScanner::scanOne(RelTy *&i) { uint32_t symIndex = rel.getSymbol(config->isMips64EL); Symbol &sym = sec->getFile()->getSymbol(symIndex); RelType type; - - // Deal with MIPS oddity. if (config->mipsN32Abi) { type = getMipsN32RelType(i); } else { type = rel.getType(config->isMips64EL); ++i; } - // Get an offset in an output section this relocation is applied to. uint64_t offset = getter.get(rel.r_offset); if (offset == uint64_t(-1)) return; - // Error if the target symbol is undefined. Symbol index 0 may be used by - // marker relocations, e.g. R_*_NONE and R_ARM_V4BX. Don't error on them. - if (sym.isUndefined() && symIndex != 0 && - maybeReportUndefined(cast(sym), *sec, offset)) - return; - - const uint8_t *relocatedAddr = sec->rawData.begin() + offset; - RelExpr expr = target->getRelExpr(type, sym, relocatedAddr); + RelExpr expr = target->getRelExpr(type, sym, sec->rawData.data() + offset); + int64_t addend = + RelTy::IsRela + ? getAddend(rel) + : target->getImplicitAddend(sec->rawData.data() + rel.r_offset, type); + if (LLVM_UNLIKELY(config->emachine == EM_MIPS)) + addend += computeMipsAddend(rel, expr, sym.isLocal()); + else if (config->emachine == EM_PPC64 && config->isPic && type == R_PPC64_TOC) + addend += getPPC64TocBase(); // Ignore R_*_NONE and other marker relocations. if (expr == R_NONE) return; - // Read an addend. - int64_t addend = computeAddend(rel, expr, sym.isLocal()); + // Error if the target symbol is undefined. Symbol index 0 may be used by + // marker relocations, e.g. R_*_NONE and R_ARM_V4BX. Don't error on them. + if (sym.isUndefined() && symIndex != 0 && + maybeReportUndefined(cast(sym), *sec, offset)) + return; if (config->emachine == EM_PPC64) { // We can separate the small code model relocations into 2 categories: