1 //===-- scudo_utils.cpp -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// Platform specific utility functions.
12 //===----------------------------------------------------------------------===//
14 #include "scudo_utils.h"
20 #if defined(__x86_64__) || defined(__i386__)
23 #if defined(__arm__) || defined(__aarch64__)
24 # include <sys/auxv.h>
27 // TODO(kostyak): remove __sanitizer *Printf uses in favor for our own less
28 // complicated string formatting code. The following is a
29 // temporary workaround to be able to use __sanitizer::VSNPrintf.
30 namespace __sanitizer {
32 extern int VSNPrintf(char *buff, int buff_length, const char *format,
35 } // namespace __sanitizer
40 void NORETURN dieWithMessage(const char *Format, ...) {
41 // Our messages are tiny, 256 characters is more than enough.
44 va_start(Args, Format);
45 __sanitizer::VSNPrintf(Message, sizeof(Message), Format, Args);
51 #if defined(__x86_64__) || defined(__i386__)
52 // i386 and x86_64 specific code to detect CRC32 hardware support via CPUID.
53 // CRC32 requires the SSE 4.2 instruction set.
61 static void getCPUID(CPUIDRegs *Regs, u32 Level)
63 __get_cpuid(Level, &Regs->Eax, &Regs->Ebx, &Regs->Ecx, &Regs->Edx);
66 CPUIDRegs getCPUFeatures() {
67 CPUIDRegs VendorRegs = {};
68 getCPUID(&VendorRegs, 0);
70 (VendorRegs.Ebx == signature_INTEL_ebx) &&
71 (VendorRegs.Edx == signature_INTEL_edx) &&
72 (VendorRegs.Ecx == signature_INTEL_ecx);
74 (VendorRegs.Ebx == signature_AMD_ebx) &&
75 (VendorRegs.Edx == signature_AMD_edx) &&
76 (VendorRegs.Ecx == signature_AMD_ecx);
77 // Default to an empty feature set if not on a supported CPU.
78 CPUIDRegs FeaturesRegs = {};
79 if (IsIntel || IsAMD) {
80 getCPUID(&FeaturesRegs, 1);
86 # define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines.
89 bool testCPUFeature(CPUFeature Feature)
91 CPUIDRegs FeaturesRegs = getCPUFeatures();
94 case CRC32CPUFeature: // CRC32 is provided by SSE 4.2.
95 return !!(FeaturesRegs.Ecx & bit_SSE4_2);
101 #elif defined(__arm__) || defined(__aarch64__)
102 // For ARM and AArch64, hardware CRC32 support is indicated in the
103 // AT_HWVAL auxiliary vector.
106 # define HWCAP_CRC32 (1<<7) // HWCAP_CRC32 is missing on older platforms.
109 bool testCPUFeature(CPUFeature Feature) {
110 uptr HWCap = getauxval(AT_HWCAP);
113 case CRC32CPUFeature:
114 return !!(HWCap & HWCAP_CRC32);
121 bool testCPUFeature(CPUFeature Feature) {
124 #endif // defined(__x86_64__) || defined(__i386__)
126 } // namespace __scudo