123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- //===---- JITLinkTestCommon.h - Utilities for Orc Unit Tests ----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Common utilities for JITLink unit tests.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
- #define LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
- #include "llvm/ADT/Triple.h"
- #include "llvm/ExecutionEngine/JITLink/JITLink.h"
- #include "llvm/MC/MCAsmBackend.h"
- #include "llvm/MC/MCAsmInfo.h"
- #include "llvm/MC/MCContext.h"
- #include "llvm/MC/MCDisassembler/MCDisassembler.h"
- #include "llvm/MC/MCInstrInfo.h"
- #include "llvm/MC/MCObjectFileInfo.h"
- #include "llvm/MC/MCObjectStreamer.h"
- #include "llvm/MC/MCParser/MCAsmParser.h"
- #include "llvm/MC/MCRegisterInfo.h"
- #include "llvm/MC/MCSubtargetInfo.h"
- #include "llvm/MC/MCTargetOptions.h"
- #include "llvm/Support/Endian.h"
- #include "llvm/Support/SourceMgr.h"
- #include "llvm/Support/TargetRegistry.h"
- #include "gtest/gtest.h"
- namespace llvm {
- class JITLinkTestCommon {
- public:
- class TestResources {
- public:
- static Expected<std::unique_ptr<TestResources>>
- Create(StringRef AsmSrc, StringRef TripleStr, bool PIC, bool LargeCodeModel,
- MCTargetOptions Options);
- MemoryBufferRef getTestObjectBufferRef() const;
- const MCDisassembler &getDisassembler() const { return *Dis; }
- private:
- TestResources(StringRef AsmSrc, StringRef TripleStr, bool PIC,
- bool LargeCodeModel, MCTargetOptions Options, Error &Err);
- Error initializeTripleSpecifics(Triple &TT);
- void initializeTestSpecifics(StringRef AsmSource, const Triple &TT,
- bool PIC, bool LargeCodeModel);
- const Target *TheTarget = nullptr;
- SourceMgr SrcMgr;
- SmallVector<char, 0> ObjBuffer;
- raw_svector_ostream ObjStream;
- MCTargetOptions Options;
- std::unique_ptr<MCRegisterInfo> MRI;
- std::unique_ptr<MCAsmInfo> MAI;
- std::unique_ptr<MCInstrInfo> MCII;
- std::unique_ptr<MCSubtargetInfo> STI;
- MCObjectFileInfo MOFI;
- std::unique_ptr<MCContext> AsCtx;
- std::unique_ptr<MCStreamer> MOS;
- std::unique_ptr<MCContext> DisCtx;
- std::unique_ptr<const MCDisassembler> Dis;
- };
- class TestJITLinkContext : public jitlink::JITLinkContext {
- public:
- using TestCaseFunction = std::function<void(jitlink::LinkGraph &)>;
- using NotifyResolvedFunction = std::function<void(jitlink::LinkGraph &G)>;
- using NotifyFinalizedFunction = std::function<void(
- std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>)>;
- TestJITLinkContext(TestResources &TR, TestCaseFunction TestCase);
- StringMap<JITEvaluatedSymbol> &externals() { return Externals; }
- TestJITLinkContext &
- setNotifyResolved(NotifyResolvedFunction NotifyResolved);
- TestJITLinkContext &
- setNotifyFinalized(NotifyFinalizedFunction NotifyFinalized);
- TestJITLinkContext &
- setMemoryManager(std::unique_ptr<jitlink::JITLinkMemoryManager> MM);
- jitlink::JITLinkMemoryManager &getMemoryManager() override;
- MemoryBufferRef getObjectBuffer() const override;
- void notifyFailed(Error Err) override;
- void lookup(
- const DenseSet<StringRef> &Symbols,
- std::unique_ptr<jitlink::JITLinkAsyncLookupContinuation> LC) override;
- void notifyResolved(jitlink::LinkGraph &G) override;
- void notifyFinalized(
- std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> A) override;
- Error modifyPassConfig(const Triple &TT,
- jitlink::PassConfiguration &Config) override;
- private:
- TestResources &TR;
- TestCaseFunction TestCase;
- NotifyResolvedFunction NotifyResolved;
- NotifyFinalizedFunction NotifyFinalized;
- std::unique_ptr<MemoryBuffer> ObjBuffer;
- std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr;
- StringMap<JITEvaluatedSymbol> Externals;
- };
- JITLinkTestCommon();
- /// Get TestResources for this target/test.
- ///
- /// If this method fails it is likely because the target is not supported in
- /// this build. The test should bail out without failing (possibly logging a
- /// diagnostic).
- Expected<std::unique_ptr<TestResources>>
- getTestResources(StringRef AsmSrc, StringRef Triple, bool PIC,
- bool LargeCodeModel, MCTargetOptions Options) const {
- return TestResources::Create(AsmSrc, Triple, PIC, LargeCodeModel,
- std::move(Options));
- }
- template <typename T>
- static Expected<T> readInt(jitlink::LinkGraph &G, jitlink::Block &B,
- size_t Offset = 0) {
- if (Offset + sizeof(T) > B.getSize())
- return make_error<StringError>("Reading past end of block content",
- inconvertibleErrorCode());
- return support::endian::read<T, 1>(B.getContent().data() + Offset,
- G.getEndianness());
- }
- template <typename T>
- static Expected<T> readInt(jitlink::LinkGraph &G, StringRef SymbolName,
- size_t Offset = 0) {
- for (auto *Sym : G.defined_symbols()) {
- if (Sym->getName() == SymbolName)
- return readInt<T>(G, Sym->getBlock(), Sym->getOffset() + Offset);
- }
- return make_error<StringError>("Symbol \"" + SymbolName + "\" not found",
- inconvertibleErrorCode());
- }
- static Expected<std::pair<MCInst, size_t>>
- disassemble(const MCDisassembler &Dis, jitlink::Block &B, size_t Offset = 0);
- static Expected<int64_t> decodeImmediateOperand(const MCDisassembler &Dis,
- jitlink::Block &B,
- size_t OpIdx,
- size_t Offset = 0);
- static jitlink::Symbol &symbol(jitlink::LinkGraph &G, StringRef Name) {
- for (auto *Sym : G.defined_symbols())
- if (Sym->getName() == Name)
- return *Sym;
- for (auto *Sym : G.external_symbols())
- if (Sym->getName() == Name)
- return *Sym;
- for (auto *Sym : G.absolute_symbols())
- if (Sym->getName() == Name)
- return *Sym;
- llvm_unreachable("Name must reference a symbol");
- }
- static JITTargetAddress symbolAddr(jitlink::LinkGraph &G, StringRef Name) {
- return symbol(G, Name).getAddress();
- }
- template <typename PredT>
- static size_t countEdgesMatching(jitlink::Block &B, const PredT &Pred) {
- return std::count_if(B.edges().begin(), B.edges().end(), Pred);
- }
- template <typename PredT>
- static size_t countEdgesMatching(jitlink::LinkGraph &G, StringRef Name,
- const PredT &Pred) {
- return countEdgesMatching(symbol(G, Name), Pred);
- }
- private:
- static bool AreTargetsInitialized;
- void initializeLLVMTargets();
- DenseMap<StringRef, JITEvaluatedSymbol> Externals;
- };
- } // end namespace llvm
- #endif
|