Coverage Report

Created: 2026-11-09 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/WasmEdge/lib/llvm/llvm.cpp
Line
Count
Source
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright The WasmEdge Authors
3
4
#include "llvm.h"
5
6
#include <llvm/IR/GlobalValue.h>
7
#include <llvm/Object/ObjectFile.h>
8
#include <llvm/Transforms/Utils/BasicBlockUtils.h>
9
#if LLVM_VERSION_MAJOR < 12 || WASMEDGE_OS_WINDOWS
10
#include <llvm/ExecutionEngine/Orc/Core.h>
11
#endif
12
#if LLVM_VERSION_MAJOR < 12
13
#include <llvm/Target/TargetMachine.h>
14
#endif
15
#if LLVM_VERSION_MAJOR < 13
16
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
17
#include <llvm/Support/CBindingWrapping.h>
18
#include <llvm/Support/Error.h>
19
#endif
20
#if LLVM_VERSION_MAJOR < 10
21
#include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
22
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
23
#include <llvm/MC/SubtargetFeature.h>
24
#include <llvm/Support/Host.h>
25
#endif
26
#if LLVM_VERSION_MAJOR < 18
27
#include <llvm/IR/Instructions.h>
28
#include <llvm/Support/CBindingWrapping.h>
29
#endif
30
31
#if WASMEDGE_OS_WINDOWS
32
#include "common/spdlog.h"
33
#include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
34
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
35
#include <llvm/Support/Process.h>
36
#include <system/winapi.h>
37
#endif
38
39
namespace llvm {
40
#if WASMEDGE_OS_WINDOWS
41
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ExecutionSession,
42
                                   LLVMOrcExecutionSessionRef)
43
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ObjectLayer, LLVMOrcObjectLayerRef)
44
#endif
45
#if LLVM_VERSION_MAJOR < 11
46
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ThreadSafeContext,
47
                                   LLVMOrcThreadSafeContextRef)
48
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::JITDylib, LLVMOrcJITDylibRef)
49
#endif
50
#if LLVM_VERSION_MAJOR < 12
51
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::LLJITBuilder, LLVMOrcLLJITBuilderRef)
52
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::JITTargetMachineBuilder,
53
                                   LLVMOrcJITTargetMachineBuilderRef)
54
#endif
55
#if LLVM_VERSION_MAJOR < 13
56
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ThreadSafeModule,
57
                                   LLVMOrcThreadSafeModuleRef)
58
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::IRTransformLayer,
59
                                   LLVMOrcIRTransformLayerRef)
60
0
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::MaterializationResponsibility,
61
0
                                   LLVMOrcMaterializationResponsibilityRef)
