14
14
// ===----------------------------------------------------------------------===//
15
15
16
16
#include " xray_interface_internal.h"
17
+
17
18
#include < atomic>
18
19
#include < cstdint>
19
20
#include < cstdio>
20
21
#include < errno.h>
21
22
#include < limits>
22
23
#include < sys/mman.h>
23
24
25
+ #include " sanitizer_common/sanitizer_common.h"
26
+
24
27
namespace __xray {
25
28
26
29
// This is the function to call when we encounter the entry or exit sleds.
@@ -83,8 +86,25 @@ std::atomic<bool> XRayPatching{false};
83
86
84
87
using namespace __xray ;
85
88
89
+ // FIXME: Figure out whether we can move this class to sanitizer_common instead
90
+ // as a generic "scope guard".
91
+ template <class Function > class CleanupInvoker {
92
+ Function Fn;
93
+
94
+ public:
95
+ explicit CleanupInvoker (Function Fn) : Fn(Fn) {}
96
+ CleanupInvoker (const CleanupInvoker &) = default ;
97
+ CleanupInvoker (CleanupInvoker &&) = default ;
98
+ CleanupInvoker &operator =(const CleanupInvoker &) = delete ;
99
+ CleanupInvoker &operator =(CleanupInvoker &&) = delete ;
100
+ ~CleanupInvoker () { Fn (); }
101
+ };
102
+
103
+ template <class Function > CleanupInvoker<Function> ScopeCleanup (Function Fn) {
104
+ return CleanupInvoker<Function>{Fn};
105
+ }
106
+
86
107
XRayPatchingStatus __xray_patch () {
87
- // FIXME: Make this happen asynchronously. For now just do this sequentially.
88
108
if (!XRayInitialized.load (std::memory_order_acquire))
89
109
return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.
90
110
@@ -95,6 +115,13 @@ XRayPatchingStatus __xray_patch() {
95
115
return XRayPatchingStatus::ONGOING; // Already patching.
96
116
}
97
117
118
+ bool PatchingSuccess = false ;
119
+ auto XRayPatchingStatusResetter = ScopeCleanup ([&PatchingSuccess] {
120
+ if (!PatchingSuccess) {
121
+ XRayPatching.store (false , std::memory_order_release);
122
+ }
123
+ });
124
+
98
125
// Step 1: Compute the function id, as a unique identifier per function in the
99
126
// instrumentation map.
100
127
XRaySledMap InstrMap = XRayInstrMap.load (std::memory_order_acquire);
@@ -131,6 +158,7 @@ XRayPatchingStatus __xray_patch() {
131
158
static constexpr int64_t MinOffset{std::numeric_limits<int32_t >::min ()};
132
159
static constexpr int64_t MaxOffset{std::numeric_limits<int32_t >::max ()};
133
160
if (Sled.Kind == XRayEntryType::ENTRY) {
161
+ // FIXME: Implement this in a more extensible manner, per-platform.
134
162
// Here we do the dance of replacing the following sled:
135
163
//
136
164
// xray_sled_n:
@@ -157,7 +185,10 @@ XRayPatchingStatus __xray_patch() {
157
185
reinterpret_cast <int64_t >(__xray_FunctionEntry) -
158
186
(static_cast <int64_t >(Sled.Address ) + 11 );
159
187
if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) {
160
- // FIXME: Print out an error here.
188
+ Report (" XRay Entry trampoline (%p) too far from sled (%p); distance = "
189
+ " %ld\n " ,
190
+ __xray_FunctionEntry, reinterpret_cast <void *>(Sled.Address ),
191
+ TrampolineOffset);
161
192
continue ;
162
193
}
163
194
*reinterpret_cast <uint32_t *>(Sled.Address + 2 ) = FuncId;
@@ -169,6 +200,7 @@ XRayPatchingStatus __xray_patch() {
169
200
}
170
201
171
202
if (Sled.Kind == XRayEntryType::EXIT) {
203
+ // FIXME: Implement this in a more extensible manner, per-platform.
172
204
// Here we do the dance of replacing the following sled:
173
205
//
174
206
// xray_sled_n:
@@ -193,7 +225,10 @@ XRayPatchingStatus __xray_patch() {
193
225
reinterpret_cast <int64_t >(__xray_FunctionExit) -
194
226
(static_cast <int64_t >(Sled.Address ) + 11 );
195
227
if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) {
196
- // FIXME: Print out an error here.
228
+ Report (" XRay Exit trampoline (%p) too far from sled (%p); distance = "
229
+ " %ld\n " ,
230
+ __xray_FunctionExit, reinterpret_cast <void *>(Sled.Address ),
231
+ TrampolineOffset);
197
232
continue ;
198
233
}
199
234
*reinterpret_cast <uint32_t *>(Sled.Address + 2 ) = FuncId;
@@ -205,5 +240,6 @@ XRayPatchingStatus __xray_patch() {
205
240
}
206
241
}
207
242
XRayPatching.store (false , std::memory_order_release);
208
- return XRayPatchingStatus::NOTIFIED;
243
+ PatchingSuccess = true ;
244
+ return XRayPatchingStatus::SUCCESS;
209
245
}
0 commit comments