diff options
Diffstat (limited to 'compiler-rt/lib/xray/xray_interface.cc')
-rw-r--r-- | compiler-rt/lib/xray/xray_interface.cc | 59 |
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); } |