diff options
author | athenian200 <athenian200@outlook.com> | 2019-10-01 06:07:31 -0500 |
---|---|---|
committer | athenian200 <athenian200@outlook.com> | 2019-10-21 04:53:39 -0500 |
commit | afc187cc3f907947453b428f857acf16b2b0774e (patch) | |
tree | 9ec0854e4c647b96532943b76e215570b0d9f0f4 | |
parent | c4c4189933f8d610e501cfc8c86dfbe52c4c160d (diff) | |
download | UXP-afc187cc3f907947453b428f857acf16b2b0774e.tar UXP-afc187cc3f907947453b428f857acf16b2b0774e.tar.gz UXP-afc187cc3f907947453b428f857acf16b2b0774e.tar.lz UXP-afc187cc3f907947453b428f857acf16b2b0774e.tar.xz UXP-afc187cc3f907947453b428f857acf16b2b0774e.zip |
MoonchildProductions#1251 - Part 1: Restore initial Solaris support, fixed up.
Compared with what Pale Moon had for Solaris originally, this is mostly the same zero point I started patching from, but I've made the following changes here after reviewing all this initial code I never looked at closely before.
1. In package-manifest.in for both Basilisk and Pale Moon, I've made the SPARC code for libfreebl not interefere with the x86 code, use the proper build flags, and also updated it to allow a SPARC64 build which is more likely to be used than the 32-bit SPARC code we had there.
2. See Mozilla bug #832272 and the old rules.mk patch from around Firefox 30 in oracle/solaris-userland. I believe they screwed up NSINSTALL on Solaris when they were trying to streamline the NSS buildsystem, because they started having unexplained issues with it around that time after Firefox 22 that they never properly resolved until Mozilla began building NSS with gyp files. I'm actually not even sure how relevant the thing they broke actually is to Solaris at this point, bug 665509 is so old it predates Firefox itself and goes back to the Mozilla suite days. I believe $(INSTALL) -t was wrong, and they meant $(NSINSTALL) -t because that makes more sense and is closer to what was there originally. It's what they have for WINNT, and it's possible a fix more like that could serve for Solaris as well. Alternatively, we could get rid of all these half-broken Makefiles and start building NSS with gyp files like Mozilla did.
3. I've completely cut out support for the Sun compiler and taken into account the reality that everyone builds Firefox (and therefore its forks) with GCC now on Solaris. This alone helped clean up a lot of the uglier parts of the code.
4. I've updated all remaining SOLARIS build flags to the newer XP_SOLARIS, because the SOLARIS flag is no longer set when building Solaris.
5. I've confirmed the workaround in gtxFontconfigFonts.cpp is no longer necessary. The Solaris people got impatient about implementing a half-baked patch for a fontconfig feature that wasn't ready yet back in 2009, and somehow convinced Mozilla to patch their software to work around it when really they should have just fixed or removed their broken fontconfig patch. The feature they wanted has since been implemented properly, and no version of Solaris still uses the broken patch that required this fix. If anyone had ever properly audited this code, it would have been removed a long time ago.
41 files changed, 945 insertions, 21 deletions
diff --git a/Makefile.in b/Makefile.in index 4adf3ac9a..26cd688d4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -290,7 +290,7 @@ MAKE_SYM_STORE_PATH := $(DIST)/bin endif DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms endif -ifeq (,$(filter-out Linux,$(OS_ARCH))) +ifeq (,$(filter-out Linux SunOS,$(OS_ARCH))) MAKE_SYM_STORE_ARGS := -c --vcs-info DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms MAKE_SYM_STORE_PATH := $(DIST)/bin diff --git a/accessible/tests/mochitest/common.js b/accessible/tests/mochitest/common.js index b3f83ea84..1e48fa067 100644 --- a/accessible/tests/mochitest/common.js +++ b/accessible/tests/mochitest/common.js @@ -59,6 +59,7 @@ const nsIPropertyElement = Components.interfaces.nsIPropertyElement; const MAC = (navigator.platform.indexOf("Mac") != -1); const LINUX = (navigator.platform.indexOf("Linux") != -1); +const SOLARIS = (navigator.platform.indexOf("SunOS") != -1); const WIN = (navigator.platform.indexOf("Win") != -1); //////////////////////////////////////////////////////////////////////////////// diff --git a/accessible/tests/mochitest/elm/test_nsApplicationAcc.html b/accessible/tests/mochitest/elm/test_nsApplicationAcc.html index e23eb37bc..58763e437 100644 --- a/accessible/tests/mochitest/elm/test_nsApplicationAcc.html +++ b/accessible/tests/mochitest/elm/test_nsApplicationAcc.html @@ -32,7 +32,7 @@ // nsIAccessible::name var applicationName = ""; - if (LINUX) { + if (LINUX || SOLARIS) { applicationName = appInfo.name; } else { try { diff --git a/accessible/tests/mochitest/treeupdate/test_contextmenu.xul b/accessible/tests/mochitest/treeupdate/test_contextmenu.xul index 916b815eb..5b31e0136 100644 --- a/accessible/tests/mochitest/treeupdate/test_contextmenu.xul +++ b/accessible/tests/mochitest/treeupdate/test_contextmenu.xul @@ -130,7 +130,7 @@ */ function getMenuTree1() { - if (LINUX) { + if (LINUX || SOLARIS) { var tree = { role: ROLE_MENUPOPUP, children: [ @@ -190,7 +190,7 @@ function getMenuTree2() { var tree = getMenuTree1(); - if (LINUX) { + if (LINUX || SOLARIS) { var submenuTree = { name: "item2.0", @@ -232,7 +232,7 @@ children: [] }; - if (LINUX) + if (LINUX || SOLARIS) tree.children[2].children[0].children.push(subsubmenuTree); else tree.children[2].children[0].children[0].children[0].children.push(subsubmenuTree); diff --git a/accessible/tests/mochitest/treeupdate/test_menu.xul b/accessible/tests/mochitest/treeupdate/test_menu.xul index d62ac8c5d..abdea217e 100644 --- a/accessible/tests/mochitest/treeupdate/test_menu.xul +++ b/accessible/tests/mochitest/treeupdate/test_menu.xul @@ -32,7 +32,7 @@ this.invoke = function openMenu_invoke() { var tree; - if (LINUX) { + if (LINUX || SOLARIS) { tree = { PARENT_MENUITEM: [ ] }; @@ -51,7 +51,7 @@ this.finalCheck = function openMenu_finalCheck() { var tree; - if (LINUX) { + if (LINUX || SOLARIS) { tree = { PARENT_MENUITEM: [ { MENUITEM: [ ] }, diff --git a/application/basilisk/installer/package-manifest.in b/application/basilisk/installer/package-manifest.in index bffab0f6e..d8f65bcfb 100644 --- a/application/basilisk/installer/package-manifest.in +++ b/application/basilisk/installer/package-manifest.in @@ -685,6 +685,13 @@ #ifndef MOZ_SYSTEM_NSS #if defined(XP_LINUX) && !defined(ANDROID) @BINPATH@/@DLL_PREFIX@freeblpriv3@DLL_SUFFIX@ +#elif defined(XP_SOLARIS) && defined(SPARC64) +@BINPATH@/@DLL_PREFIX@freebl_64fpu_3@DLL_SUFFIX@ +@BINPATH@/@DLL_PREFIX@freebl_64int_3@DLL_SUFFIX@ +#elif defined(XP_SOLARIS) && defined(SPARC) +@BINPATH@/@DLL_PREFIX@freebl_32fpu_3@DLL_SUFFIX@ +@BINPATH@/@DLL_PREFIX@freebl_32int64_3@DLL_SUFFIX@ +@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@ #else @BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@ #endif diff --git a/application/palemoon/installer/package-manifest.in b/application/palemoon/installer/package-manifest.in index f95f18f77..e24b605e8 100644 --- a/application/palemoon/installer/package-manifest.in +++ b/application/palemoon/installer/package-manifest.in @@ -296,6 +296,13 @@ #ifndef MOZ_SYSTEM_NSS #if defined(XP_LINUX) && !defined(ANDROID) @BINPATH@/@DLL_PREFIX@freeblpriv3@DLL_SUFFIX@ +#elif defined(XP_SOLARIS) && defined(SPARC64) +@BINPATH@/@DLL_PREFIX@freebl_64fpu_3@DLL_SUFFIX@ +@BINPATH@/@DLL_PREFIX@freebl_64int_3@DLL_SUFFIX@ +#elif defined(XP_SOLARIS) && defined(SPARC) +@BINPATH@/@DLL_PREFIX@freebl_32fpu_3@DLL_SUFFIX@ +@BINPATH@/@DLL_PREFIX@freebl_32int64_3@DLL_SUFFIX@ +@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@ #else @BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@ #endif diff --git a/build/gyp.mozbuild b/build/gyp.mozbuild index 545b888bd..fd8714ecf 100644 --- a/build/gyp.mozbuild +++ b/build/gyp.mozbuild @@ -89,6 +89,7 @@ flavors = { 'Android': 'android', 'Linux': 'linux', 'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios', + 'SunOS': 'solaris', 'GNU/kFreeBSD': 'freebsd', 'DragonFly': 'dragonfly', 'FreeBSD': 'freebsd', diff --git a/config/external/nss/Makefile.in b/config/external/nss/Makefile.in index 2c266eb20..71954b403 100644 --- a/config/external/nss/Makefile.in +++ b/config/external/nss/Makefile.in @@ -43,6 +43,21 @@ endif # Default HAVE_FREEBL_LIBS = 1 +# SunOS SPARC + +ifeq ($(OS_ARCH), SunOS) +ifneq (86,$(findstring 86,$(OS_TEST))) +ifdef HAVE_64BIT_BUILD +HAVE_FREEBL_LIBS = +HAVE_FREEBL_LIBS_64 = 1 +else +HAVE_FREEBL_LIBS = +HAVE_FREEBL_LIBS_32FPU = 1 +HAVE_FREEBL_LIBS_32INT64 = 1 +endif +endif +endif + ifeq ($(OS_TARGET),Linux) HAVE_FREEBL_LIBS = HAVE_FREEBL_LIBS_PRIV = 1 @@ -317,6 +332,11 @@ NSS_DIST_DLL_DEST := $(DIST)/bin NSS_DIST_DLL_TARGET := target INSTALL_TARGETS += NSS_DIST_DLL +ifeq ($(OS_ARCH)_$(1), SunOS_softokn3) +# has to use copy mode on Solaris, see #665509 +$(DIST)/bin/$(DLL_PREFIX)softokn3$(DLL_SUFFIX): INSTALL := $(NSINSTALL) -t +endif + NSS_SDK_LIB_FILES := \ $(addprefix $(DIST)/lib/$(LIB_PREFIX),$(addsuffix .$(LIB_SUFFIX),$(SDK_LIBS))) \ $(addprefix $(DIST)/bin/$(DLL_PREFIX),$(addsuffix $(DLL_SUFFIX),$(NSS_DLLS))) \ diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 299a8e859..26635acd6 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -13,6 +13,10 @@ #include <float.h> #endif +#if defined(XP_SOLARIS) +#include <ieeefp.h> +#endif + #include "js/TypeDecls.h" #include "js/Value.h" #include "js/RootingAPI.h" diff --git a/dom/plugins/base/nptypes.h b/dom/plugins/base/nptypes.h index c36532472..d0cef6540 100644 --- a/dom/plugins/base/nptypes.h +++ b/dom/plugins/base/nptypes.h @@ -22,6 +22,19 @@ typedef unsigned int uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; +#elif defined(__sun) + /* + * SunOS ships an inttypes.h header that defines [u]int32_t, + * but not bool for C. + */ + #include <inttypes.h> + + + #ifndef __cplusplus + typedef int bool; + #define true 1 + #define false 0 + #endif #elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD) /* * BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and diff --git a/dom/plugins/base/nsPluginsDirUnix.cpp b/dom/plugins/base/nsPluginsDirUnix.cpp index e6956c34c..22d6bd44b 100644 --- a/dom/plugins/base/nsPluginsDirUnix.cpp +++ b/dom/plugins/base/nsPluginsDirUnix.cpp @@ -19,7 +19,9 @@ #include "nsIPrefService.h" #define LOCAL_PLUGIN_DLL_SUFFIX ".so" -#if defined(LINUX) +#if defined(XP_SOLARIS) +#define DEFAULT_X11_PATH "/usr/openwin/lib" +#elif defined(LINUX) #define DEFAULT_X11_PATH "/usr/X11R6/lib/" #elif defined(__APPLE__) #define DEFAULT_X11_PATH "/usr/X11R6/lib" @@ -92,7 +94,11 @@ static bool LoadExtraSharedLib(const char *name, char **soname, bool tryToGetSon #define PLUGIN_MAX_NUMBER_OF_EXTRA_LIBS 32 #define PREF_PLUGINS_SONAME "plugin.soname.list" +#if defined (XP_SOLARIS) +#define DEFAULT_EXTRA_LIBS_LIST "libXt" LOCAL_PLUGIN_DLL_SUFFIX ":libXext" LOCAL_PLUGIN_DLL_SUFFIX ":libXm" LOCAL_PLUGIN_DLL_SUFFIX +#else #define DEFAULT_EXTRA_LIBS_LIST "libXt" LOCAL_PLUGIN_DLL_SUFFIX ":libXext" LOCAL_PLUGIN_DLL_SUFFIX +#endif /* this function looks for user_pref("plugin.soname.list", "/usr/X11R6/lib/libXt.so.6:libXext.so"); @@ -264,11 +270,15 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary) // at runtime. Explicitly opening Xt/Xext into the global // namespace before attempting to load the plug-in seems to // work fine. - - +#if defined(XP_SOLARIS) + // Acrobat/libXm: Lazy resolving might cause crash later (bug 211587) + *outLibrary = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW); + pLibrary = *outLibrary; +#else // Some dlopen() doesn't recover from a failed PR_LD_NOW (bug 223744) *outLibrary = PR_LoadLibraryWithFlags(libSpec, 0); pLibrary = *outLibrary; +#endif if (!pLibrary) { LoadExtraSharedLibs(); // try reload plugin once more diff --git a/editor/libeditor/tests/test_htmleditor_keyevent_handling.html b/editor/libeditor/tests/test_htmleditor_keyevent_handling.html index 414045ac0..bfec290a5 100644 --- a/editor/libeditor/tests/test_htmleditor_keyevent_handling.html +++ b/editor/libeditor/tests/test_htmleditor_keyevent_handling.html @@ -27,7 +27,7 @@ var htmlEditor = document.getElementById("htmlEditor"); const kIsMac = navigator.platform.indexOf("Mac") == 0; const kIsWin = navigator.platform.indexOf("Win") == 0; -const kIsLinux = navigator.platform.indexOf("Linux") == 0; +const kIsLinux = navigator.platform.indexOf("Linux") == 0 || navigator.platform.indexOf("SunOS") == 0 ; function runTests() { diff --git a/editor/reftests/xul/platform.js b/editor/reftests/xul/platform.js index a8633fb09..d3f5d33bf 100644 --- a/editor/reftests/xul/platform.js +++ b/editor/reftests/xul/platform.js @@ -13,6 +13,8 @@ if (/Windows/.test(ua)) { } else if (/Linux/.test(ua)) id = "linux"; +else if (/SunOS/.test(ua)) + id = "linux"; else if (/Mac OS X/.test(ua)) id = "mac"; diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 20678c68c..bc99e62b5 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -138,6 +138,17 @@ distclean:: CFLAGS += $(MOZ_ZLIB_CFLAGS) +ifeq ($(OS_ARCH),SunOS) +ifeq ($(TARGET_CPU),sparc) + +ifdef GNU_CC +CFLAGS += -mcpu=v9 +CXXFLAGS += -mcpu=v9 +endif #GNU_CC + +endif +endif + $(LIBRARY_NAME).pc: js.pc cp $^ $@ diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 992fe2c97..6beb82932 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -239,8 +239,11 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp) value = BooleanValue(true); if (!JS_SetProperty(cx, info, "intl-api", value)) return false; - +#if defined(XP_SOLARIS) + value = BooleanValue(false); +#else value = BooleanValue(true); +#endif if (!JS_SetProperty(cx, info, "mapped-array-buffer", value)) return false; diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index d6adfac2c..aed1114bd 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -20,6 +20,10 @@ #include <float.h> #endif +#if defined(XP_SOLARIS) +#include <ieeefp.h> +#endif + #ifdef HAVE_SSIZE_T #include <sys/types.h> #endif diff --git a/js/src/jsnativestack.cpp b/js/src/jsnativestack.cpp index 94a296bd0..389d7e657 100644 --- a/js/src/jsnativestack.cpp +++ b/js/src/jsnativestack.cpp @@ -67,6 +67,19 @@ js::GetNativeStackBaseImpl() # endif } +#elif defined(XP_SOLARIS) + +#include <ucontext.h> + +JS_STATIC_ASSERT(JS_STACK_GROWTH_DIRECTION < 0); + +void js::GetNativeStackBaseImpl() +{ + stack_t st; + stack_getbounds(&st); + return static_cast<char*>(st.ss_sp) + st.ss_size; +} + #elif defined(XP_LINUX) && !defined(ANDROID) && defined(__GLIBC__) void* js::GetNativeStackBaseImpl() diff --git a/js/src/moz.build b/js/src/moz.build index a0f074d1c..47ffe0159 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -721,6 +721,14 @@ if CONFIG['OS_ARCH'] == 'Linux': 'dl', ] +if CONFIG['OS_ARCH'] == 'SunOS': + OS_LIBS += [ + 'posix4', + 'dl', + 'nsl', + 'socket', + ] + OS_LIBS += CONFIG['REALTIME_LIBS'] CFLAGS += CONFIG['MOZ_ICU_CFLAGS'] diff --git a/js/src/vm/Time.cpp b/js/src/vm/Time.cpp index 87531c148..a9a5b7f0f 100644 --- a/js/src/vm/Time.cpp +++ b/js/src/vm/Time.cpp @@ -11,6 +11,10 @@ #include "mozilla/DebugOnly.h" #include "mozilla/MathAlgorithms.h" +#ifdef XP_SOLARIS +#define _REENTRANT 1 +#endif + #include <string.h> #include <time.h> @@ -30,6 +34,10 @@ #ifdef XP_UNIX +#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */ +extern int gettimeofday(struct timeval* tv); +#endif + #include <sys/time.h> #endif /* XP_UNIX */ @@ -42,7 +50,11 @@ PRMJ_Now() { struct timeval tv; +#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris <sys/types.h> */ + gettimeofday(&tv); +#else gettimeofday(&tv, 0); +#endif /* _SVID_GETTOD */ return int64_t(tv.tv_sec) * PRMJ_USEC_PER_SEC + int64_t(tv.tv_usec); } diff --git a/js/xpconnect/src/XPCShellImpl.cpp b/js/xpconnect/src/XPCShellImpl.cpp index 4ddc8deb3..abe50f449 100644 --- a/js/xpconnect/src/XPCShellImpl.cpp +++ b/js/xpconnect/src/XPCShellImpl.cpp @@ -644,6 +644,7 @@ env_setProperty(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue ObjectOpResult& result) { /* XXX porting may be easy, but these don't seem to supply setenv by default */ +#if !defined XP_SOLARIS RootedString valstr(cx); RootedString idstr(cx); int rv; @@ -686,6 +687,7 @@ env_setProperty(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue return false; } vp.setString(valstr); +#endif /* !defined XP_SOLARIS */ return result.succeed(); } diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 08400635b..a0f65c069 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -67,6 +67,9 @@ #define alloca _alloca #endif #endif +#ifdef XP_SOLARIS +#include <alloca.h> +#endif using std::max; using std::min; diff --git a/memory/mozjemalloc/jemalloc.c b/memory/mozjemalloc/jemalloc.c index 9a97bbb09..c54a85959 100644 --- a/memory/mozjemalloc/jemalloc.c +++ b/memory/mozjemalloc/jemalloc.c @@ -280,7 +280,9 @@ typedef long ssize_t; #define JEMALLOC_RECYCLE #ifndef MOZ_MEMORY_WINDOWS +#ifndef MOZ_MEMORY_SOLARIS #include <sys/cdefs.h> +#endif #ifndef __DECONST # define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) #endif @@ -306,7 +308,7 @@ __FBSDID("$FreeBSD: head/lib/libc/stdlib/malloc.c 180599 2008-07-18 19:35:44Z ja #endif #include <sys/time.h> #include <sys/types.h> -#if !defined(MOZ_MEMORY_ANDROID) +#if !defined(MOZ_MEMORY_SOLARIS) && !defined(MOZ_MEMORY_ANDROID) #include <sys/sysctl.h> #endif #include <sys/uio.h> @@ -408,6 +410,10 @@ void *_mmap(void *addr, size_t length, int prot, int flags, #endif #endif +#if defined(MOZ_MEMORY_SOLARIS && defined(MAP_ALIGN) && !defined(JEMALLOC_NEVER_USES_MAP_ALIGN) +#define JEMALLOC_USES_MAP_ALIGN /* Required on Solaris 10. Might improve performance elsewhere. */ +#endif + #ifndef __DECONST #define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) #endif @@ -5120,6 +5126,13 @@ malloc_ncpus(void) else return (n); } +#elif (defined(MOZ_MEMORY_SOLARIS)) + +static inline unsigned +malloc_ncpus(void) +{ + return sysconf(_SC_NPROCESSORS_ONLN); +} #elif (defined(MOZ_MEMORY_WINDOWS)) static inline unsigned malloc_ncpus(void) @@ -5916,9 +5929,15 @@ RETURN: #define MOZ_MEMORY_ELF #endif +#ifdef MOZ_MEMORY_SOLARIS +# if (defined(__GNUC__)) +__attribute__((noinline)) +# endif +#else #if (defined(MOZ_MEMORY_ELF)) __attribute__((visibility ("hidden"))) #endif +#endif #endif /* MOZ_REPLACE_MALLOC */ #ifdef MOZ_MEMORY_ELF diff --git a/toolkit/components/osfile/modules/osfile_unix_back.jsm b/toolkit/components/osfile/modules/osfile_unix_back.jsm index bf5c66b8d..7c2c6f28d 100644 --- a/toolkit/components/osfile/modules/osfile_unix_back.jsm +++ b/toolkit/components/osfile/modules/osfile_unix_back.jsm @@ -585,10 +585,18 @@ } else if (Const._STAT_VER != undefined) { const ver = Const._STAT_VER; let xstat_name, lxstat_name, fxstat_name; - // Linux, all widths - xstat_name = "__xstat"; - lxstat_name = "__lxstat"; - fxstat_name = "__fxstat"; + if (OS.Constants.Sys.Name == "SunOS") { + // Solaris + xstat_name = "_xstat"; + lxstat_name = "_lxstat"; + fxstat_name = "_fxstat"; + } else { + + // Linux, all widths + xstat_name = "__xstat"; + lxstat_name = "__lxstat"; + fxstat_name = "__fxstat"; + } let Stat = {}; libc.declareLazyFFI(Stat, "xstat", diff --git a/toolkit/library/moz.build b/toolkit/library/moz.build index ba7fb5032..cd900a615 100644 --- a/toolkit/library/moz.build +++ b/toolkit/library/moz.build @@ -270,6 +270,12 @@ if CONFIG['MOZ_ENABLE_STARTUP_NOTIFICATION']: if CONFIG['MOZ_ENABLE_LIBPROXY']: OS_LIBS += CONFIG['MOZ_LIBPROXY_LIBS'] +if CONFIG['OS_ARCH'] == 'SunOS': + OS_LIBS += [ + 'elf', + 'demangle', + ] + if CONFIG['OS_ARCH'] == 'FreeBSD': OS_LIBS += [ 'util', diff --git a/toolkit/mozapps/update/common/updatedefines.h b/toolkit/mozapps/update/common/updatedefines.h index 5790cf996..871755246 100644 --- a/toolkit/mozapps/update/common/updatedefines.h +++ b/toolkit/mozapps/update/common/updatedefines.h @@ -96,7 +96,11 @@ static inline int mywcsprintf(WCHAR* dest, size_t count, const WCHAR* fmt, ...) # include <sys/wait.h> # include <unistd.h> +#ifdef XP_SOLARIS +# include <sys/stat.h> +#else # include <fts.h> +#endif # include <dirent.h> #ifdef XP_MACOSX diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp index 8025deaaf..f5f71935d 100644 --- a/toolkit/mozapps/update/updater/updater.cpp +++ b/toolkit/mozapps/update/updater/updater.cpp @@ -3648,6 +3648,88 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list) return rv; } +#elif defined(XP_SOLARIS) +int add_dir_entries(const NS_tchar *dirpath, ActionList *list) +{ + int rv = OK; + NS_tchar foundpath[MAXPATHLEN]; + struct { + dirent dent_buffer; + char chars[MAXNAMLEN]; + } ent_buf; + struct dirent* ent; + mozilla::UniquePtr<NS_tchar[]> searchpath(get_full_path(dirpath)); + + DIR* dir = opendir(searchpath.get()); + if (!dir) { + LOG(("add_dir_entries error on opendir: " LOG_S ", err: %d", searchpath.get(), + errno)); + return UNEXPECTED_FILE_OPERATION_ERROR; + } + + while (readdir_r(dir, (dirent *)&ent_buf, &ent) == 0 && ent) { + if ((strcmp(ent->d_name, ".") == 0) || + (strcmp(ent->d_name, "..") == 0)) + continue; + + NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]), + NS_T("%s%s"), searchpath.get(), ent->d_name); + struct stat64 st_buf; + int test = stat64(foundpath, &st_buf); + if (test) { + closedir(dir); + return UNEXPECTED_FILE_OPERATION_ERROR; + } + if (S_ISDIR(st_buf.st_mode)) { + NS_tsnprintf(foundpath, sizeof(foundpath)/sizeof(foundpath[0]), + NS_T("%s/"), foundpath); + // Recurse into the directory. + rv = add_dir_entries(foundpath, list); + if (rv) { + LOG(("add_dir_entries error: " LOG_S ", err: %d", foundpath, rv)); + closedir(dir); + return rv; + } + } else { + // Add the file to be removed to the ActionList. + NS_tchar *quotedpath = get_quoted_path(get_relative_path(foundpath)); + if (!quotedpath) { + closedir(dir); + return PARSE_ERROR; + } + + Action *action = new RemoveFile(); + rv = action->Parse(quotedpath); + if (rv) { + LOG(("add_dir_entries Parse error on recurse: " LOG_S ", err: %d", + quotedpath, rv)); + closedir(dir); + return rv; + } + + list->Append(action); + } + } + closedir(dir); + + // Add the directory to be removed to the ActionList. + NS_tchar *quotedpath = get_quoted_path(get_relative_path(dirpath)); + if (!quotedpath) + return PARSE_ERROR; + + Action *action = new RemoveDir(); + rv = action->Parse(quotedpath); + if (rv) { + LOG(("add_dir_entries Parse error on close: " LOG_S ", err: %d", + quotedpath, rv)); + } + else { + list->Append(action); + } + + return rv; +} + #else int add_dir_entries(const NS_tchar *dirpath, ActionList *list) diff --git a/toolkit/xre/nsSigHandlers.cpp b/toolkit/xre/nsSigHandlers.cpp index 454882c1b..bcbcb6e3d 100644 --- a/toolkit/xre/nsSigHandlers.cpp +++ b/toolkit/xre/nsSigHandlers.cpp @@ -32,6 +32,11 @@ #endif #endif +#if defined(XP_SOLARIS) +#include <sys/resource.h> +#include <ucontext.h> +#endif + static const char* gProgname = "huh?"; // Note: some tests manipulate this value. @@ -193,6 +198,33 @@ static void fpehandler(int signum, siginfo_t *si, void *context) *mxcsr &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */ #endif #endif +#ifdef XP_SOLARIS + ucontext_t *uc = (ucontext_t *)context; + +#if defined(__i386) + uint32_t *cw = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[0]; + *cw |= FPU_EXCEPTION_MASK; + + uint32_t *sw = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[1]; + *sw &= ~FPU_STATUS_FLAGS; + + /* address of the instruction that caused the exception */ + uint32_t *ip = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[3]; + uc->uc_mcontext.gregs[REG_PC] = *ip; +#endif +#if defined(__amd64__) + uint16_t *cw = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state.cw; + *cw |= FPU_EXCEPTION_MASK; + + uint16_t *sw = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw; + *sw &= ~FPU_STATUS_FLAGS; + + uint32_t *mxcsr = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr; + *mxcsr |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */ + *mxcsr &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */ +#endif +#endif +} } #endif @@ -255,6 +287,31 @@ void InstallSignalHandlers(const char *aProgname) } #endif +#if defined(XP_SOLARIS) +#define NOFILES 512 + + // Boost Solaris file descriptors + { + struct rlimit rl; + + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) + + if (rl.rlim_cur < NOFILES) { + rl.rlim_cur = NOFILES; + + if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { + perror("setrlimit(RLIMIT_NOFILE)"); + fprintf(stderr, "Cannot exceed hard limit for open files"); + } +#if defined(DEBUG) + if (getrlimit(RLIMIT_NOFILE, &rl) == 0) + printf("File descriptors set to %d\n", rl.rlim_cur); +#endif //DEBUG + } + } +#endif //XP_SOLARIS + + #if defined(MOZ_WIDGET_GTK) && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6)) const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK"); if (assertString && diff --git a/xpcom/base/nsDebugImpl.cpp b/xpcom/base/nsDebugImpl.cpp index a81eb3d71..84ba150db 100644 --- a/xpcom/base/nsDebugImpl.cpp +++ b/xpcom/base/nsDebugImpl.cpp @@ -450,6 +450,12 @@ RealBreak() ".object_arch armv4t\n" #endif "BKPT #0"); +#elif defined(__sun) +#if defined (__i386__) || defined(__i386) || defined(__x86_64__) + asm("int $3"); +#else + raise(SIGTRAP); +#endif #else #warning do not know how to break on this platform #endif @@ -524,6 +530,8 @@ Break(const char* aMsg) RealBreak(); #elif defined(__arm__) RealBreak(); +#elif defined(__sun) + RealBreak(); #else #warning do not know how to break on this platform #endif diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 88964f9b5..9c2d620cc 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -317,6 +317,85 @@ VsizeMaxContiguousDistinguishedAmount(int64_t* aN) } #endif // FreeBSD +#elif defined(XP_SOLARIS) + +#include <procfs.h> +#include <fcntl.h> +#include <unistd.h> + +static void +XMappingIter(int64_t& aVsize, int64_t& aResident) +{ + aVsize = -1; + aResident = -1; + int mapfd = open("/proc/self/xmap", O_RDONLY); + struct stat st; + prxmap_t* prmapp = nullptr; + if (mapfd >= 0) { + if (!fstat(mapfd, &st)) { + int nmap = st.st_size / sizeof(prxmap_t); + while (1) { + // stat(2) on /proc/<pid>/xmap returns an incorrect value, + // prior to the release of Solaris 11. + // Here is a workaround for it. + nmap *= 2; + prmapp = (prxmap_t*)malloc((nmap + 1) * sizeof(prxmap_t)); + if (!prmapp) { + // out of memory + break; + } + int n = pread(mapfd, prmapp, (nmap + 1) * sizeof(prxmap_t), 0); + if (n < 0) { + break; + } + if (nmap >= n / sizeof(prxmap_t)) { + aVsize = 0; + aResident = 0; + for (int i = 0; i < n / sizeof(prxmap_t); i++) { + aVsize += prmapp[i].pr_size; + aResident += prmapp[i].pr_rss * prmapp[i].pr_pagesize; + } + break; + } + free(prmapp); + } + free(prmapp); + } + close(mapfd); + } +} + +#define HAVE_VSIZE_AND_RESIDENT_REPORTERS 1 +static MOZ_MUST_USE nsresult +VsizeDistinguishedAmount(int64_t* aN) +{ + int64_t vsize, resident; + XMappingIter(vsize, resident); + if (vsize == -1) { + return NS_ERROR_FAILURE; + } + *aN = vsize; + return NS_OK; +} + +static MOZ_MUST_USE nsresult +ResidentDistinguishedAmount(int64_t* aN) +{ + int64_t vsize, resident; + XMappingIter(vsize, resident); + if (resident == -1) { + return NS_ERROR_FAILURE; + } + *aN = resident; + return NS_OK; +} + +static MOZ_MUST_USE nsresult +ResidentFastDistinguishedAmount(int64_t* aN) +{ + return ResidentDistinguishedAmount(aN); +} + #elif defined(XP_MACOSX) #include <mach/mach_init.h> @@ -1066,9 +1145,13 @@ ResidentPeakDistinguishedAmount(int64_t* aN) if (0 == getrusage(RUSAGE_SELF, &usage)) { // The units for ru_maxrrs: // - Mac: bytes + // - Solaris: pages? But some sources it actually always returns 0, so + // check for that // - Linux, {Net/Open/Free}BSD, DragonFly: KiB #ifdef XP_MACOSX *aN = usage.ru_maxrss; +#elif defined(XP_SOLARIS) + *aN = usage.ru.maxrss * getpagesize(); #else *aN = usage.ru_maxrss * 1024; #endif diff --git a/xpcom/ds/nsMathUtils.h b/xpcom/ds/nsMathUtils.h index cbbd38611..08bf908da 100644 --- a/xpcom/ds/nsMathUtils.h +++ b/xpcom/ds/nsMathUtils.h @@ -11,6 +11,10 @@ #include <cmath> #include <float.h> +#ifdef XP_SOLARIS +#include <ieeefp.h> +#endif + /* * round */ diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp index 272153bba..c0b5c0f48 100644 --- a/xpcom/io/nsLocalFileUnix.cpp +++ b/xpcom/io/nsLocalFileUnix.cpp @@ -1591,6 +1591,23 @@ nsLocalFile::IsExecutable(bool* aResult) // Then check the execute bit. *aResult = (access(mPath.get(), X_OK) == 0); +#ifdef XP_SOLARIS + // On Solaris, access will always return 0 for root user, however + // the file is only executable if S_IXUSR | S_IXGRP | S_IXOTH is set. + // See bug 351950, https://bugzilla.mozilla.org/show_bug.cgi?id=351950 + if (*aResult) { + struct STAT buf; + + *aResult = (STAT(mPath.get(), &buf) == 0); + if (*aResult || errno == EACCES) { + *aResult = *aResult && (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)); + return NS_OK; + } + + return NSRESULT_FOR_ERRNO(); + } +#endif + if (*aResult || errno == EACCES) { if (*aResult || errno == EACCES) { return NS_OK; } diff --git a/xpcom/reflect/xptcall/md/unix/moz.build b/xpcom/reflect/xptcall/md/unix/moz.build index d455ed854..c5cba0c8d 100644 --- a/xpcom/reflect/xptcall/md/unix/moz.build +++ b/xpcom/reflect/xptcall/md/unix/moz.build @@ -46,6 +46,21 @@ if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD'): 'xptcstubs_ipf64.cpp' ] +# Without the need to accomodate the Sun compiler, Solaris/GCC support is pretty +# standard, actually. Not all that different from Linux. + +if CONFIG['OS_ARCH'] == 'SunOS': + if CONFIG['OS_TEST'] == 'x86_64': + SOURCES += [ + 'xptcinvoke_asm_x86_64_unix.S', + 'xptcinvoke_x86_64_unix.cpp', + 'xptcstubs_x86_64_linux.cpp' + ] + elif CONFIG['OS_TEST'] == 'x86': + SOURCES += [ + 'xptcinvoke_gcc_x86_unix.cpp', + 'xptcstubs_gcc_x86_unix.cpp' + ] if CONFIG['OS_TEST'] == 'alpha': if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD', 'NetBSD'): @@ -186,7 +201,11 @@ if CONFIG['OS_ARCH'] == 'OpenBSD' and CONFIG['OS_TEST'] == 'sparc': 'xptcstubs_sparc_openbsd.cpp', ] -if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD') and CONFIG['OS_TEST'] == 'sparc64': +# Mozilla discovered at some point that Solaris and Linux can also use these +# files for 64-bit SPARC with no ill effects, so basically the entire mess that +# was there before is no longer needed. + +if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD', 'SunOS') and CONFIG['OS_TEST'] == 'sparc64': SOURCES += [ 'xptcinvoke_asm_sparc64_openbsd.s', 'xptcinvoke_sparc64_openbsd.cpp', @@ -194,6 +213,17 @@ if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD') and CONFIG['OS_TEST'] == 'sparc64 'xptcstubs_sparc64_openbsd.cpp', ] +# As for the 32-bit SPARC build? That would look like the Linux version with +# one file changed. + +if CONFIG['OS_ARCH'] == 'SunOS' and CONFIG['OS_TEST'] == 'sparc': + SOURCES += [ + 'xptcinvoke_asm_sparc_solaris_GCC3.s', + 'xptcinvoke_sparc_solaris.cpp', + 'xptcstubs_asm_sparc_solaris.s', + 'xptcstubs_sparc_solaris.cpp', + ] + if CONFIG['OS_ARCH'] == 'Linux': if CONFIG['OS_TEST'] == 's390': SOURCES += [ diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s new file mode 100644 index 000000000..54adcd147 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc_solaris_GCC3.s @@ -0,0 +1,52 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Platform specific code to invoke XPCOM methods on native objects for + * solaris/sparc with gcc 3 ABI. + */ + .global NS_InvokeByIndex +/* + * NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, + * uint32_t paramCount, nsXPTCVariant* params); + */ +NS_InvokeByIndex: + save %sp,-(64 + 32),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 32 + mov %i2,%o0 ! paramCount + call invoke_count_words ! returns the required stack size in %o0 + mov %i3,%o1 ! params + + sll %o0,2,%l0 ! number of bytes + sub %sp,%l0,%sp ! create the additional stack space + + mov %sp,%o0 ! pointer for copied args + add %o0,72,%o0 ! step past the register window, the + ! struct result pointer and the 'this' slot + mov %i2,%o1 ! paramCount + call invoke_copy_to_stack + mov %i3,%o2 ! params +! +! calculate the target address from the vtable +! + ld [%i0],%l1 ! *that --> vTable + sll %i1,2,%i1 ! multiply index by 4 + add %i1,%l1,%l1 ! l1 now points to vTable entry + ld [%l1],%l0 ! target address + +.L5: ld [%sp + 88],%o5 +.L4: ld [%sp + 84],%o4 +.L3: ld [%sp + 80],%o3 +.L2: ld [%sp + 76],%o2 +.L1: ld [%sp + 72],%o1 +.L0: + jmpl %l0,%o7 ! call the routine +! always have a 'this', from the incoming 'that' + mov %i0,%o0 + + mov %o0,%i0 ! propagate return value + ret + restore diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S new file mode 100644 index 000000000..131cfc334 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_x86_64_unix.S @@ -0,0 +1,122 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Darwin gives a leading '_' to symbols defined in C code. +#ifdef XP_DARWIN +#define SYM(x) _ ## x +#define CFI_STARTPROC +#define CFI_ENDPROC +#define CFI_DEF_CFA_OFFSET(offset) +#define CFI_OFFSET(reg, offset) +#define CFI_DEF_CFA_REGISTER(reg) +#define CFI_DEF_CFA(reg, offset) +#else +#define SYM(x) x +#define CFI_STARTPROC .cfi_startproc +#define CFI_ENDPROC .cfi_endproc +#define CFI_DEF_CFA_OFFSET(offset) .cfi_def_cfa_offset offset +#define CFI_OFFSET(reg, offset) .cfi_offset reg, offset +#define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg +#define CFI_DEF_CFA(reg, offset) .cfi_def_cfa reg, offset +#endif + +.intel_syntax noprefix + +# nsresult NS_InvokeByIndex(nsISupports* this, uint32_t aVtableIndex, +# uint32_t argc, nsXPTCVariant* argv); +.text +.global SYM(NS_InvokeByIndex) +#ifndef XP_DARWIN +.type NS_InvokeByIndex, @function +#endif +.align 4 +SYM(NS_InvokeByIndex): + CFI_STARTPROC + push rbp + CFI_DEF_CFA_OFFSET(16) + CFI_OFFSET(6, -16) + mov rbp, rsp + CFI_DEF_CFA_REGISTER(6) + +# save r12 and r13 because we use them and they are callee saved. + push r12 + push r13 + CFI_OFFSET(12, -24) + CFI_OFFSET(13, -32) + +# save this and the vtable index because we need them after setting up the +# stack. + mov r12, rdi + mov r13, rsi + +# allocate space for stack arguments, in theory we only need 8 * (argc - 5) +# bytes because at least 5 arguments will go in registers, but for now it is +# just simpler to allocate 8 * argc bytes. Note that we treat the this +# pointer specially. + lea eax, [edx * 8] + sub rsp, rax + +# If there is an odd number of args the stack can be misaligned so realign it. + and rsp, 0xfffffffffffffff0 + +# pass the stack slot area to InvokeCopyToStack. + mov r8, rsp + +# setup space for the register slots: there are 5 integer ones and 8 floating +# point ones. So we need 104 bytes of space, but we allocate 112 to keep rsp +# aligned to 16 bytes. + sub rsp, 112 + +# the first argument to InvokeCopyToStack is the integer register area, and the +# second is the floating point area. + mov rdi, rsp + lea rsi, [rsp + 40] + +# The 3rd and 4th arguments to InvokeCopyToStack are already in the right +# registers. So now we can just call InvokeCopyToStack. + call SYM(InvokeCopyToStack) + +# setup this + mov rdi, r12 + +# copy the integer arguments into place. + mov rsi, [rsp] + mov rdx, [rsp + 8] + mov rcx, [rsp + 16] + mov r8, [rsp + 24] + mov r9, [rsp + 32] + +# copy the float arguments into place + movsd xmm0, [rsp + 40] + movsd xmm1, [rsp + 48] + movsd xmm2, [rsp + 56] + movsd xmm3, [rsp + 64] + movsd xmm4, [rsp + 72] + movsd xmm5, [rsp + 80] + movsd xmm6, [rsp + 88] + movsd xmm7, [rsp + 96] + +# get rid of the scratch space for registers + add rsp, 112 + +# load the function pointer and call + lea eax, [r13d * 8] + add rax, [rdi] + call [rax] + +# r12 and r13 were pushed relative to the old stack pointer which is now the +# frame pointer. + mov r12, [rbp - 0x8] + mov r13, [rbp - 0x10] + + mov rsp, rbp + pop rbp + CFI_DEF_CFA(7, 8) + ret + CFI_ENDPROC + +#ifndef XP_DARWIN +// Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits ; .previous +#endif diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp index 050f9414d..1b5039ed9 100644 --- a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_openbsd.cpp @@ -30,9 +30,9 @@ invoke_copy_to_stack(uint64_t* d, uint32_t paramCount, nsXPTCVariant* s) { if (regCount < 5) regCount++; - if (l_s->IsPtrData()) + if (l_s->IsIndirect()) { - *l_d = (uint64_t)l_s->ptr; + *l_d = (uint64_t) &l_s->val; continue; } switch (l_s->type) diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp new file mode 100644 index 000000000..126ef1dad --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc_solaris.cpp @@ -0,0 +1,131 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Platform specific code to invoke XPCOM methods on native objects */ + +#include "xptcprivate.h" + +/* solaris defines __sparc for workshop compilers and + linux defines __sparc__ */ + +#if !defined(__sparc) && !defined(__sparc__) +#error "This code is for Sparc only" +#endif + +typedef unsigned nsXPCVariant; + +extern "C" uint32_t +invoke_count_words(uint32_t paramCount, nsXPTCVariant* s) +{ + uint32_t result = 0; + for(uint32_t i = 0; i < paramCount; i++, s++) + { + if(s->IsPtrData()) + { + result++; + continue; + } + switch(s->type) + { + case nsXPTType::T_I8 : + case nsXPTType::T_I16 : + case nsXPTType::T_I32 : + result++; + break; + case nsXPTType::T_I64 : + result+=2; + break; + case nsXPTType::T_U8 : + case nsXPTType::T_U16 : + case nsXPTType::T_U32 : + result++; + break; + case nsXPTType::T_U64 : + result+=2; + break; + case nsXPTType::T_FLOAT : + result++; + break; + case nsXPTType::T_DOUBLE : + result+=2; + break; + case nsXPTType::T_BOOL : + case nsXPTType::T_CHAR : + case nsXPTType::T_WCHAR : + result++; + break; + default: + // all the others are plain pointer types + result++; + break; + } + } + // nuts, I know there's a cooler way of doing this, but it's late + // now and it'll probably come to me in the morning. + if (result & 0x3) result += 4 - (result & 0x3); // ensure q-word alignment + return result; +} + +extern "C" uint32_t +invoke_copy_to_stack(uint32_t* d, uint32_t paramCount, nsXPTCVariant* s) +{ +/* + We need to copy the parameters for this function to locals and use them + from there since the parameters occupy the same stack space as the stack + we're trying to populate. +*/ + uint32_t *l_d = d; + nsXPTCVariant *l_s = s; + uint32_t l_paramCount = paramCount; + uint32_t regCount = 0; // return the number of registers to load from the stack + + typedef struct { + uint32_t hi; + uint32_t lo; + } DU; // have to move 64 bit entities as 32 bit halves since + // stack slots are not guaranteed 16 byte aligned + + for(uint32_t i = 0; i < l_paramCount; i++, l_d++, l_s++) + { + if (regCount < 5) regCount++; + if(l_s->IsPtrData()) + { + if(l_s->type == nsXPTType::T_JSVAL) + { + // On SPARC, we need to pass a pointer to HandleValue + *((void**)l_d) = &l_s->ptr; + } else + { + *((void**)l_d) = l_s->ptr; + } + continue; + } + switch(l_s->type) + { + case nsXPTType::T_I8 : *((int32_t*) l_d) = l_s->val.i8; break; + case nsXPTType::T_I16 : *((int32_t*) l_d) = l_s->val.i16; break; + case nsXPTType::T_I32 : *((int32_t*) l_d) = l_s->val.i32; break; + case nsXPTType::T_I64 : + case nsXPTType::T_U64 : + case nsXPTType::T_DOUBLE : *((uint32_t*) l_d++) = ((DU *)l_s)->hi; + if (regCount < 5) regCount++; + *((uint32_t*) l_d) = ((DU *)l_s)->lo; + break; + case nsXPTType::T_U8 : *((uint32_t*) l_d) = l_s->val.u8; break; + case nsXPTType::T_U16 : *((uint32_t*) l_d) = l_s->val.u16; break; + case nsXPTType::T_U32 : *((uint32_t*) l_d) = l_s->val.u32; break; + case nsXPTType::T_FLOAT : *((float*) l_d) = l_s->val.f; break; + case nsXPTType::T_BOOL : *((uint32_t*) l_d) = l_s->val.b; break; + case nsXPTType::T_CHAR : *((uint32_t*) l_d) = l_s->val.c; break; + case nsXPTType::T_WCHAR : *((int32_t*) l_d) = l_s->val.wc; break; + default: + // all the others are plain pointer types + *((void**)l_d) = l_s->val.p; + break; + } + } + return regCount; +} + diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s b/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s new file mode 100644 index 000000000..9b448d7c7 --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc_solaris.s @@ -0,0 +1,49 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + .global SharedStub + +/* + in the frame for the function that called SharedStub are the + rest of the parameters we need + +*/ + +SharedStub: +! we don't create a new frame yet, but work within the frame of the calling +! function to give ourselves the other parameters we want + + mov %o0, %o1 ! shuffle the index up to 2nd place + mov %i0, %o0 ! the original 'this' + add %fp, 72, %o2 ! previous stack top adjusted to the first argument slot (beyond 'this') +! save off the original incoming parameters that arrived in +! registers, the ABI guarantees the space for us to do this + st %i1, [%fp + 72] + st %i2, [%fp + 76] + st %i3, [%fp + 80] + st %i4, [%fp + 84] + st %i5, [%fp + 88] +! now we can build our own stack frame + save %sp,-(64 + 32),%sp ! room for the register window and + ! struct pointer, rounded up to 0 % 32 +! our function now appears to have been called +! as SharedStub(nsISupports* that, uint32_t index, uint32_t* args) +! so we can just copy these through + + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + call PrepareAndDispatch + nop + mov %o0,%i0 ! propagate return value + b .LL1 + nop +.LL1: + ret + restore + + .size SharedStub, .-SharedStub + .type SharedStub, #function diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp index b8a09c97e..e28a03794 100644 --- a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp +++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_openbsd.cpp @@ -85,8 +85,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args) extern "C" nsresult SharedStub(int, int*); +/* + * Avoid GCC stack protector to wipe out imput registers since the compiler + * thinks the function takes no arguments. + */ + #define STUB_ENTRY(n) \ -nsresult nsXPTCStubBase::Stub##n() \ +nsresult __attribute__((__optimize__("no-stack-protector"))) nsXPTCStubBase::Stub##n() \ { \ int dummy; /* defeat tail-call optimization */ \ return SharedStub(n, &dummy); \ diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp new file mode 100644 index 000000000..61f3df4ff --- /dev/null +++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc_solaris.cpp @@ -0,0 +1,112 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Implement shared vtbl methods. */ + +#include "xptcprivate.h" +#include "xptiprivate.h" + +#if defined(sparc) || defined(__sparc__) + +extern "C" nsresult ATTRIBUTE_USED +PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args) +{ + + typedef struct { + uint32_t hi; + uint32_t lo; + } DU; // have to move 64 bit entities as 32 bit halves since + // stack slots are not guaranteed 16 byte aligned + +#define PARAM_BUFFER_COUNT 16 + + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; + nsXPTCMiniVariant* dispatchParams = nullptr; + const nsXPTMethodInfo* info; + uint8_t paramCount; + uint8_t i; + nsresult result = NS_ERROR_FAILURE; + + NS_ASSERTION(self,"no self"); + + self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info); + NS_ASSERTION(info,"no interface info"); + + paramCount = info->GetParamCount(); + + // setup variant array pointer + if(paramCount > PARAM_BUFFER_COUNT) + dispatchParams = new nsXPTCMiniVariant[paramCount]; + else + dispatchParams = paramBuffer; + NS_ASSERTION(dispatchParams,"no place for params"); + + uint32_t* ap = args; + for(i = 0; i < paramCount; i++, ap++) + { + const nsXPTParamInfo& param = info->GetParam(i); + const nsXPTType& type = param.GetType(); + nsXPTCMiniVariant* dp = &dispatchParams[i]; + + if(param.IsOut() || !type.IsArithmetic()) + { + if (type == nsXPTType::T_JSVAL) + dp->val.p = *((void**) *ap); + else + dp->val.p = (void*) *ap; + continue; + } + // else + switch(type) + { + case nsXPTType::T_I8 : dp->val.i8 = *((int32_t*) ap); break; + case nsXPTType::T_I16 : dp->val.i16 = *((int32_t*) ap); break; + case nsXPTType::T_I32 : dp->val.i32 = *((int32_t*) ap); break; + case nsXPTType::T_DOUBLE : + case nsXPTType::T_U64 : + case nsXPTType::T_I64 : ((DU *)dp)->hi = ((DU *)ap)->hi; + ((DU *)dp)->lo = ((DU *)ap)->lo; + ap++; + break; + case nsXPTType::T_U8 : dp->val.u8 = *((uint32_t*)ap); break; + case nsXPTType::T_U16 : dp->val.u16 = *((uint32_t*)ap); break; + case nsXPTType::T_U32 : dp->val.u32 = *((uint32_t*)ap); break; + case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break; + case nsXPTType::T_BOOL : dp->val.b = *((uint32_t*)ap); break; + case nsXPTType::T_CHAR : dp->val.c = *((uint32_t*)ap); break; + case nsXPTType::T_WCHAR : dp->val.wc = *((int32_t*) ap); break; + default: + NS_ERROR("bad type"); + break; + } + } + + result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams); + + if(dispatchParams != paramBuffer) + delete [] dispatchParams; + + return result; +} + +extern "C" nsresult SharedStub(int, int*); + +#define STUB_ENTRY(n) \ +nsresult nsXPTCStubBase::Stub##n() \ +{ \ + int dummy; /* defeat tail-call optimization */ \ + return SharedStub(n, &dummy); \ +} + +#define SENTINEL_ENTRY(n) \ +nsresult nsXPTCStubBase::Sentinel##n() \ +{ \ + NS_ERROR("nsXPTCStubBase::Sentinel called"); \ + return NS_ERROR_NOT_IMPLEMENTED; \ +} + +#include "xptcstubsdef.inc" + +#endif /* sparc || __sparc__ */ diff --git a/xpcom/reflect/xptcall/status.html b/xpcom/reflect/xptcall/status.html index deb4da92e..996159c82 100644 --- a/xpcom/reflect/xptcall/status.html +++ b/xpcom/reflect/xptcall/status.html @@ -241,6 +241,20 @@ a port. <TR> <TD bgcolor="green"><font color="white"><b>Done</b></font></TD> +<TD>SunOS x86</TD> +<TD> +<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> +<a href="mailto:aljones@lbl.gov">Arthur Jones <aljones@lbl.gov></a><BR> +<font color="red"><b>?</b></font> +<a href="mailto:ppokorny@mindspring.com">Philip Pokorny <ppokorny@mindspring.com></a><BR> +</TD> +<TD> +The word I hear is that this is working and done +</TD> +</TR> + +<TR> +<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> <TD>Irix</TD> <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> <a href="mailto:jasonh@m7.engr.sgi.com">Jason Heirtzler <jasonh@m7.engr.sgi.com></a><BR> |