1//===----------------------------------------------------------------------===//
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// Host GPU shim for sanitizer runtimes. HSA is resolved, never linked.
10// Callers must not include a system hsa.h alongside this header.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef SANITIZER_OFFLOAD_H
15#define SANITIZER_OFFLOAD_H
16
17#include "sanitizer_atomic.h"
18#include "sanitizer_common.h"
19#include "sanitizer_mutex.h"
20#include "sanitizer_offload_hsa.h"
21#include "sanitizer_symbolizer.h"
22
23namespace __sanitizer {
24
25struct OffloadRpc;
26
27class Offload {
28 public:
29 static Offload& Get();
30
31 bool Init();
32 void Shutdown();
33 bool Ready() const;
34
35 const void* HostPointer(uptr DeviceAddr);
36
37 using Handler = u32 (*)(void* Port, u32 Lanes);
38 void RegisterHandler(Handler Fn);
39
40 void TrackExecutable(hsa_executable_t Exec);
41 void UntrackExecutable(hsa_executable_t Exec);
42 void UntrackImages();
43 bool GetMemoryPool(hsa_agent_t Agent, hsa_amd_memory_pool_t* Pool);
44 bool Allocate(hsa_amd_memory_pool_t Pool, uptr Bytes, void** Out);
45 SymbolizedStack* Symbolize(uptr PC);
46 bool SymbolizeData(uptr Addr, DataInfo* Info);
47
48 private:
49 friend struct OffloadRpc;
50
51 constexpr Offload() = default;
52
53 static Offload Ctx;
54
55 struct Device {
56 hsa_agent_t Agent;
57 hsa_amd_memory_pool_t Pool;
58 u32 Lanes;
59 u32 MaxWaves;
60 };
61
62 struct Api {
63#define SANITIZER_HSA_DECLARE(Name) decltype(&::Name) Name;
64 SANITIZER_HSA_FUNCTIONS(SANITIZER_HSA_DECLARE)
65#undef SANITIZER_HSA_DECLARE
66 } Api{};
67
68 bool Resolve();
69 bool Discover();
70 bool BindLoader();
71 bool Release();
72 void Teardown();
73
74 const Device& Host() const { return HostDevice; }
75 const InternalMmapVectorNoCtor<Device>& Devices() const { return DeviceList; }
76
77 bool Alloc(const Device& D, uptr Bytes, void** Out);
78 void Free(void* P);
79 bool Copy(void* Dst, const void* Src, uptr N);
80 bool Lookup(hsa_executable_t Exec, const char* Name, hsa_agent_t Agent,
81 u64* Addr);
82 bool CreateSignal(hsa_signal_t* Out);
83 void DestroySignal(hsa_signal_t Sig);
84 void WaitSignal(hsa_signal_t Sig);
85 void StoreSignal(hsa_signal_t Sig);
86
87 void TrackImage(uptr LoadBase, uptr LoadSize, const void* Storage,
88 uptr StorageSize);
89 void UntrackImage(uptr LoadBase);
90 bool ExecutableInfo(hsa_loaded_code_object_t Obj,
91 hsa_ven_amd_loader_loaded_code_object_info_t Attr,
92 u64* Out);
93 template <typename Cb>
94 void ForEachAgentObject(hsa_executable_t Exec, Cb F);
95
96 Device HostDevice{};
97 InternalMmapVectorNoCtor<Device> DeviceList{};
98
99 // Serializes initialization and shutdown of the core HSA interface.
100 Mutex LifetimeMtx{};
101
102 // Serializes HSA functions that affect the common compiler-rt state.
103 Mutex OffloadMtx{};
104 uptr Refs{};
105 atomic_uint8_t Active{};
106 LoaderApi Loader{};
107};
108
109} // namespace __sanitizer
110
111#endif // SANITIZER_OFFLOAD_H
112