summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/xray/xray_AArch64.cc3
-rw-r--r--lib/xray/xray_arm.cc3
-rw-r--r--lib/xray/xray_emulate_tsc.h5
-rw-r--r--lib/xray/xray_inmemory_log.cc5
-rw-r--r--lib/xray/xray_x86_64.cc22
-rw-r--r--lib/xray/xray_x86_64.h3
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