62
0
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::LLJIT, LLVMOrcLLJITRef)
63
0
#endif
64
0
} // namespace llvm
65
0
66
0
#if LLVM_VERSION_MAJOR < 18
67
0
LLVMTailCallKind LLVMGetTailCallKind(LLVMValueRef Call) {
68
0
  return static_cast<LLVMTailCallKind>(
69
0
      llvm::unwrap<llvm::CallInst>(Call)->getTailCallKind());
70
0
}
71
72
5.59k
void LLVMSetTailCallKind(LLVMValueRef Call, LLVMTailCallKind kind) {
73
5.59k
  llvm::unwrap<llvm::CallInst>(Call)->setTailCallKind(
74
5.59k
      static_cast<llvm::CallInst::TailCallKind>(kind));
75
5.59k
}
76
#endif
77
#if LLVM_VERSION_MAJOR < 10
78
LLVMBool LLVMGetWeak(LLVMValueRef CmpXchgInst) noexcept {
79
  return llvm::unwrap<llvm::AtomicCmpXchgInst>(CmpXchgInst)->isWeak();
80
}
81
82
void LLVMSetWeak(LLVMValueRef CmpXchgInst, LLVMBool IsWeak) noexcept {
83
  llvm::unwrap<llvm::AtomicCmpXchgInst>(CmpXchgInst)->setWeak(IsWeak);
84
}
85
#endif
86
87
namespace WasmEdge::LLVM {
88
89
22.4k
void Value::setDSOLocal(bool Local) noexcept {
90
22.4k
  llvm::cast<llvm::GlobalValue>(reinterpret_cast<llvm::Value *>(Ref))
91
22.4k
      ->setDSOLocal(Local);
92
22.4k
}
93
94
10.3k
void Value::eliminateUnreachableBlocks() noexcept {
95
10.3k
  llvm::EliminateUnreachableBlocks(
96
10.3k
      *llvm::cast<llvm::Function>(reinterpret_cast<llvm::Value *>(Ref)));
97
10.3k
}
98
99
58.6k
bool SectionIterator::isText() const noexcept {
100
58.6k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
101
58.6k
  return (*S)->isText();
102
58.6k
}
103
104
54.3k
bool SectionIterator::isData() const noexcept {
105
54.3k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
106
54.3k
  return (*S)->isData();
107
54.3k
}
108
109
45.5k
bool SectionIterator::isBSS() const noexcept {
110
45.5k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
111
45.5k
  return (*S)->isBSS();
112
45.5k
}
113
114
58.6k
bool SectionIterator::isPData() const noexcept {
115
#if WASMEDGE_OS_WINDOWS
116
  using namespace std::literals;
117
  return ".pdata"sv == getName();
118
#else
119
58.6k
  return false;
120
58.6k
#endif
121
58.6k
}
122
123
62.9k
bool SectionIterator::isEHFrame() const noexcept {
124
62.9k
#if WASMEDGE_OS_LINUX
125
62.9k
  using namespace std::literals;
126
62.9k
  return ".eh_frame"sv == getName();
127
#elif WASMEDGE_OS_MACOS
128
  using namespace std::literals;
129
  return "__eh_frame"sv == getName();
130
#else
131
  return false;
132
#endif
133
62.9k
}
134
135
31.4k
bool SectionIterator::isVirtual() const noexcept {
136
31.4k
  auto *S = reinterpret_cast<const llvm::object::section_iterator *>(Ref);
137
31.4k
  return (*S)->isVirtual();
138
31.4k
}
139
140
#if WASMEDGE_OS_WINDOWS
141
namespace {
142
class DefaultMMapper final : public llvm::SectionMemoryManager::MemoryMapper {
143
public:
144
  llvm::sys::MemoryBlock allocateMappedMemory(
145
      llvm::SectionMemoryManager::AllocationPurpose /*Purpose*/,
146
      size_t NumBytes, const llvm::sys::MemoryBlock *const NearBlock,
147
      unsigned Flags, std::error_code &EC) override {
148
    return llvm::sys::Memory::allocateMappedMemory(NumBytes, NearBlock, Flags,
149
                                                   EC);
150
  }
151
  std::error_code protectMappedMemory(const llvm::sys::MemoryBlock &Block,
152
                                      unsigned Flags) override {
153
    return llvm::sys::Memory::protectMappedMemory(Block, Flags);
154
  }
155
156
  std::error_code releaseMappedMemory(llvm::sys::MemoryBlock &M) override {
157
    return llvm::sys::Memory::releaseMappedMemory(M);
158
  }
159
};
160
161
class ContiguousSectionMemoryManager : public llvm::RTDyldMemoryManager {
162
public:
163
  explicit ContiguousSectionMemoryManager(
164
      llvm::SectionMemoryManager::MemoryMapper *UnownedMM = nullptr)
165
      : MMapper(UnownedMM), OwnedMMapper(nullptr) {
166
    if (!MMapper) {
167
      OwnedMMapper = std::make_unique<DefaultMMapper>();
168
      MMapper = OwnedMMapper.get();
169
    }
170
  }
171
172
  ~ContiguousSectionMemoryManager() noexcept override {
173
    using namespace std::literals;
174
    if (Preallocated.allocatedSize() != 0) {
175
      auto EC = MMapper->releaseMappedMemory(Preallocated);
176
      if (EC) {
177
        spdlog::error("releaseMappedMemory failed with error: {}"sv,
178
                      EC.message());
179
      }
180
    }
181
  }
182
183
  bool needsToReserveAllocationSpace() override { return true; }
184
185
  void reserveAllocationSpace(uintptr_t CodeSize, llvm::Align CodeAlign,
186
                              uintptr_t RODataSize, llvm::Align RODataAlign,
187
                              uintptr_t RWDataSize,
188
                              llvm::Align RWDataAlign) override {
189
    using namespace std::literals;
190
    assuming(Preallocated.allocatedSize() == 0);
191
192
    static const size_t PageSize = llvm::sys::Process::getPageSizeEstimate();
193
    assuming(CodeAlign.value() <= PageSize);
194
    assuming(RODataAlign.value() <= PageSize);
195
    assuming(RWDataAlign.value() <= PageSize);
196
    CodeSize = roundUpTo(CodeSize + CodeAlign.value(), PageSize);
197
    RODataSize = roundUpTo(RODataSize + RODataAlign.value(), PageSize);
198
    RWDataSize = roundUpTo(RWDataSize + RWDataAlign.value(), PageSize);
199
    const uintptr_t TotalSize =
200
        CodeSize + RODataSize + RWDataSize + PageSize * 3;
201
202
    std::error_code EC;
203
    Preallocated = MMapper->allocateMappedMemory(
204
        llvm::SectionMemoryManager::AllocationPurpose::Code, TotalSize, nullptr,
205
        llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE, EC);
206
    if (EC) {
207
      spdlog::error("allocateMappedMemory failed with error: {}"sv,
208
                    EC.message());
209
      return;
210
    }
211
212
    auto base = reinterpret_cast<std::uintptr_t>(Preallocated.base());
213
    CodeMem = CodeFree =
214
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(base), CodeSize);
215
    base += CodeSize;
216
    RODataMem = RODataFree =
217
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(base), RODataSize);
218
    base += RODataSize;
219
    RWDataMem = RWDataFree =
220
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(base), RWDataSize);
221
  }
