Index: compiler-rt/trunk/lib/xray/xray_AArch64.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_AArch64.cc +++ compiler-rt/trunk/lib/xray/xray_AArch64.cc @@ -120,4 +120,7 @@ return patchSled(Enable, FuncId, Sled, __xray_FunctionTailExit); } +// FIXME: Maybe implement this better? +bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; } + } // namespace __xray Index: compiler-rt/trunk/lib/xray/xray_arm.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_arm.cc +++ compiler-rt/trunk/lib/xray/xray_arm.cc @@ -156,4 +156,7 @@ return patchSled(Enable, FuncId, Sled, __xray_FunctionTailExit); } +// FIXME: Maybe implement this better? +bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; } + } // namespace __xray Index: compiler-rt/trunk/lib/xray/xray_emulate_tsc.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_emulate_tsc.h +++ compiler-rt/trunk/lib/xray/xray_emulate_tsc.h @@ -35,6 +35,9 @@ CPU = 0; return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec; } -} + +bool probeRequiredCPUFeatures(); + +} // namespace __xray #endif // XRAY_EMULATE_TSC_H Index: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc +++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc @@ -138,6 +138,11 @@ } 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; Index: compiler-rt/trunk/lib/xray/xray_x86_64.h =================================================================== --- compiler-rt/trunk/lib/xray/xray_x86_64.h +++ compiler-rt/trunk/lib/xray/xray_x86_64.h @@ -27,6 +27,9 @@ CPU = LongCPU; return TSC; } + +bool probeRequiredCPUFeatures(); + } // namespace __xray #endif // XRAY_X86_64_H Index: compiler-rt/trunk/lib/xray/xray_x86_64.cc =================================================================== --- compiler-rt/trunk/lib/xray/xray_x86_64.cc +++ compiler-rt/trunk/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 #include #include @@ -61,8 +63,8 @@ &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 @@ 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