LLVM  13.0.0git
TargetProcessControl.cpp
Go to the documentation of this file.
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 
10 
13 #include "llvm/Support/Host.h"
14 #include "llvm/Support/Process.h"
15 
16 #include <mutex>
17 
18 namespace llvm {
19 namespace orc {
20 
22 
24 
26  std::shared_ptr<SymbolStringPool> SSP, Triple TargetTriple,
27  unsigned PageSize, std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr)
29 
30  OwnedMemMgr = std::move(MemMgr);
31  if (!OwnedMemMgr)
32  OwnedMemMgr = std::make_unique<jitlink::InProcessMemoryManager>();
33 
34  this->TargetTriple = std::move(TargetTriple);
35  this->PageSize = PageSize;
36  this->MemMgr = OwnedMemMgr.get();
37  this->MemAccess = this;
38  if (this->TargetTriple.isOSBinFormatMachO())
39  GlobalManglingPrefix = '_';
40 }
41 
44  std::shared_ptr<SymbolStringPool> SSP,
45  std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {
47  if (!PageSize)
48  return PageSize.takeError();
49 
51 
52  return std::make_unique<SelfTargetProcessControl>(
54 }
55 
57 SelfTargetProcessControl::loadDylib(const char *DylibPath) {
58  std::string ErrMsg;
59  auto Dylib = std::make_unique<sys::DynamicLibrary>(
60  sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg));
61  if (!Dylib->isValid())
62  return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
63  DynamicLibraries.push_back(std::move(Dylib));
64  return pointerToJITTargetAddress(DynamicLibraries.back().get());
65 }
66 
69  std::vector<tpctypes::LookupResult> R;
70 
71  for (auto &Elem : Request) {
72  auto *Dylib = jitTargetAddressToPointer<sys::DynamicLibrary *>(Elem.Handle);
73  assert(llvm::any_of(DynamicLibraries,
74  [=](const std::unique_ptr<sys::DynamicLibrary> &DL) {
75  return DL.get() == Dylib;
76  }) &&
77  "Invalid handle");
78 
79  R.push_back(std::vector<JITTargetAddress>());
80  for (auto &KV : Elem.Symbols) {
81  auto &Sym = KV.first;
82  std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
83  (*Sym).size() - !!GlobalManglingPrefix);
84  void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str());
85  if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) {
86  // FIXME: Collect all failing symbols before erroring out.
87  SymbolNameVector MissingSymbols;
88  MissingSymbols.push_back(Sym);
89  return make_error<SymbolsNotFound>(std::move(MissingSymbols));
90  }
91  R.back().push_back(pointerToJITTargetAddress(Addr));
92  }
93  }
94 
95  return R;
96 }
97 
101  using MainTy = int (*)(int, char *[]);
102  return orc::runAsMain(jitTargetAddressToFunction<MainTy>(MainFnAddr), Args);
103 }
104 
107  ArrayRef<uint8_t> ArgBuffer) {
108  using WrapperFnTy =
109  tpctypes::CWrapperFunctionResult (*)(const uint8_t *Data, uint64_t Size);
110  auto *WrapperFn = jitTargetAddressToFunction<WrapperFnTy>(WrapperFnAddr);
111  return WrapperFn(ArgBuffer.data(), ArgBuffer.size());
112 }
113 
115 
116 void SelfTargetProcessControl::writeUInt8s(ArrayRef<tpctypes::UInt8Write> Ws,
117  WriteResultFn OnWriteComplete) {
118  for (auto &W : Ws)
119  *jitTargetAddressToPointer<uint8_t *>(W.Address) = W.Value;
120  OnWriteComplete(Error::success());
121 }
122 
123 void SelfTargetProcessControl::writeUInt16s(ArrayRef<tpctypes::UInt16Write> Ws,
124  WriteResultFn OnWriteComplete) {
125  for (auto &W : Ws)
126  *jitTargetAddressToPointer<uint16_t *>(W.Address) = W.Value;
127  OnWriteComplete(Error::success());
128 }
129 
130 void SelfTargetProcessControl::writeUInt32s(ArrayRef<tpctypes::UInt32Write> Ws,
131  WriteResultFn OnWriteComplete) {
132  for (auto &W : Ws)
133  *jitTargetAddressToPointer<uint32_t *>(W.Address) = W.Value;
134  OnWriteComplete(Error::success());
135 }
136 
137 void SelfTargetProcessControl::writeUInt64s(ArrayRef<tpctypes::UInt64Write> Ws,
138  WriteResultFn OnWriteComplete) {
139  for (auto &W : Ws)
140  *jitTargetAddressToPointer<uint64_t *>(W.Address) = W.Value;
141  OnWriteComplete(Error::success());
142 }
143 
144 void SelfTargetProcessControl::writeBuffers(ArrayRef<tpctypes::BufferWrite> Ws,
145  WriteResultFn OnWriteComplete) {
146  for (auto &W : Ws)
147  memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
148  W.Buffer.size());
149  OnWriteComplete(Error::success());
150 }
151 
152 } // end namespace orc
153 } // end namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm
Definition: AllocatorList.h:23
llvm::orc::SelfTargetProcessControl::runAsMain
Expected< int32_t > runAsMain(JITTargetAddress MainFnAddr, ArrayRef< std::string > Args) override
Run function with a main-like signature.
Definition: TargetProcessControl.cpp:99
llvm::orc::TargetProcessControl::SSP
std::shared_ptr< SymbolStringPool > SSP
Definition: TargetProcessControl.h:158
Host.h
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:134
llvm::orc::SelfTargetProcessControl::disconnect
Error disconnect() override
Disconnect from the target process.
Definition: TargetProcessControl.cpp:114
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:332
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::Data
@ Data
Definition: SIMachineScheduler.h:56
llvm::orc::SelfTargetProcessControl::loadDylib
Expected< tpctypes::DylibHandle > loadDylib(const char *DylibPath) override
Load the dynamic library at the given path and return a handle to it.
Definition: TargetProcessControl.cpp:57
llvm::orc::TargetProcessControl::MemoryAccess::~MemoryAccess
virtual ~MemoryAccess()
Definition: TargetProcessControl.cpp:21
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:160
Process.h
llvm::orc::SelfTargetProcessControl::runWrapper
Expected< tpctypes::WrapperFunctionResult > runWrapper(JITTargetAddress WrapperFnAddr, ArrayRef< uint8_t > ArgBuffer) override
Run a wrapper function with signature:
Definition: TargetProcessControl.cpp:106
llvm::sys::DynamicLibrary::getPermanentLibrary
static DynamicLibrary getPermanentLibrary(const char *filename, std::string *errMsg=nullptr)
This function permanently loads the dynamic library at the given path.
Definition: DynamicLibrary.cpp:146
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::Triple::isOSBinFormatMachO
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:645
llvm::orc::runAsMain
int runAsMain(int(*Main)(int, char *[]), ArrayRef< std::string > Args, Optional< StringRef > ProgramName=None)
Run a main function, returning the result.
Definition: TargetExecutionUtils.cpp:16
llvm::orc::SelfTargetProcessControl::Create
static Expected< std::unique_ptr< SelfTargetProcessControl > > Create(std::shared_ptr< SymbolStringPool > SSP, std::unique_ptr< jitlink::JITLinkMemoryManager > MemMgr=nullptr)
Create a SelfTargetProcessControl with the given memory manager.
Definition: TargetProcessControl.cpp:43
llvm::orc::TargetProcessControl
TargetProcessControl supports interaction with a JIT target process.
Definition: TargetProcessControl.h:32
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::orc::SelfTargetProcessControl::SelfTargetProcessControl
SelfTargetProcessControl(std::shared_ptr< SymbolStringPool > SSP, Triple TargetTriple, unsigned PageSize, std::unique_ptr< jitlink::JITLinkMemoryManager > MemMgr)
Definition: TargetProcessControl.cpp:25
llvm::sys::Process::getPageSize
static Expected< unsigned > getPageSize()
Get the process's page size.
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1540
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1489
llvm::orc::TargetProcessControl::MemMgr
jitlink::JITLinkMemoryManager * MemMgr
Definition: TargetProcessControl.h:162
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::pointerToJITTargetAddress
JITTargetAddress pointerToJITTargetAddress(T *Ptr)
Convert a pointer to a JITTargetAddress.
Definition: JITSymbol.h:69
llvm::orc::TargetProcessControl::PageSize
unsigned PageSize
Definition: TargetProcessControl.h:160
llvm::orc::TargetProcessControl::TargetTriple
Triple TargetTriple
Definition: TargetProcessControl.h:159
std
Definition: BitVector.h:838
TargetProcessControl.h
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::sys::getProcessTriple
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Host.cpp:1678
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::TargetProcessControl::MemAccess
MemoryAccess * MemAccess
Definition: TargetProcessControl.h:161
llvm::orc::tpctypes::CWrapperFunctionResult
C ABI compatible wrapper function result.
Definition: TargetProcessControlTypes.h:74
llvm::JITTargetAddress
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:42
llvm::orc::TargetProcessControl::~TargetProcessControl
virtual ~TargetProcessControl()
Definition: TargetProcessControl.cpp:23
Core.h
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::orc::SelfTargetProcessControl::lookupSymbols
Expected< std::vector< tpctypes::LookupResult > > lookupSymbols(ArrayRef< LookupRequest > Request) override
Search for symbols in the target process.
Definition: TargetProcessControl.cpp:68
TargetExecutionUtils.h
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::orc::SymbolLookupFlags::RequiredSymbol
@ RequiredSymbol
llvm::orc::SymbolNameVector
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
Definition: Core.h:106