222
223
  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
224
                               unsigned /*SectionID*/,
225
                               llvm::StringRef /*SectionName*/,
226
                               bool IsReadOnly) override {
227
    if (IsReadOnly) {
228
      return Allocate(RODataFree, Size, Alignment);
229
    } else {
230
      return Allocate(RWDataFree, Size, Alignment);
231
    }
232
  }
233
234
  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
235
                               unsigned /*SectionID*/,
236
                               llvm::StringRef /*SectionName*/) override {
237
    return Allocate(CodeFree, Size, Alignment);
238
  }
239
240
  bool finalizeMemory(std::string *ErrMsg) override {
241
    std::error_code EC;
242
243
    EC = MMapper->protectMappedMemory(CodeMem, llvm::sys::Memory::MF_READ |
244
                                                   llvm::sys::Memory::MF_EXEC);
245
    if (EC) {
246
      if (ErrMsg) {
247
        *ErrMsg = EC.message();
248
      }
249
      return true;
250
    }
251
    EC = MMapper->protectMappedMemory(RODataMem, llvm::sys::Memory::MF_READ);
252
    if (EC) {
253
      if (ErrMsg) {
254
        *ErrMsg = EC.message();
255
      }
256
      return true;
257
    }
258
259
    llvm::sys::Memory::InvalidateInstructionCache(CodeMem.base(),
260
                                                  CodeMem.allocatedSize());
261
    return false;
262
  }
263
264
private:
265
  llvm::sys::MemoryBlock Preallocated;
266
267
  // Sections must be in the order code < rodata < rwdata.
268
  llvm::sys::MemoryBlock CodeMem;
269
  llvm::sys::MemoryBlock RODataMem;
270
  llvm::sys::MemoryBlock RWDataMem;
271
272
  llvm::sys::MemoryBlock CodeFree;
273
  llvm::sys::MemoryBlock RODataFree;
274
  llvm::sys::MemoryBlock RWDataFree;
275
276
  llvm::SectionMemoryManager::MemoryMapper *MMapper;
277
  std::unique_ptr<llvm::SectionMemoryManager::MemoryMapper> OwnedMMapper;
278
279
  uint8_t *Allocate(llvm::sys::MemoryBlock &FreeBlock, std::uintptr_t Size,
280
                    unsigned alignment) {
281
    using namespace std::literals;
282
    const auto Base = reinterpret_cast<uintptr_t>(FreeBlock.base());
283
    const auto Start = roundUpTo(Base, alignment);
284
    const uintptr_t PaddedSize = (Start - Base) + Size;
285
    if (PaddedSize > FreeBlock.allocatedSize()) {
286
      spdlog::error("Failed to satisfy suballocation request for {}"sv, Size);
287
      return nullptr;
288
    }
289
    FreeBlock =
290
        llvm::sys::MemoryBlock(reinterpret_cast<void *>(Base + PaddedSize),
291
                               FreeBlock.allocatedSize() - PaddedSize);
292
    return reinterpret_cast<uint8_t *>(Start);
293
  }
294
295
  static uintptr_t roundUpTo(uintptr_t Value, uintptr_t Divisor) noexcept {
296
    return ((Value + (Divisor - 1)) / Divisor) * Divisor;
297
  }
