llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lld Author: Peter Collingbourne (pcc) <details> <summary>Changes</summary> This enables the use of IFUNC to implement custom relocation types, such as the PAuth relocation types that will be introduced in a subsequent pull request. TODO: - Add tests. - Fix broken tests. --- Full diff: https://github.com/llvm/llvm-project/pull/133531.diff 3 Files Affected: - (modified) lld/ELF/Relocations.cpp (+5-3) - (modified) lld/ELF/Symbols.h (+2) - (modified) lld/ELF/SyntheticSections.cpp (+5-1) ``````````diff diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 629702b45965b..46117a75ccea8 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -869,7 +869,8 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, // relrDyn sections don't support odd offsets. Also, relrDyn sections // don't store the addend values, so we must write it to the relocated // address. - if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) { + if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0 && + !sym.isGnuIFunc()) { isec.addReloc({expr, type, offsetInSec, addend, &sym}); if (shard) part.relrDyn->relocsVec[parallel::getThreadIndex()].push_back( @@ -1107,8 +1108,6 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset, } } else if (needsPlt(expr)) { sym.setFlags(NEEDS_PLT); - } else if (LLVM_UNLIKELY(isIfunc)) { - sym.setFlags(HAS_DIRECT_RELOC); } // If the relocation is known to be a link-time constant, we know no dynamic @@ -1194,6 +1193,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset, } } + if (LLVM_UNLIKELY(isIfunc && !needsGot(expr) && !needsPlt(expr))) + sym.setFlags(HAS_DIRECT_RELOC); + // 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. // Copy relocations/canonical PLT entries are unsupported for diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 64f2f6eaa8d09..d4280f367d23b 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -42,6 +42,8 @@ void printTraceSymbol(const Symbol &sym, StringRef name); enum { NEEDS_GOT = 1 << 0, NEEDS_PLT = 1 << 1, + // True if this is an ifunc with a direct relocation that cannot be + // represented as a RELATIVE relocation. HAS_DIRECT_RELOC = 1 << 2, // True if this symbol needs a canonical PLT entry, or (during // postScanRelocations) a copy relocation. diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index b03c4282ab1aa..afa0482bae3ba 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1707,9 +1707,13 @@ void RelocationBaseSection::mergeRels() { } void RelocationBaseSection::partitionRels() { + const RelType relativeRel = ctx.target->relativeRel; + const RelType iRelativeRel = ctx.target->iRelativeRel; + for (auto &r : relocs) + if (r.type == relativeRel && r.sym->isGnuIFunc()) + r.type = iRelativeRel; if (!combreloc) return; - const RelType relativeRel = ctx.target->relativeRel; numRelativeRelocs = std::stable_partition(relocs.begin(), relocs.end(), [=](auto &r) { return r.type == relativeRel; }) - `````````` </details> https://github.com/llvm/llvm-project/pull/133531 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits