diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h index 2ba63f6ce45819..9795700581be1e 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h @@ -1388,8 +1388,8 @@ class JITLinkContext { Error markAllSymbolsLive(LinkGraph &G); /// Create an out of range error for the given edge in the given block. -Error makeTargetOutOfRangeError(const Block &B, const Edge &E, - const char *(*getEdgeKindName)(Edge::Kind)); +Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, + const Edge &E); /// Create a LinkGraph from the given object buffer. /// diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h index d310c30270ce46..2503577ea36ba7 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h @@ -245,7 +245,8 @@ enum EdgeKind_x86_64 : Edge::Kind { const char *getEdgeKindName(Edge::Kind K); /// Apply fixup expression for edge to block content. -inline Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) { +inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E, + char *BlockWorkingMem) { using namespace support; char *FixupPtr = BlockWorkingMem + E.getOffset(); @@ -262,7 +263,7 @@ inline Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) { case Pointer32: { uint64_t Value = E.getTarget().getAddress() + E.getAddend(); if (Value > std::numeric_limits::max()) - return makeTargetOutOfRangeError(B, E, getEdgeKindName); + return makeTargetOutOfRangeError(G, B, E); *(ulittle32_t *)FixupPtr = Value; break; } @@ -276,7 +277,7 @@ inline Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) { E.getTarget().getAddress() - (FixupAddress + 4) + E.getAddend(); if (Value < std::numeric_limits::min() || Value > std::numeric_limits::max()) - return makeTargetOutOfRangeError(B, E, getEdgeKindName); + return makeTargetOutOfRangeError(G, B, E); *(little32_t *)FixupPtr = Value; break; } @@ -291,7 +292,7 @@ inline Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) { int64_t Value = E.getTarget().getAddress() - FixupAddress + E.getAddend(); if (Value < std::numeric_limits::min() || Value > std::numeric_limits::max()) - return makeTargetOutOfRangeError(B, E, getEdgeKindName); + return makeTargetOutOfRangeError(G, B, E); *(little32_t *)FixupPtr = Value; break; } @@ -306,7 +307,7 @@ inline Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) { int64_t Value = FixupAddress - E.getTarget().getAddress() + E.getAddend(); if (Value < std::numeric_limits::min() || Value > std::numeric_limits::max()) - return makeTargetOutOfRangeError(B, E, getEdgeKindName); + return makeTargetOutOfRangeError(G, B, E); *(little32_t *)FixupPtr = Value; break; } diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp index be104c3ad1453d..50d30c7d205841 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -695,19 +695,8 @@ class ELFJITLinker_x86_64 : public JITLinker { : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {} private: - - static Error targetOutOfRangeError(const Block &B, const Edge &E) { - std::string ErrMsg; - { - raw_string_ostream ErrStream(ErrMsg); - ErrStream << "Relocation target out of range: "; - printEdge(ErrStream, B, E, getELFX86RelocationKindName(E.getKind())); - ErrStream << "\n"; - } - return make_error(std::move(ErrMsg)); - } - - Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) const { + Error applyFixup(LinkGraph &G, Block &B, const Edge &E, + char *BlockWorkingMem) const { using namespace ELF_x86_64_Edges; using namespace llvm::support; char *FixupPtr = BlockWorkingMem + E.getOffset(); @@ -720,7 +709,7 @@ class ELFJITLinker_x86_64 : public JITLinker { int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; if (Value < std::numeric_limits::min() || Value > std::numeric_limits::max()) - return targetOutOfRangeError(B, E); + return makeTargetOutOfRangeError(G, B, E); *(little32_t *)FixupPtr = Value; break; } diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp index 2619f31b6d8579..954423bb751235 100644 --- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp @@ -51,7 +51,7 @@ namespace jitlink { char JITLinkError::ID = 0; -void JITLinkError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; } +void JITLinkError::log(raw_ostream &OS) const { OS << ErrMsg; } std::error_code JITLinkError::convertToErrorCode() const { return std::error_code(GenericJITLinkError, *JITLinkerErrorCategory); @@ -309,14 +309,35 @@ Error markAllSymbolsLive(LinkGraph &G) { return Error::success(); } -Error makeTargetOutOfRangeError(const Block &B, const Edge &E, - const char *(*getEdgeKindName)(Edge::Kind)) { +Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, + const Edge &E) { std::string ErrMsg; { raw_string_ostream ErrStream(ErrMsg); - ErrStream << "Relocation target out of range: "; - printEdge(ErrStream, B, E, getEdgeKindName(E.getKind())); - ErrStream << "\n"; + Section &Sec = B.getSection(); + ErrStream << "In graph " << G.getName() << ", section " << Sec.getName() + << ": relocation target "; + if (E.getTarget().hasName()) + ErrStream << "\"" << E.getTarget().getName() << "\" "; + ErrStream << "at address " << formatv("{0:x}", E.getTarget().getAddress()); + ErrStream << " is out of range of " << G.getEdgeKindName(E.getKind()) + << " fixup at " << formatv("{0:x}", B.getFixupAddress(E)) << " ("; + + Symbol *BestSymbolForBlock = nullptr; + for (auto *Sym : Sec.symbols()) + if (&Sym->getBlock() == &B && Sym->hasName() && Sym->getOffset() == 0 && + (!BestSymbolForBlock || + Sym->getScope() < BestSymbolForBlock->getScope() || + Sym->getLinkage() < BestSymbolForBlock->getLinkage())) + BestSymbolForBlock = Sym; + + if (BestSymbolForBlock) + ErrStream << BestSymbolForBlock->getName() << ", "; + else + ErrStream << " @ "; + + ErrStream << formatv("{0:x}", B.getAddress()) << " + " + << formatv("{0:x}", E.getOffset()) << ")"; } return make_error(std::move(ErrMsg)); } diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h index c5d30cfb52b475..26e07be5282083 100644 --- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h +++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.h @@ -154,7 +154,7 @@ template class JITLinker : public JITLinkerBase { // Dispatch to LinkerImpl for fixup. auto *BlockData = const_cast(B->getContent().data()); - if (auto Err = impl().applyFixup(*B, E, BlockData)) + if (auto Err = impl().applyFixup(G, *B, E, BlockData)) return Err; } } diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp index 729320c6c0df8d..d0a50d84007d81 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp @@ -509,17 +509,6 @@ class MachOJITLinker_arm64 : public JITLinker { private: - static Error targetOutOfRangeError(const Block &B, const Edge &E) { - std::string ErrMsg; - { - raw_string_ostream ErrStream(ErrMsg); - ErrStream << "Relocation target out of range: "; - printEdge(ErrStream, B, E, getMachOARM64RelocationKindName(E.getKind())); - ErrStream << "\n"; - } - return make_error(std::move(ErrMsg)); - } - static unsigned getPageOffset12Shift(uint32_t Instr) { constexpr uint32_t LoadStoreImm12Mask = 0x3b000000; constexpr uint32_t Vec128Mask = 0x04800000; @@ -536,7 +525,8 @@ class MachOJITLinker_arm64 : public JITLinker { return 0; } - Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) const { + Error applyFixup(LinkGraph &G, Block &B, const Edge &E, + char *BlockWorkingMem) const { using namespace support; char *FixupPtr = BlockWorkingMem + E.getOffset(); @@ -553,7 +543,7 @@ class MachOJITLinker_arm64 : public JITLinker { "aligned"); if (Value < -(1 << 27) || Value > ((1 << 27) - 1)) - return targetOutOfRangeError(B, E); + return makeTargetOutOfRangeError(G, B, E); uint32_t RawInstr = *(little32_t *)FixupPtr; assert((RawInstr & 0x7fffffff) == 0x14000000 && @@ -566,7 +556,7 @@ class MachOJITLinker_arm64 : public JITLinker { case Pointer32: { uint64_t Value = E.getTarget().getAddress() + E.getAddend(); if (Value > std::numeric_limits::max()) - return targetOutOfRangeError(B, E); + return makeTargetOutOfRangeError(G, B, E); *(ulittle32_t *)FixupPtr = Value; break; } @@ -587,7 +577,7 @@ class MachOJITLinker_arm64 : public JITLinker { int64_t PageDelta = TargetPage - PCPage; if (PageDelta < -(1 << 30) || PageDelta > ((1 << 30) - 1)) - return targetOutOfRangeError(B, E); + return makeTargetOutOfRangeError(G, B, E); uint32_t RawInstr = *(ulittle32_t *)FixupPtr; assert((RawInstr & 0xffffffe0) == 0x90000000 && @@ -637,7 +627,7 @@ class MachOJITLinker_arm64 : public JITLinker { return make_error("LDR literal target is not 32-bit " "aligned"); if (Delta < -(1 << 20) || Delta > ((1 << 20) - 1)) - return targetOutOfRangeError(B, E); + return makeTargetOutOfRangeError(G, B, E); uint32_t EncodedImm = (static_cast(Delta) >> 2) << 5; uint32_t FixedInstr = RawInstr | EncodedImm; @@ -657,7 +647,7 @@ class MachOJITLinker_arm64 : public JITLinker { if (E.getKind() == Delta32 || E.getKind() == NegDelta32) { if (Value < std::numeric_limits::min() || Value > std::numeric_limits::max()) - return targetOutOfRangeError(B, E); + return makeTargetOutOfRangeError(G, B, E); *(little32_t *)FixupPtr = Value; } else *(little64_t *)FixupPtr = Value; diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp index 058cf9b036c263..e0f5ea595c2bba 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp @@ -601,9 +601,9 @@ class MachOJITLinker_x86_64 : public JITLinker { : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {} private: - - Error applyFixup(Block &B, const Edge &E, char *BlockWorkingMem) const { - return x86_64::applyFixup(B, E, BlockWorkingMem); + Error applyFixup(LinkGraph &G, Block &B, const Edge &E, + char *BlockWorkingMem) const { + return x86_64::applyFixup(G, B, E, BlockWorkingMem); } };