298
};
299
300
// Register stack unwind info for JIT functions
301
class Win64EHManager : public ContiguousSectionMemoryManager {
302
  using Base = ContiguousSectionMemoryManager;
303
  uint64_t CodeAddress = 0;
304
305
public:
306
  ~Win64EHManager() noexcept override {}
307
308
  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
309
                               unsigned SectionID,
310
                               llvm::StringRef SectionName) override {
311
    using namespace std::literals;
312
    const auto Allocated =
313
        Base::allocateCodeSection(Size, Alignment, SectionID, SectionName);
314
    if (SectionName == llvm::StringRef(".text"sv)) {
315
      CodeAddress = reinterpret_cast<uint64_t>(Allocated);
316
    }
317
    return Allocated;
318
  }
319
320
  void registerEHFrames(uint8_t *Addr, uint64_t /*LoadAddr*/,
321
                        size_t Size) noexcept override {
322
    using namespace std::literals;
323
    winapi::RUNTIME_FUNCTION_ *const FunctionTable =
324
        reinterpret_cast<winapi::RUNTIME_FUNCTION_ *>(Addr);
325
    const uint32_t EntryCount =
326
        static_cast<uint32_t>(Size / sizeof(winapi::RUNTIME_FUNCTION_));
327
    if (EntryCount == 0)
328
      return;
329
    // Calculate the object image base address by assuming that the address of
330
    // the first function is equal to the address of the code section.
331
    const auto ImageBase = CodeAddress - FunctionTable[0].BeginAddress;
332
    winapi::RtlAddFunctionTable(FunctionTable, EntryCount, ImageBase);
333
    EHFrames.push_back({Addr, Size});
334
  }
335
  void deregisterEHFrames() noexcept override {
336
    using namespace std::literals;
337
    for (auto &Frame : EHFrames) {
338
      winapi::RtlDeleteFunctionTable(
339
          reinterpret_cast<winapi::RUNTIME_FUNCTION_ *>(Frame.Addr));
340
    }
341
    EHFrames.clear();
342
  }
343
};
344
} // namespace
345
346
LLVMOrcLLJITBuilderRef OrcLLJIT::getBuilder() noexcept {
347
  using llvm::unwrap;
348
  using llvm::wrap;
349
  const LLVMOrcLLJITBuilderRef Builder = LLVMOrcCreateLLJITBuilder();
350
  LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
351
      Builder,
352
      [](void *, LLVMOrcExecutionSessionRef ES, const char *) noexcept {
353
        auto Layer = std::make_unique<llvm::orc::RTDyldObjectLinkingLayer>(
354
            *unwrap(ES), [](
355
#if LLVM_VERSION_MAJOR < 21
356
#else
357
                             const llvm::MemoryBuffer &
358
#endif
359
                         ) { return std::make_unique<Win64EHManager>(); });
360
        Layer->setOverrideObjectFlagsWithResponsibilityFlags(true);
361
        Layer->setAutoClaimResponsibilityForObjectSymbols(true);
362
        return wrap(static_cast<llvm::orc::ObjectLayer *>(Layer.release()));
363
      },
364
      nullptr);
365
  return Builder;
366
}
367
#elif LLVM_VERSION_MAJOR < 10
368
namespace {
369
class EHFrameDeregisteringMemoryManager : public llvm::SectionMemoryManager {
370
public:
371
  ~EHFrameDeregisteringMemoryManager() noexcept override {
372
    deregisterEHFrames();
373
  }
374
};
375
} // namespace
376
377
LLVMOrcLLJITBuilderRef OrcLLJIT::getBuilder() noexcept {
378
  using llvm::unwrap;
379
  const LLVMOrcLLJITBuilderRef Builder = LLVMOrcCreateLLJITBuilder();
380
  if (auto JTMB = llvm::orc::JITTargetMachineBuilder::detectHost()) {
381
    llvm::StringMap<bool> FeatureMap;
382
    llvm::sys::getHostCPUFeatures(FeatureMap);
383
    for (auto &Feature : FeatureMap) {
384
      JTMB->getFeatures().AddFeature(Feature.first(), Feature.second);
385
    }
386
    JTMB->setCPU(llvm::sys::getHostCPUName().str());
387
    unwrap(Builder)->setJITTargetMachineBuilder(std::move(*JTMB));
388
  } else {
389
    llvm::consumeError(JTMB.takeError());
390
  }
391
  unwrap(Builder)->setObjectLinkingLayerCreator(
392
      [](llvm::orc::ExecutionSession &ES) {
393
        return std::make_unique<llvm::orc::RTDyldObjectLinkingLayer>(ES, []() {
394
          return std::make_unique<EHFrameDeregisteringMemoryManager>();
395
        });
396
      });
397
  return Builder;
398
}
399
#else
400
0
LLVMOrcLLJITBuilderRef OrcLLJIT::getBuilder() noexcept { return nullptr; }
401
#endif
402
403
} // namespace WasmEdge::LLVM
404
405
#if LLVM_VERSION_MAJOR < 12 && WASMEDGE_OS_WINDOWS
406
void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
407
    LLVMOrcLLJITBuilderRef Builder,
