diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp')
| -rw-r--r-- | llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp index 410dd7fedad1..d0701ba08bd9 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp @@ -11,10 +11,12 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/JITLink/ELF_riscv.h" +#include "EHFrameSupportImpl.h" #include "ELFLinkGraphBuilder.h" #include "JITLinkGeneric.h" #include "PerGraphGOTAndPLTStubsBuilder.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h" #include "llvm/ExecutionEngine/JITLink/JITLink.h" #include "llvm/ExecutionEngine/JITLink/riscv.h" #include "llvm/Object/ELF.h" @@ -456,6 +458,13 @@ private: case AlignRelaxable: // Ignore when the relaxation pass did not run break; + case NegDelta32: { + int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend(); + if (LLVM_UNLIKELY(!isInRangeForImm(Value, 32))) + return makeTargetOutOfRangeError(G, B, E); + *(little32_t *)FixupPtr = static_cast<uint32_t>(Value); + break; + } } return Error::success(); } @@ -516,8 +525,7 @@ static RelaxAux initRelaxAux(LinkGraph &G) { RelaxAux Aux; Aux.Config.IsRV32 = G.getTargetTriple().isRISCV32(); const auto &Features = G.getFeatures().getFeatures(); - Aux.Config.HasRVC = - std::find(Features.begin(), Features.end(), "+c") != Features.end(); + Aux.Config.HasRVC = llvm::is_contained(Features, "+c"); for (auto &S : G.sections()) { if (!shouldRelax(S)) @@ -959,6 +967,13 @@ void link_ELF_riscv(std::unique_ptr<LinkGraph> G, PassConfiguration Config; const Triple &TT = G->getTargetTriple(); if (Ctx->shouldAddDefaultTargetPasses(TT)) { + + Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame")); + Config.PrePrunePasses.push_back(EHFrameEdgeFixer( + ".eh_frame", G->getPointerSize(), Edge::Invalid, Edge::Invalid, + Edge::Invalid, Edge::Invalid, NegDelta32)); + Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame")); + if (auto MarkLive = Ctx->getMarkLivePass(TT)) Config.PrePrunePasses.push_back(std::move(MarkLive)); else |
