diff options
-rw-r--r-- | lib/xray/xray_AArch64.cc | 3 | ||||
-rw-r--r-- | lib/xray/xray_arm.cc | 3 | ||||
-rw-r--r-- | lib/xray/xray_emulate_tsc.h | 5 | ||||
-rw-r--r-- | lib/xray/xray_inmemory_log.cc | 5 | ||||
-rw-r--r-- | lib/xray/xray_x86_64.cc | 22 | ||||
-rw-r--r-- | lib/xray/xray_x86_64.h | 3 |
6 files changed, 38 insertions, 3 deletions
diff --git a/lib/xray/xray_AArch64.cc b/lib/xray/xray_AArch64.cc index af06bdbf2..952a4c7eb 100644 --- a/lib/xray/xray_AArch64.cc +++ b/lib/xray/xray_AArch64.cc @@ -120,4 +120,7 @@ bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, return patchSled(Enable, FuncId, Sled, __xray_FunctionTailExit); } +// FIXME: Maybe implement this better? +bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; } + } // namespace __xray diff --git a/lib/xray/xray_arm.cc b/lib/xray/xray_arm.cc index bf36ea067..73e9b4111 100644 --- a/lib/xray/xray_arm.cc +++ b/lib/xray/xray_arm.cc @@ -156,4 +156,7 @@ bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, return patchSled(Enable, FuncId, Sled, __xray_FunctionTailExit); } +// FIXME: Maybe implement this better? +bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; } + } // namespace __xray diff --git a/lib/xray/xray_emulate_tsc.h b/lib/xray/xray_emulate_tsc.h index a3e8b1c92..5285931dd 100644 --- a/lib/xray/xray_emulate_tsc.h +++ b/lib/xray/xray_emulate_tsc.h @@ -35,6 +35,9 @@ ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { CPU = 0; return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec; } -} + +bool probeRequiredCPUFeatures(); + +} // namespace __xray #endif // XRAY_EMULATE_TSC_H diff --git a/lib/xray/xray_inmemory_log.cc b/lib/xray/xray_inmemory_log.cc index d25a61bdb..9decfc437 100644 --- a/lib/xray/xray_inmemory_log.cc +++ b/lib/xray/xray_inmemory_log.cc @@ -138,6 +138,11 @@ void __xray_InMemoryRawLog(int32_t FuncId, } static auto Unused = [] { + if (!probeRequiredCPUFeatures()) { + Report("Required CPU features missing for XRay instrumentation, not " + "installing instrumentation hooks.\n"); + return false; + } if (flags()->xray_naive_log) __xray_set_handler(__xray_InMemoryRawLog); return true; diff --git a/lib/xray/xray_x86_64.cc b/lib/xray/xray_x86_64.cc index 3ee91896c..25c64957c 100644 --- a/lib/xray/xray_x86_64.cc +++ b/lib/xray/xray_x86_64.cc @@ -1,6 +1,8 @@ +#include "cpuid.h" #include "sanitizer_common/sanitizer_common.h" #include "xray_defs.h" #include "xray_interface_internal.h" + #include <atomic> #include <cstdint> #include <errno.h> @@ -61,8 +63,8 @@ uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT { &CPUFrequency)) { CPUFrequency *= 1000; } else if (readValueFromFile( - "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", - &CPUFrequency)) { + "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", + &CPUFrequency)) { CPUFrequency *= 1000; } else { Report("Unable to determine CPU frequency for TSC accounting.\n"); @@ -199,4 +201,20 @@ bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId, return true; } +// We determine whether the CPU we're running on has the correct features we +// need. In x86_64 this will be rdtscp support. +bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { + unsigned int EAX, EBX, ECX, EDX; + + // We check whether rdtscp support is enabled. According to the x86_64 manual, + // level should be set at 0x80000001, and we should have a look at bit 27 in + // EDX. That's 0x8000000 (or 1u << 26). + __get_cpuid(0x80000001, &EAX, &EBX, &ECX, &EDX); + if (!(EDX & (1u << 26))) { + Report("Missing rdtscp support.\n"); + return false; + } + return true; +} + } // namespace __xray diff --git a/lib/xray/xray_x86_64.h b/lib/xray/xray_x86_64.h index e3de99d63..6b2bbebb7 100644 --- a/lib/xray/xray_x86_64.h +++ b/lib/xray/xray_x86_64.h @@ -27,6 +27,9 @@ ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT { CPU = LongCPU; return TSC; } + +bool probeRequiredCPUFeatures(); + } // namespace __xray #endif // XRAY_X86_64_H |