408
    LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F,
409
    void *Ctx) noexcept {
410
  using llvm::unwrap;
411
  using llvm::wrap;
412
  unwrap(Builder)->setObjectLinkingLayerCreator(
413
      [=](llvm::orc::ExecutionSession &ES, const llvm::Triple &TT) {
414
        auto TTStr = TT.str();
415
        return std::unique_ptr<llvm::orc::ObjectLayer>(
416
            unwrap(F(Ctx, wrap(&ES), TTStr.c_str())));
417
      });
418
}
419
#endif
420
#if LLVM_VERSION_MAJOR < 11
421
LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext() noexcept {
422
  using llvm::wrap;
423
  return wrap(
424
      new llvm::orc::ThreadSafeContext(std::make_unique<llvm::LLVMContext>()));
425
}
426
427
LLVMContextRef
428
LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) noexcept {
429
  using llvm::unwrap;
430
  using llvm::wrap;
431
  return wrap(unwrap(TSCtx)->getContext());
432
}
433
434
void LLVMOrcDisposeThreadSafeContext(
435
    LLVMOrcThreadSafeContextRef TSCtx) noexcept {
436
  delete llvm::unwrap(TSCtx);
437
}
438
439
LLVMOrcThreadSafeModuleRef
440
LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M,
441
                                 LLVMOrcThreadSafeContextRef TSCtx) noexcept {
442
  using llvm::unwrap;
443
  using llvm::wrap;
444
  return wrap(new llvm::orc::ThreadSafeModule(
445
      std::unique_ptr<llvm::Module>(unwrap(M)), *unwrap(TSCtx)));
446
}
447
448
void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) noexcept {
449
  delete llvm::unwrap(TSM);
450
}
451
452
LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder() noexcept {
453
  return llvm::wrap(new llvm::orc::LLJITBuilder());
454
}
455
456
void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) noexcept {
457
  delete llvm::unwrap(Builder);
458
}
459
460
void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
461
    LLVMOrcLLJITBuilderRef Builder,
462
    LLVMOrcJITTargetMachineBuilderRef JTMB) noexcept {
463
  using llvm::unwrap;
464
  unwrap(Builder)->setJITTargetMachineBuilder(std::move(*unwrap(JTMB)));
465
  delete unwrap(JTMB);
466
}
467
468
LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
469
                                LLVMOrcLLJITBuilderRef Builder) noexcept {
470
  using llvm::unwrap;
471
  using llvm::wrap;
472
  if (!Builder) {
473
    Builder = LLVMOrcCreateLLJITBuilder();
474
  }
475
  auto J = unwrap(Builder)->create();
476
  LLVMOrcDisposeLLJITBuilder(Builder);
477
  if (!J) {
478
    *Result = nullptr;
479
    return wrap(J.takeError());
480
  }
481
  *Result = wrap(J->release());
482
  return LLVMErrorSuccess;
483
}
484
485
LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) noexcept {
486
  delete llvm::unwrap(J);
487
  return LLVMErrorSuccess;
488
}
489
490
LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) noexcept {
491
  using llvm::unwrap;
492
  using llvm::wrap;
493
  return wrap(&unwrap(J)->getMainJITDylib());
494
}
495
496
LLVMErrorRef
497
LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
498
                            LLVMOrcThreadSafeModuleRef TSM) noexcept {
499
  using llvm::unwrap;
500
  using llvm::wrap;
501
  std::unique_ptr<llvm::orc::ThreadSafeModule> TmpTSM(unwrap(TSM));
502
  return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM)));
503
}
504
505
LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
506
                                LLVMOrcJITTargetAddress *Result,
