diff options
4 files changed, 53 insertions, 35 deletions
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp index e6fe60a9486..0b105634a56 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp @@ -27,6 +27,8 @@ enum debugState { debugStateOn }; +extern "C" bool CPUHasAVX(); // Defined over in DNBArchImplX86_64.cpp + static debugState sFPUDebugState = debugStateUnknown; static debugState sAVXForceState = debugStateUnknown; @@ -252,9 +254,6 @@ enum gdb_ymm7 = gdb_xmm7 }; -// AVX support isn't working at all from user space, so disable it for now. -enum DNBArchImplI386::AVXPresence DNBArchImplI386::s_has_avx = DNBArchImplI386::kAVXNotPresent; - uint64_t DNBArchImplI386::GetPC(uint64_t failValue) { diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h index fe1af6dbe16..316aed2ba50 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -223,15 +223,6 @@ protected: static const DNBRegisterSetInfo * GetRegisterSetInfo(nub_size_t *num_reg_sets); - static bool - CPUHasAVX() - { - if (s_has_avx == kAVXUnknown) - s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent); - - return (s_has_avx == kAVXPresent); - } - // Helper functions for watchpoint manipulations. static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write); static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index); @@ -242,12 +233,6 @@ protected: MachThread *m_thread; State m_state; - - static enum AVXPresence { - kAVXPresent, - kAVXNotPresent, - kAVXUnknown - } s_has_avx; }; #endif // #if defined (__i386__) || defined (__x86_64__) diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp index 48ea92d6a6b..3206874d938 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp @@ -14,6 +14,8 @@ #if defined (__i386__) || defined (__x86_64__) #include <sys/cdefs.h> +#include <sys/types.h> +#include <sys/sysctl.h> #include "MacOSX/x86_64/DNBArchImplX86_64.h" #include "DNBLog.h" @@ -65,7 +67,54 @@ static bool ForceAVXRegs () #define FORCE_AVX_REGS (0) #endif -enum DNBArchImplX86_64::AVXPresence DNBArchImplX86_64::s_has_avx = DNBArchImplX86_64::kAVXNotPresent; + +extern "C" bool +CPUHasAVX() +{ + enum AVXPresence + { + eAVXUnknown = -1, + eAVXNotPresent = 0, + eAVXPresent = 1 + }; + + static AVXPresence g_has_avx = eAVXUnknown; + if (g_has_avx == eAVXUnknown) + { + g_has_avx = eAVXNotPresent; + + // 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 (<rdar://problem/10122874>). 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)\n", g_has_avx, err, errno, xnu_version); + } + + return (g_has_avx == eAVXPresent); +} uint64_t DNBArchImplX86_64::GetPC(uint64_t failValue) diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h index 1e2f1fb4962..04c07bc0dd1 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h @@ -230,15 +230,6 @@ protected: static const DNBRegisterSetInfo * GetRegisterSetInfo(nub_size_t *num_reg_sets); - static bool - CPUHasAVX() - { - if (s_has_avx == kAVXUnknown) - s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent); - - return (s_has_avx == kAVXPresent); - } - // Helper functions for watchpoint manipulations. static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write); static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index); @@ -248,13 +239,7 @@ protected: static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index); MachThread *m_thread; - State m_state; - - static enum AVXPresence { - kAVXPresent, - kAVXNotPresent, - kAVXUnknown - } s_has_avx; + State m_state; }; #endif // #if defined (__i386__) || defined (__x86_64__) |

