summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/xray/xray_interface.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/xray/xray_interface.cc')
-rw-r--r--compiler-rt/lib/xray/xray_interface.cc59
1 files changed, 53 insertions, 6 deletions
diff --git a/compiler-rt/lib/xray/xray_interface.cc b/compiler-rt/lib/xray/xray_interface.cc
index 766313e85c5..edfb59c6c23 100644
--- a/compiler-rt/lib/xray/xray_interface.cc
+++ b/compiler-rt/lib/xray/xray_interface.cc
@@ -19,9 +19,12 @@
#include <cstdio>
#include <errno.h>
#include <limits>
+#include <string.h>
#include <sys/mman.h>
+#include "sanitizer_common/sanitizer_addrhashmap.h"
#include "sanitizer_common/sanitizer_common.h"
+
#include "xray_defs.h"
#include "xray_flags.h"
@@ -56,18 +59,32 @@ __sanitizer::atomic_uintptr_t XRayArgLogger{0};
// This is the function to call when we encounter a custom event log call.
__sanitizer::atomic_uintptr_t XRayPatchedCustomEvent{0};
+// This is the function to call when we encounter a typed event log call.
+__sanitizer::atomic_uintptr_t XRayPatchedTypedEvent{0};
+
// This is the global status to determine whether we are currently
// patching/unpatching.
__sanitizer::atomic_uint8_t XRayPatching{0};
-// MProtectHelper is an RAII wrapper for calls to mprotect(...) that will undo
-// any successful mprotect(...) changes. This is used to make a page writeable
-// and executable, and upon destruction if it was successful in doing so returns
-// the page into a read-only and executable page.
+struct TypeDescription {
+ uint32_t type_id;
+ std::size_t description_string_length;
+};
+
+using TypeDescriptorMapType = __sanitizer::AddrHashMap<TypeDescription, 11>;
+// An address map from immutable descriptors to type ids.
+TypeDescriptorMapType TypeDescriptorAddressMap{};
+
+__sanitizer::atomic_uint32_t TypeEventDescriptorCounter{0};
+
+// MProtectHelper is an RAII wrapper for calls to mprotect(...) that will
+// undo any successful mprotect(...) changes. This is used to make a page
+// writeable and executable, and upon destruction if it was successful in
+// doing so returns the page into a read-only and executable page.
//
// This is only used specifically for runtime-patching of the XRay
-// instrumentation points. This assumes that the executable pages are originally
-// read-and-execute only.
+// instrumentation points. This assumes that the executable pages are
+// originally read-and-execute only.
class MProtectHelper {
void *PageAlignedAddr;
std::size_t MProtectLen;
@@ -116,6 +133,9 @@ bool patchSled(const XRaySledEntry &Sled, bool Enable,
case XRayEntryType::CUSTOM_EVENT:
Success = patchCustomEvent(Enable, FuncId, Sled);
break;
+ case XRayEntryType::TYPED_EVENT:
+ Success = patchTypedEvent(Enable, FuncId, Sled);
+ break;
default:
Report("Unsupported sled kind '%d' @%04x\n", Sled.Address, int(Sled.Kind));
return false;
@@ -341,6 +361,18 @@ int __xray_set_customevent_handler(void (*entry)(void *, size_t))
return 0;
}
+int __xray_set_typedevent_handler(void (*entry)(
+ uint16_t, const void *, size_t)) noexcept XRAY_NEVER_INSTRUMENT {
+ if (__sanitizer::atomic_load(&XRayInitialized,
+ __sanitizer::memory_order_acquire)) {
+ __sanitizer::atomic_store(&__xray::XRayPatchedTypedEvent,
+ reinterpret_cast<uintptr_t>(entry),
+ __sanitizer::memory_order_release);
+ return 1;
+ }
+ return 0;
+}
+
int __xray_remove_handler() XRAY_NEVER_INSTRUMENT {
return __xray_set_handler(nullptr);
}
@@ -349,6 +381,21 @@ int __xray_remove_customevent_handler() XRAY_NEVER_INSTRUMENT {
return __xray_set_customevent_handler(nullptr);
}
+int __xray_remove_typedevent_handler() noexcept XRAY_NEVER_INSTRUMENT {
+ return __xray_set_typedevent_handler(nullptr);
+}
+
+uint16_t __xray_register_event_type(
+ const char *const event_type) noexcept XRAY_NEVER_INSTRUMENT {
+ TypeDescriptorMapType::Handle h(&TypeDescriptorAddressMap, (uptr)event_type);
+ if (h.created()) {
+ h->type_id = __sanitizer::atomic_fetch_add(
+ &TypeEventDescriptorCounter, 1, __sanitizer::memory_order_acq_rel);
+ h->description_string_length = strnlen(event_type, 1024);
+ }
+ return h->type_id;
+}
+
XRayPatchingStatus __xray_patch() XRAY_NEVER_INSTRUMENT {
return controlPatching(true);
}
OpenPOWER on IntegriCloud