507
                                const char *Name) noexcept {
508
  using llvm::unwrap;
509
  using llvm::wrap;
510
  auto Sym = unwrap(J)->lookup(Name);
511
  if (!Sym) {
512
    *Result = 0;
513
    return wrap(Sym.takeError());
514
  }
515
  *Result = Sym->getAddress();
516
  return LLVMErrorSuccess;
517
}
518
#endif
519
#if LLVM_VERSION_MAJOR < 12
520
LLVMOrcJITTargetMachineBuilderRef
521
LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) {
522
  using llvm::wrap;
523
  auto *TemplateTM = reinterpret_cast<llvm::TargetMachine *>(TM);
524
  auto JTMB = std::make_unique<llvm::orc::JITTargetMachineBuilder>(
525
      TemplateTM->getTargetTriple());
526
  JTMB->setCPU(TemplateTM->getTargetCPU().str())
527
      .setRelocationModel(TemplateTM->getRelocationModel())
528
      .setCodeModel(TemplateTM->getCodeModel())
529
      .setCodeGenOptLevel(TemplateTM->getOptLevel());
530
#if LLVM_VERSION_MAJOR < 10
531
  JTMB->getFeatures() =
532
      llvm::SubtargetFeatures(TemplateTM->getTargetFeatureString());
533
  JTMB->getOptions() = TemplateTM->Options;
534
#else
535
  JTMB->setFeatures(TemplateTM->getTargetFeatureString())
536
      .setOptions(TemplateTM->Options);
537
#endif
538
  LLVMDisposeTargetMachine(TM);
539
  return wrap(JTMB.release());
540
}
541
542
LLVMOrcResourceTrackerRef
543
LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) noexcept {
544
  return reinterpret_cast<LLVMOrcResourceTrackerRef>(JD);
545
}
546
547
void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef) noexcept {}
548
549
LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef) noexcept {
550
  return LLVMErrorSuccess;
551
}
552
553
LLVMErrorRef
554
LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J,
555
                                  LLVMOrcResourceTrackerRef RT,
556
                                  LLVMOrcThreadSafeModuleRef TSM) noexcept {
557
  return LLVMOrcLLJITAddLLVMIRModule(
558
      J, reinterpret_cast<LLVMOrcJITDylibRef>(RT), TSM);
559
}
560
#endif
561
#if LLVM_VERSION_MAJOR < 11
562
#elif LLVM_VERSION_MAJOR < 13
563
LLVMOrcIRTransformLayerRef
564
0
LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) noexcept {
565
0
  using llvm::unwrap;
566
0
  using llvm::wrap;
567
0
  return wrap(&(unwrap(J)->getIRTransformLayer()));
568
0
}
569
void LLVMOrcIRTransformLayerSetTransform(
570
    LLVMOrcIRTransformLayerRef IRTransformLayer,
571
    LLVMOrcIRTransformLayerTransformFunction TransformFunction,
572
0
    void *Ctx) noexcept {
573
0
  using llvm::unwrap;
574
0
  using llvm::wrap;
575
0
  unwrap(IRTransformLayer)
576
0
      ->setTransform([=](llvm::orc::ThreadSafeModule TSM,
577
0
                         llvm::orc::MaterializationResponsibility &R)
578
0
                         -> llvm::Expected<llvm::orc::ThreadSafeModule> {
579
0
        LLVMOrcThreadSafeModuleRef TSMRef =
580
0
            wrap(new llvm::orc::ThreadSafeModule(std::move(TSM)));
581
0
        if (LLVMErrorRef Err = TransformFunction(Ctx, &TSMRef, wrap(&R))) {
582
0
          return unwrap(Err);
583
0
        }
584
0
        return std::move(*unwrap(TSMRef));
585
0
      });
586
0
}
587
#endif
588
#if LLVM_VERSION_MAJOR < 13
589
LLVMErrorRef
590
LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM,
591
                                    LLVMOrcGenericIRModuleOperationFunction F,
592
0
                                    void *Ctx) noexcept {
593
0
  using llvm::unwrap;
594
0
  using llvm::wrap;
595
#if LLVM_VERSION_MAJOR < 10
596
  auto Lock = unwrap(TSM)->getContextLock();
597
  return F(Ctx, wrap(unwrap(TSM)->getModule()));
598
#else
599
0
  return wrap(unwrap(TSM)->withModuleDo(
600
0
      [&](llvm::Module &M) { return unwrap(F(Ctx, wrap(&M))); }));
601
0
#endif
602
0
}
603
#endif