Index: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj =================================================================== --- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj +++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj @@ -94,10 +94,8 @@ 456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; }; 456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; }; 456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D5D571293835600ED4C01 /* DNBArch.cpp */; }; - 456F67681AD46CE9002850C2 /* HasAVX.s in Sources */ = {isa = PBXBuildFile; fileRef = 4971AE7113D10F4F00649E37 /* HasAVX.s */; }; 456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B5ECF1460A68200E43F0A /* DNBArchImplARM64.cpp */; }; 456F676B1AD46CE9002850C2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; settings = {ATTRIBUTES = (Required, ); }; }; - 4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */ = {isa = PBXBuildFile; fileRef = 4971AE7113D10F4F00649E37 /* HasAVX.s */; }; 49D404621E39260F00570CDC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; }; AF48558C1D75126800D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; }; AF48558D1D75127500D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; }; @@ -210,8 +208,6 @@ 26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = ""; }; 26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = ""; }; 456F67721AD46CE9002850C2 /* debugserver-nonui */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "debugserver-nonui"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4971AE7013D10F4F00649E37 /* HasAVX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HasAVX.h; sourceTree = ""; }; - 4971AE7113D10F4F00649E37 /* HasAVX.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = HasAVX.s; sourceTree = ""; }; 49D404611E39260F00570CDC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = ""; }; 49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesX86_64.h; sourceTree = ""; }; @@ -413,8 +409,6 @@ 26C637E90C71334A0024798E /* i386 */, 26C637FA0C71334A0024798E /* ppc */, 26CF99A11142EB7400011AAB /* x86_64 */, - 4971AE7013D10F4F00649E37 /* HasAVX.h */, - 4971AE7113D10F4F00649E37 /* HasAVX.s */, 26C637E80C71334A0024798E /* dbgnub-mig.defs */, AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */, AF0934BA18E12B92005A11FD /* Genealogy.h */, @@ -626,7 +620,6 @@ 23562ED91D342B0000AB2BD4 /* LogMessage.cpp in Sources */, 26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */, 264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */, - 4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */, 237821B01D4917D20028B7A1 /* LogFilterExactMatch.cpp in Sources */, 266B5ED11460A68200E43F0A /* DNBArchImplARM64.cpp in Sources */, ); @@ -679,7 +672,6 @@ 456F67641AD46CE9002850C2 /* CFBundle.cpp in Sources */, 456F67651AD46CE9002850C2 /* PseudoTerminal.cpp in Sources */, 456F67671AD46CE9002850C2 /* DNBArch.cpp in Sources */, - 456F67681AD46CE9002850C2 /* HasAVX.s in Sources */, 23AC04D01D2F58AF0072351D /* LogFilterRegex.cpp in Sources */, 456F67691AD46CE9002850C2 /* DNBArchImplARM64.cpp in Sources */, ); Index: lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt =================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt +++ lldb/trunk/tools/debugserver/source/MacOSX/CMakeLists.txt @@ -29,7 +29,6 @@ ) add_lldb_tool(debugserver INCLUDE_IN_FRAMEWORK - HasAVX.s CFBundle.cpp CFString.cpp Genealogy.cpp Index: lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h =================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h +++ lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h @@ -1,27 +0,0 @@ -//===-- HasAVX.h ------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef HasAVX_h -#define HasAVX_h - -#if defined(__i386__) || defined(__x86_64__) - -#ifdef __cplusplus -extern "C" { -#endif - -int HasAVX(); - -#ifdef __cplusplus -} -#endif - -#endif - -#endif Index: lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s =================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s +++ lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s @@ -1,50 +0,0 @@ -//===-- HasAVX.s ---------------------------------------*- x86 Assembly -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#if defined (__i386__) || defined (__x86_64__) - -.globl _HasAVX - -_HasAVX: -#if defined (__x86_64__) - pushq %rbp - movq %rsp, %rbp - pushq %rbx -#else - pushl %ebp - movl %esp, %ebp - pushl %ebx -#endif - mov $1, %eax - cpuid // clobbers ebx - and $0x018000000, %ecx - cmp $0x018000000, %ecx - jne not_supported - mov $0, %ecx -.byte 0x0f, 0x01, 0xd0 // xgetbv, for those assemblers that don't know it - and $0x06, %eax - cmp $0x06, %eax - jne not_supported - mov $1, %eax - jmp done -not_supported: - mov $0, %eax -done: -#if defined (__x86_64__) - popq %rbx - movq %rbp, %rsp - popq %rbp -#else - popl %ebx - movl %ebp, %esp - popl %ebp -#endif - ret // return - -#endif Index: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h =================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -16,7 +16,6 @@ #if defined(__i386__) || defined(__x86_64__) -#include "../HasAVX.h" #include "DNBArch.h" #include "MachRegisterStatesI386.h" Index: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp =================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp +++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp @@ -17,7 +17,6 @@ #include #include -#include "../HasAVX.h" #include "DNBLog.h" #include "MacOSX/x86_64/DNBArchImplX86_64.h" #include "MachProcess.h" @@ -60,42 +59,64 @@ #define FORCE_AVX_REGS (0) #endif -extern "C" bool CPUHasAVX() { - enum AVXPresence { eAVXUnknown = -1, eAVXNotPresent = 0, eAVXPresent = 1 }; +bool DetectHardwareFeature(const char *feature) { + int answer = 0; + size_t answer_size = sizeof(answer); + int error = ::sysctlbyname(feature, &answer, &answer_size, NULL, 0); + return error != 0 && answer != 0; +} + +enum AVXPresence { eAVXUnknown = -1, eAVXNotPresent = 0, eAVXPresent = 1 }; + +bool LogAVXAndReturn(AVXPresence has_avx, int err, const char * os_ver) { + DNBLogThreadedIf(LOG_THREAD, + "CPUHasAVX(): g_has_avx = %i (err = %i, os_ver = %s)", + has_avx, err, os_ver); + return (has_avx == eAVXPresent); +} +extern "C" bool CPUHasAVX() { static AVXPresence g_has_avx = eAVXUnknown; - if (g_has_avx == eAVXUnknown) { - g_has_avx = eAVXNotPresent; + if (g_has_avx != eAVXUnknown) + return LogAVXAndReturn(g_has_avx, 0, ""); - // Only xnu-2020 or later has AVX support, any versions before - // this have a busted thread_get_state RPC where it would truncate - // the thread state buffer (). So we need to - // verify the kernel version number manually or disable AVX support. - int mib[2]; - char buffer[1024]; - size_t length = sizeof(buffer); - uint64_t xnu_version = 0; - mib[0] = CTL_KERN; - mib[1] = KERN_VERSION; - int err = ::sysctl(mib, 2, &buffer, &length, NULL, 0); - if (err == 0) { - const char *xnu = strstr(buffer, "xnu-"); - if (xnu) { - const char *xnu_version_cstr = xnu + 4; - xnu_version = strtoull(xnu_version_cstr, NULL, 0); - if (xnu_version >= 2020 && xnu_version != ULLONG_MAX) { - if (::HasAVX()) { - g_has_avx = eAVXPresent; - } - } - } - } - DNBLogThreadedIf(LOG_THREAD, "CPUHasAVX(): g_has_avx = %i (err = %i, errno " - "= %i, xnu_version = %llu)", - g_has_avx, err, errno, xnu_version); + g_has_avx = eAVXNotPresent; + + // OS X 10.7.3 and earlier have a bug in thread_get_state that truncated the + // size of the return. To work around this we have to disable AVX debugging + // on hosts prior to 10.7.3 (). + int mib[2]; + char buffer[1024]; + size_t length = sizeof(buffer); + mib[0] = CTL_KERN; + mib[1] = KERN_OSVERSION; + + // KERN_OSVERSION returns the build number which is a number signifying the + // major version, a capitol letter signifying the minor version, and numbers + // signifying the build (ex: on 10.12.3, the returned value is 16D32). + int err = ::sysctl(mib, 2, &buffer, &length, NULL, 0); + if (err != 0) + return LogAVXAndReturn(g_has_avx, err, ""); + + size_t first_letter = 0; + for (; first_letter < length; ++first_letter) { + // This is looking for the first uppercase letter + if (isupper(buffer[first_letter])) + break; } + char letter = buffer[first_letter]; + buffer[first_letter] = '\0'; + auto major_ver = strtoull(buffer, NULL, 0); + buffer[first_letter] = letter; + + // In this check we're looking to see that our major and minor version numer + // was >= 11E, which is the 10.7.4 release. + if (major_ver < 11 || (major_ver == 11 && letter < 'E')) + return LogAVXAndReturn(g_has_avx, err, buffer); + if (DetectHardwareFeature("hw.optional.avx1_0")) + g_has_avx = eAVXPresent; - return (g_has_avx == eAVXPresent); + return LogAVXAndReturn(g_has_avx, err, buffer); } uint64_t DNBArchImplX86_64::GetPC(uint64_t failValue) {