From b9fc7c5eae61d168e677d96c1f1ad8a14cd1c3bd Mon Sep 17 00:00:00 2001 From: trav90 Date: Sat, 26 May 2018 20:54:19 -0500 Subject: Display an error on Linux in the absence of SSE2 --- application/palemoon/app/Makefile.in | 8 ++++++ application/palemoon/app/moz.build | 3 +++ application/palemoon/app/nsBrowserApp.cpp | 45 +++++++++++++++++++++++++++++++ application/palemoon/confvars.sh | 5 ++++ browser/app/Makefile.in | 8 ++++++ browser/app/moz.build | 4 +++ browser/app/nsBrowserApp.cpp | 45 +++++++++++++++++++++++++++++++ browser/confvars.sh | 5 ++++ old-configure.in | 6 +++++ 9 files changed, 129 insertions(+) diff --git a/application/palemoon/app/Makefile.in b/application/palemoon/app/Makefile.in index c0f01212c..12f28768a 100644 --- a/application/palemoon/app/Makefile.in +++ b/application/palemoon/app/Makefile.in @@ -33,6 +33,14 @@ NSDISTMODE = copy include $(topsrcdir)/config/config.mk +# If we are trying to show an error dialog about the lack of SSE2 support, +# make sure that code itself doesn't use SSE2. +ifdef MOZ_LINUX_SSE2_STARTUP_ERROR +CXXFLAGS := $(filter-out -march=% -msse2 -mfpmath=sse,$(CXXFLAGS)) +CXX := $(filter-out -march=% -msse2 -mfpmath=sse,$(CXX)) +CXXFLAGS += -mno-sse2 -mfpmath=387 +endif + ifeq ($(OS_ARCH),WINNT) # Rebuild firefox.exe if the manifest changes - it's included by splash.rc. # (this dependency should really be just for firefox.exe, not other targets) diff --git a/application/palemoon/app/moz.build b/application/palemoon/app/moz.build index 8b358b622..044c3e2d1 100644 --- a/application/palemoon/app/moz.build +++ b/application/palemoon/app/moz.build @@ -68,3 +68,6 @@ if CONFIG['MOZ_LINKER']: if CONFIG['HAVE_CLOCK_MONOTONIC']: OS_LIBS += CONFIG['REALTIME_LIBS'] + +if CONFIG['MOZ_LINUX_SSE2_STARTUP_ERROR']: + DEFINES['MOZ_LINUX_SSE2_STARTUP_ERROR'] = True diff --git a/application/palemoon/app/nsBrowserApp.cpp b/application/palemoon/app/nsBrowserApp.cpp index 8b0613528..c73b05d23 100644 --- a/application/palemoon/app/nsBrowserApp.cpp +++ b/application/palemoon/app/nsBrowserApp.cpp @@ -35,6 +35,51 @@ #include "mozilla/Telemetry.h" #include "mozilla/WindowsDllBlocklist.h" +#ifdef MOZ_LINUX_SSE2_STARTUP_ERROR +#include +#include "mozilla/Unused.h" + +static bool +IsSSE2Available() +{ + // The rest of the app has been compiled to assume that SSE2 is present + // unconditionally, so we can't use the normal copy of SSE.cpp here. + // Since SSE.cpp caches the results and we need them only transiently, + // instead of #including SSE.cpp here, let's just inline the specific check + // that's needed. + unsigned int level = 1u; + unsigned int eax, ebx, ecx, edx; + unsigned int bits = (1u<<26); + unsigned int max = __get_cpuid_max(0, nullptr); + if (level > max) { + return false; + } + __cpuid_count(level, 0, eax, ebx, ecx, edx); + return (edx & bits) == bits; +} + +static const char sSSE2Message[] = + "This browser version requires a processor with the SSE2 instruction " + "set extension.\n"; + +__attribute__((constructor)) +static void +SSE2Check() +{ + if (IsSSE2Available()) { + return; + } + // Using write() in order to avoid jemalloc-based buffering. Ignoring return + // values, since there isn't much we could do on failure and there is no + // point in trying to recover from errors. + MOZ_UNUSED(write(STDERR_FILENO, + sSSE2Message, + MOZ_ARRAY_LENGTH(sSSE2Message) - 1)); + // _exit() instead of exit() to avoid running the usual "at exit" code. + _exit(255); +} +#endif + #if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID) #define MOZ_BROWSER_CAN_BE_CONTENTPROC #include "../../ipc/contentproc/plugin-container.cpp" diff --git a/application/palemoon/confvars.sh b/application/palemoon/confvars.sh index 5109c0829..d1d2ce065 100644 --- a/application/palemoon/confvars.sh +++ b/application/palemoon/confvars.sh @@ -98,6 +98,11 @@ if test "$OS_ARCH" = "WINNT" -o \ MOZ_BUNDLED_FONTS=1 fi +# Display an error on non-SSE2 Linux systems +if test "$OS_ARCH" = "Linux"; then + MOZ_LINUX_SSE2_STARTUP_ERROR=1 +fi + # Short-circuit a few services to be removed MOZ_MAINTENANCE_SERVICE= MOZ_SERVICES_HEALTHREPORT= diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in index d807b4337..cb35ed1fb 100644 --- a/browser/app/Makefile.in +++ b/browser/app/Makefile.in @@ -23,6 +23,14 @@ NSDISTMODE = copy include $(topsrcdir)/config/config.mk +# If we are trying to show an error dialog about the lack of SSE2 support, +# make sure that code itself doesn't use SSE2. +ifdef MOZ_LINUX_SSE2_STARTUP_ERROR +CXXFLAGS := $(filter-out -march=% -msse2 -mfpmath=sse,$(CXXFLAGS)) +CXX := $(filter-out -march=% -msse2 -mfpmath=sse,$(CXX)) +CXXFLAGS += -mno-sse2 -mfpmath=387 +endif + ifeq ($(OS_ARCH),WINNT) # Rebuild firefox.exe if the manifest changes - it's included by splash.rc. # (this dependency should really be just for firefox.exe, not other targets) diff --git a/browser/app/moz.build b/browser/app/moz.build index 1004e280c..9650761ee 100644 --- a/browser/app/moz.build +++ b/browser/app/moz.build @@ -70,6 +70,10 @@ if CONFIG['HAVE_CLOCK_MONOTONIC']: if CONFIG['MOZ_GPSD']: DEFINES['MOZ_GPSD'] = True + +if CONFIG['MOZ_LINUX_SSE2_STARTUP_ERROR']: + DEFINES['MOZ_LINUX_SSE2_STARTUP_ERROR'] = True + for icon in ('firefox', 'document', 'newwindow', 'newtab', 'pbmode'): DEFINES[icon.upper() + '_ICO'] = '"%s/dist/branding/%s.ico"' % ( TOPOBJDIR, icon) diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp index 66ea8aed5..fc5ea8785 100644 --- a/browser/app/nsBrowserApp.cpp +++ b/browser/app/nsBrowserApp.cpp @@ -35,6 +35,51 @@ #include "mozilla/Telemetry.h" #include "mozilla/WindowsDllBlocklist.h" +#ifdef MOZ_LINUX_SSE2_STARTUP_ERROR +#include +#include "mozilla/Unused.h" + +static bool +IsSSE2Available() +{ + // The rest of the app has been compiled to assume that SSE2 is present + // unconditionally, so we can't use the normal copy of SSE.cpp here. + // Since SSE.cpp caches the results and we need them only transiently, + // instead of #including SSE.cpp here, let's just inline the specific check + // that's needed. + unsigned int level = 1u; + unsigned int eax, ebx, ecx, edx; + unsigned int bits = (1u<<26); + unsigned int max = __get_cpuid_max(0, nullptr); + if (level > max) { + return false; + } + __cpuid_count(level, 0, eax, ebx, ecx, edx); + return (edx & bits) == bits; +} + +static const char sSSE2Message[] = + "This browser version requires a processor with the SSE2 instruction " + "set extension.\n"; + +__attribute__((constructor)) +static void +SSE2Check() +{ + if (IsSSE2Available()) { + return; + } + // Using write() in order to avoid jemalloc-based buffering. Ignoring return + // values, since there isn't much we could do on failure and there is no + // point in trying to recover from errors. + MOZ_UNUSED(write(STDERR_FILENO, + sSSE2Message, + MOZ_ARRAY_LENGTH(sSSE2Message) - 1)); + // _exit() instead of exit() to avoid running the usual "at exit" code. + _exit(255); +} +#endif + #if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID) #define MOZ_BROWSER_CAN_BE_CONTENTPROC #include "../../ipc/contentproc/plugin-container.cpp" diff --git a/browser/confvars.sh b/browser/confvars.sh index 0343034a4..e8b911da3 100755 --- a/browser/confvars.sh +++ b/browser/confvars.sh @@ -18,6 +18,11 @@ if test "$OS_ARCH" = "WINNT"; then MOZ_MAINTENANCE_SERVICE= fi +# Display an error on non-SSE2 Linux systems +if test "$OS_ARCH" = "Linux"; then + MOZ_LINUX_SSE2_STARTUP_ERROR=1 +fi + # For Basilisk we want to use 52.9.YYYY.MM.DD as MOZ_APP_VERSION in release # builds so add-on developers have something to target while maintaining # Firefox compatiblity. diff --git a/old-configure.in b/old-configure.in index 0d169d55f..4d4d66f88 100644 --- a/old-configure.in +++ b/old-configure.in @@ -4801,6 +4801,12 @@ if test "$USE_FC_FREETYPE"; then fi fi +dnl ======================================================== +dnl Check if we need the Linux SSE2 error dialog +dnl ======================================================== + +AC_SUBST(MOZ_LINUX_SSE2_STARTUP_ERROR) + dnl ======================================================== dnl Check for pixman and cairo dnl ======================================================== -- cgit v1.2.3