1 //===------ TargetProcessControl.cpp -- Target process control APIs -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
10
11 #include "llvm/ExecutionEngine/Orc/Core.h"
12 #include "llvm/Support/Host.h"
13 #include "llvm/Support/Process.h"
14
15 #include <mutex>
16
17 namespace llvm {
18 namespace orc {
19
~MemoryAccess()20 TargetProcessControl::MemoryAccess::~MemoryAccess() {}
21
~TargetProcessControl()22 TargetProcessControl::~TargetProcessControl() {}
23
SelfTargetProcessControl(Triple TT,unsigned PageSize,std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr)24 SelfTargetProcessControl::SelfTargetProcessControl(
25 Triple TT, unsigned PageSize,
26 std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {
27
28 OwnedMemMgr = std::move(MemMgr);
29 if (!OwnedMemMgr)
30 OwnedMemMgr = std::make_unique<jitlink::InProcessMemoryManager>();
31
32 this->TT = std::move(TT);
33 this->PageSize = PageSize;
34 this->MemMgr = OwnedMemMgr.get();
35 this->MemAccess = this;
36 if (this->TT.isOSBinFormatMachO())
37 GlobalManglingPrefix = '_';
38 }
39
40 Expected<std::unique_ptr<SelfTargetProcessControl>>
Create(std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr)41 SelfTargetProcessControl::Create(
42 std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {
43 auto PageSize = sys::Process::getPageSize();
44 if (!PageSize)
45 return PageSize.takeError();
46
47 Triple TT(sys::getProcessTriple());
48
49 return std::make_unique<SelfTargetProcessControl>(std::move(TT), *PageSize,
50 std::move(MemMgr));
51 }
52
53 Expected<TargetProcessControl::DylibHandle>
loadDylib(const char * DylibPath)54 SelfTargetProcessControl::loadDylib(const char *DylibPath) {
55 std::string ErrMsg;
56 auto Dylib = std::make_unique<sys::DynamicLibrary>(
57 sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg));
58 if (!Dylib->isValid())
59 return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
60 DynamicLibraries.push_back(std::move(Dylib));
61 return pointerToJITTargetAddress(DynamicLibraries.back().get());
62 }
63
64 Expected<TargetProcessControl::LookupResult>
lookupSymbols(LookupRequest Request)65 SelfTargetProcessControl::lookupSymbols(LookupRequest Request) {
66 LookupResult R;
67
68 for (auto &Elem : Request) {
69 auto *Dylib = jitTargetAddressToPointer<sys::DynamicLibrary *>(Elem.Handle);
70 assert(llvm::find_if(DynamicLibraries,
71 [=](const std::unique_ptr<sys::DynamicLibrary> &DL) {
72 return DL.get() == Dylib;
73 }) != DynamicLibraries.end() &&
74 "Invalid handle");
75
76 R.push_back(std::vector<JITTargetAddress>());
77 for (auto &KV : Elem.Symbols) {
78 auto &Sym = KV.first;
79 std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
80 (*Sym).size() - !!GlobalManglingPrefix);
81 void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str());
82 if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) {
83 // FIXME: Collect all failing symbols before erroring out.
84 SymbolNameVector MissingSymbols;
85 MissingSymbols.push_back(Sym);
86 return make_error<SymbolsNotFound>(std::move(MissingSymbols));
87 }
88 R.back().push_back(pointerToJITTargetAddress(Addr));
89 }
90 }
91
92 return R;
93 }
94
writeUInt8s(ArrayRef<UInt8Write> Ws,WriteResultFn OnWriteComplete)95 void SelfTargetProcessControl::writeUInt8s(ArrayRef<UInt8Write> Ws,
96 WriteResultFn OnWriteComplete) {
97 for (auto &W : Ws)
98 *jitTargetAddressToPointer<uint8_t *>(W.Address) = W.Value;
99 OnWriteComplete(Error::success());
100 }
101
writeUInt16s(ArrayRef<UInt16Write> Ws,WriteResultFn OnWriteComplete)102 void SelfTargetProcessControl::writeUInt16s(ArrayRef<UInt16Write> Ws,
103 WriteResultFn OnWriteComplete) {
104 for (auto &W : Ws)
105 *jitTargetAddressToPointer<uint16_t *>(W.Address) = W.Value;
106 OnWriteComplete(Error::success());
107 }
108
writeUInt32s(ArrayRef<UInt32Write> Ws,WriteResultFn OnWriteComplete)109 void SelfTargetProcessControl::writeUInt32s(ArrayRef<UInt32Write> Ws,
110 WriteResultFn OnWriteComplete) {
111 for (auto &W : Ws)
112 *jitTargetAddressToPointer<uint32_t *>(W.Address) = W.Value;
113 OnWriteComplete(Error::success());
114 }
115
writeUInt64s(ArrayRef<UInt64Write> Ws,WriteResultFn OnWriteComplete)116 void SelfTargetProcessControl::writeUInt64s(ArrayRef<UInt64Write> Ws,
117 WriteResultFn OnWriteComplete) {
118 for (auto &W : Ws)
119 *jitTargetAddressToPointer<uint64_t *>(W.Address) = W.Value;
120 OnWriteComplete(Error::success());
121 }
122
writeBuffers(ArrayRef<BufferWrite> Ws,WriteResultFn OnWriteComplete)123 void SelfTargetProcessControl::writeBuffers(ArrayRef<BufferWrite> Ws,
124 WriteResultFn OnWriteComplete) {
125 for (auto &W : Ws)
126 memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
127 W.Buffer.size());
128 OnWriteComplete(Error::success());
129 }
130
131 } // end namespace orc
132 } // end namespace llvm
133