[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#824449: firefox: FTBFS on sparc64 due to wrong platform definitions



Hi!

Some more updates:

Jose Marchesi from Oracle has provided me with two old patches that
were used to address the problem with Firefox 17.

Those patches are:

- xulrunner-linux-sparc64-xpcom.patch
- xulrunner-linux-sparc64.patch

Those patches didn't apply anymore right away. I had to update some
paths (src was omitted in some cases), plus the two following
changes:

1. I adjusted the padding in JSTryNote so it would be 64-bit aligned
   again as Firefox 46 changed stackDepth from uint16_t to uint32_t.

2. The patch to memory/jemalloc/src/include/jemalloc/internal
   /jemalloc_internal.h.in can't be applied anymore at all, even
   with editing. The code section is gone.

With these changes included, the new patch (sparc64-fixes.patch)
applies without problems but compiling Firefox will still crash
xpcshell:

(sid)root@deb4g:/build/firefox-ORgwZM/firefox-46.0.1# export
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/build/firefox-ORgwZM/firefox-46.0.1/build-browser/dist/bin/
(sid)root@deb4g:/build/firefox-ORgwZM/firefox-46.0.1#
./build-browser/dist/bin/xpcshell

(process:240502): Gtk-WARNING **: Locale not supported by C library.
	Using the fallback 'C' locale.
Segmentation fault
(sid)root@deb4g:/build/firefox-ORgwZM/firefox-46.0.1#

The backtrace looks like this:

(gdb) bt
#0  0xfff8000102a117c4 in js::gc::Cell::storeBuffer (this=<optimized
out>) at /build/firefox-F4xXKx/firefox-46.0.1/js/src/gc/Heap.h:1339
#1  js::HeapSlot::post (target=..., slot=0, kind=js::HeapSlot::Slot,
owner=0xfff8000112523070, this=0xfff8000112523090)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/gc/Barrier.h:692
#2  js::HeapSlot::set (this=0xfff8000112523090,
owner=owner@entry=0xfff8000112523070, slot=slot@entry=0, v=...,
kind=js::HeapSlot::Slot)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/gc/Barrier.h:679
#3  0xfff8000102a13634 in js::NativeObject::setSlot
(this=0xfff8000112523070, value=..., slot=0)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/vm/NativeObject.h:824
#4  0xfff8000102a13758 in js::NativeObject::setReservedSlot (v=...,
index=0, this=<optimized out>)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/vm/NativeObject.h:890
#5  js::ClonedBlockObject::create (cx=cx@entry=0xfff800010a73a400,
block=..., enclosing=...)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/vm/ScopeObject.cpp:945
#6  0xfff8000102a18f1c in js::ClonedBlockObject::createGlobal
(cx=cx@entry=0xfff800010a73a400, global=...)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/vm/ScopeObject.cpp:976
#7  0xfff80001029b43fc in js::GlobalObject::createInternal
(cx=cx@entry=0xfff800010a73a400,
    clasp=0xfff8000103e07028
<JSRuntime::createSelfHostingGlobal(JSContext*)::shgClass>) at
/build/firefox-F4xXKx/firefox-46.0.1/js/src/vm/GlobalObject.cpp:278
#8  0xfff8000102a062bc in JSRuntime::createSelfHostingGlobal
(cx=cx@entry=0xfff800010a73a400)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/vm/SelfHosting.cpp:1956
#9  0xfff8000102a08988 in JSRuntime::initSelfHosting
(this=this@entry=0xfff800010c3d2000, cx=cx@entry=0xfff800010a73a400)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/vm/SelfHosting.cpp:1988
#10 0xfff8000102876f74 in js::NewContext (rt=0xfff800010c3d2000,
rt@entry=0x0, stackChunkSize=stackChunkSize@entry=8192)
    at /build/firefox-F4xXKx/firefox-46.0.1/js/src/jscntxt.cpp:121
#11 0xfff8000102876fbc in JS_NewContext (rt=0x0,
stackChunkSize=stackChunkSize@entry=8192) at
/build/firefox-F4xXKx/firefox-46.0.1/js/src/jsapi.cpp:573
#12 0xfff8000101058308 in XPCJSContextStack::InitSafeJSContext
(this=0xfff800010b248240)
    at
/build/firefox-F4xXKx/firefox-46.0.1/js/xpconnect/src/XPCJSContextStack.cpp:122
#13 0xfff80001010738ac in nsXPConnect::InitStatics () at
/build/firefox-F4xXKx/firefox-46.0.1/js/xpconnect/src/nsXPConnect.cpp:126
#14 0xfff800010105ccd4 in xpcModuleCtor () at
/build/firefox-F4xXKx/firefox-46.0.1/js/xpconnect/src/XPCModule.cpp:13
#15 0xfff800010229b818 in Initialize () at
/build/firefox-F4xXKx/firefox-46.0.1/layout/build/nsLayoutModule.cpp:436
#16 0xfff8000100bf9070 in nsComponentManagerImpl::KnownModule::Load
(this=0xfff800010b22f280)
    at
/build/firefox-F4xXKx/firefox-46.0.1/xpcom/components/nsComponentManager.cpp:898
#17 0xfff8000100bfa018 in nsFactoryEntry::GetFactory
(this=0xfff800010b23a180)
    at
/build/firefox-F4xXKx/firefox-46.0.1/xpcom/components/nsComponentManager.cpp:1934
#18 0xfff8000100bfa8d4 in
nsComponentManagerImpl::CreateInstanceByContractID
(this=0xfff800010a7f60c0,
    aContractID=0xfff8000102bb8b98 "@mozilla.org/moz/jsloader;1",
aDelegate=0x0, aIID=..., aResult=0x7feffffe930)
    at
/build/firefox-F4xXKx/firefox-46.0.1/xpcom/components/nsComponentManager.cpp:1232
#19 0xfff8000100bfc298 in nsComponentManagerImpl::GetServiceByContractID
(this=0xfff800010a7f60c0,
    aContractID=0xfff8000102bb8b98 "@mozilla.org/moz/jsloader;1",
aIID=..., aResult=0x7feffffeac0)
    at
/build/firefox-F4xXKx/firefox-46.0.1/xpcom/components/nsComponentManager.cpp:1592
#20 0xfff8000100c28514 in CallGetService (aContractID=0xfff8000102bab760
<nsISupports::COMTypeInfo<nsISupports, void>::kIID> "", aIID=...,
aResult=0x0,
    aResult@entry=0x7feffffeac0) at
/build/firefox-F4xXKx/firefox-46.0.1/xpcom/glue/nsComponentManagerUtils.cpp:69
#21 0xfff8000100c28538 in nsGetServiceByContractID::operator()
(this=this@entry=0x7feffffeb58, aIID=...,
aInstancePtr=aInstancePtr@entry=0x7feffffeac0)
    at
/build/firefox-F4xXKx/firefox-46.0.1/xpcom/glue/nsComponentManagerUtils.cpp:280
#22 0xfff8000100c202b0 in nsCOMPtr_base::assign_from_gs_contractid
(this=this@entry=0x7feffffeba0, aGS=..., aIID=...)
    at /build/firefox-F4xXKx/firefox-46.0.1/xpcom/glue/nsCOMPtr.cpp:103
#23 0xfff8000100c24c28 in nsCOMPtr<nsISupports>::nsCOMPtr (aGS=...,
this=0x7feffffeba0)
    at
/build/firefox-F4xXKx/firefox-46.0.1/build-browser/dist/include/nsCOMPtr.h:855
#24 NS_InitXPCOM2 (aResult=0x7feffffedd8, aBinDirectory=<optimized out>,
aAppFileLocationProvider=<optimized out>)
    at /build/firefox-F4xXKx/firefox-46.0.1/xpcom/build/XPCOMInit.cpp:724
---Type <return> to continue, or q <return> to quit---
#25 0xfff8000100c24de0 in NS_InitXPCOM2 (aResult=0x1,
aBinDirectory=0x7fefffff598, aAppFileLocationProvider=0x7fefffff5a8,
aAppFileLocationProvider@entry=0x7feffffee90)
    at /build/firefox-F4xXKx/firefox-46.0.1/xpcom/build/XPCOMInit.cpp:481
#26 0xfff800010107a794 in XRE_XPCShellMain (argc=1, argv=0x7fefffff598,
envp=0x7fefffff5a8) at
/build/firefox-F4xXKx/firefox-46.0.1/js/xpconnect/src/XPCShellImpl.cpp:1424
#27 0x0000010000004710 in main (argc=1, argv=0x7fefffff598,
envp=0x7fefffff5a8) at
/build/firefox-ORgwZM/firefox-46.0.1/js/xpconnect/shell/xpcshell.cpp:54
(gdb)

Michael Karcher was able to identify this as an issue with JSValue which
has been reported before upstream [1]. The suggested fix, using a hint
for mmap to force memory being allocated above 0x0000070000000000UL
which doesn't work on Linux however, since the hint is completely
ignored on consecutive calls and the memory is again allocated
in the lower area:

root@deb4g:~# cat vmtest.c
#include <stdio.h>
#include <sys/mman.h>

int main(void)
{
	void *ptr1, *ptr2, *ptr3;
	ptr1 = mmap(NULL, 1024*1024, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
	ptr2 = mmap((void*)0x0000070000000000UL, 1024*1024, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
	ptr3 = mmap((void*)0x0000070000000000UL, 1024*1024, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
	printf("%p %p %p\n", ptr1, ptr2, ptr3);
}
root@deb4g:~# ./vmtest
0xfff800010038e000 0x70000000000 0xfff800010048e000
root@deb4g:~#

Thus, in order to fix this issue on sparc64/Linux, a more elaborate
fix will have to be developed.

Adrian

> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=994133

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913
diff --git a/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/Makefile.in b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/Makefile.in
index 54fdddb..22fb720 100644
--- a/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/Makefile.in
+++ b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/Makefile.in
@@ -332,6 +332,11 @@ ifneq (,$(findstring sparc,$(OS_TEST)))
 CPPSRCS		:= xptcinvoke_sparc_solaris.cpp xptcstubs_sparc_solaris.cpp
 ASFILES		:= xptcinvoke_asm_sparc_linux_GCC3.s xptcstubs_asm_sparc_solaris.s
 endif
+# Linux/SPARC 64bit (borrow openbsd code) (OS_ARCH=Linux OS_TEST=sparc64)
+ifdef HAVE_64BIT_OS
+ASFILES		:= xptcinvoke_asm_sparc64_linux.s xptcstubs_asm_sparc64_linux.s
+CPPSRCS		:= xptcinvoke_sparc64_linux.cpp xptcstubs_sparc64_linux.cpp 
+endif
 endif
 #
 # NetBSD/SPARC
diff --git a/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc64_linux.s b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc64_linux.s
new file mode 100644
index 0000000..02d6c81
--- /dev/null
+++ b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc64_linux.s
@@ -0,0 +1,86 @@
+/* -*- Mode: asm; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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 sparcv9 GNU/Linux.
+
+    See the SPARC Compliance Definition (SCD) Chapter 3
+    for more information about what is going on here, including
+    the use of BIAS (0x7ff).
+    The SCD is available from http://www.sparc.com/.
+*/
+
+        .global NS_InvokeByIndex_P
+        .type   NS_InvokeByIndex_P, #function
+
+/*
+    NS_InvokeByIndex_P(nsISupports* that, uint32_t methodIndex,
+                     uint32_t paramCount, nsXPTCVariant* params);
+    
+*/
+NS_InvokeByIndex_P:
+        save    %sp,-(128 + 64),%sp ! room for the register window and
+                                    ! struct pointer, rounded up to 0 % 64
+        sll     %i2,4,%l0           ! assume the worst case
+                                    ! paramCount * 2 * 8 bytes
+        cmp     %l0, 0              ! are there any args? If not,
+        be      .invoke             ! no need to copy args to stack
+        nop
+
+        sub     %sp,%l0,%sp         ! create the additional stack space
+        add     %sp,0x7ff+136,%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
+
+!
+!   load arguments from stack into the outgoing registers
+!   BIAS is 0x7ff (2047)
+!
+
+!   load the %o1..5 64bit (extended word) output registers registers 
+        ldx     [%sp + 0x7ff + 136],%o1    ! %i1
+        ldx     [%sp + 0x7ff + 144],%o2    ! %i2
+        ldx     [%sp + 0x7ff + 152],%o3    ! %i3
+        ldx     [%sp + 0x7ff + 160],%o4    ! %i4
+        ldx     [%sp + 0x7ff + 168],%o5    ! %i5
+
+!   load the even number double registers starting with %f2
+        ldd     [%sp + 0x7ff + 136],%f2
+        ldd     [%sp + 0x7ff + 144],%f4
+        ldd     [%sp + 0x7ff + 152],%f6
+        ldd     [%sp + 0x7ff + 160],%f8
+        ldd     [%sp + 0x7ff + 168],%f10
+        ldd     [%sp + 0x7ff + 176],%f12
+        ldd     [%sp + 0x7ff + 184],%f14
+        ldd     [%sp + 0x7ff + 192],%f16
+        ldd     [%sp + 0x7ff + 200],%f18
+        ldd     [%sp + 0x7ff + 208],%f20
+        ldd     [%sp + 0x7ff + 216],%f22
+        ldd     [%sp + 0x7ff + 224],%f24
+        ldd     [%sp + 0x7ff + 232],%f26
+        ldd     [%sp + 0x7ff + 240],%f28
+        ldd     [%sp + 0x7ff + 248],%f30
+
+!
+!   calculate the target address from the vtable
+!
+.invoke:
+        sll     %i1,3,%l0           ! index *= 8
+!       add     %l0,16,%l0          ! there are 2 extra entries in the vTable (16bytes)
+        ldx     [%i0],%l1           ! *that --> address of vtable
+        ldx     [%l0 + %l1],%l0     ! that->vtable[index * 8 + 16] --> address
+
+        jmpl    %l0,%o7             ! call the routine
+        mov     %i0,%o0             ! move 'this' pointer to out register
+
+        mov     %o0,%i0             ! propagate return value
+        ret
+        restore
+
+        .size    NS_InvokeByIndex_P, .-NS_InvokeByIndex_P
diff --git a/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc64_linux.cpp b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc64_linux.cpp
new file mode 100644
index 0000000..050f941
--- /dev/null
+++ b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_sparc64_linux.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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"
+
+#if !defined(__sparc) && !defined(__sparc__)
+#error "This code is for Sparc only"
+#endif
+
+extern "C" uint64_t
+invoke_copy_to_stack(uint64_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.
+  */
+  uint64_t *l_d = d;
+  nsXPTCVariant *l_s = s;
+  uint64_t l_paramCount = paramCount;
+  uint64_t regCount = 0;  // return the number of registers to load from the stack
+
+  for(uint64_t i = 0; i < l_paramCount; i++, l_d++, l_s++)
+  {
+    if (regCount < 5) regCount++;
+
+    if (l_s->IsPtrData())
+    {
+      *l_d = (uint64_t)l_s->ptr;
+      continue;
+    }
+    switch (l_s->type)
+    {
+      case nsXPTType::T_I8    : *((int64_t*)l_d)     = l_s->val.i8;    break;
+      case nsXPTType::T_I16   : *((int64_t*)l_d)     = l_s->val.i16;   break;
+      case nsXPTType::T_I32   : *((int64_t*)l_d)     = l_s->val.i32;   break;
+      case nsXPTType::T_I64   : *((int64_t*)l_d)     = l_s->val.i64;   break;
+      
+      case nsXPTType::T_U8    : *((uint64_t*)l_d)    = l_s->val.u8;    break;
+      case nsXPTType::T_U16   : *((uint64_t*)l_d)    = l_s->val.u16;   break;
+      case nsXPTType::T_U32   : *((uint64_t*)l_d)    = l_s->val.u32;   break;
+      case nsXPTType::T_U64   : *((uint64_t*)l_d)    = l_s->val.u64;   break;
+
+      /* in the case of floats, we want to put the bits in to the
+         64bit space right justified... floats in the parameter array on
+         sparcv9 use odd numbered registers.. %f1, %f3, so we have to skip
+         the space that would be occupied by %f0, %f2, etc.
+      */
+      case nsXPTType::T_FLOAT : *(((float*)l_d) + 1) = l_s->val.f;     break;
+      case nsXPTType::T_DOUBLE: *((double*)l_d)      = l_s->val.d;     break;
+      case nsXPTType::T_BOOL  : *((int64_t*)l_d)     = l_s->val.b;     break;
+      case nsXPTType::T_CHAR  : *((uint64_t*)l_d)    = l_s->val.c;     break;
+      case nsXPTType::T_WCHAR : *((int64_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/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc64_linux.s b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc64_linux.s
new file mode 100644
index 0000000..ab97a89
--- /dev/null
+++ b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_sparc64_linux.s
@@ -0,0 +1,50 @@
+/* -*- Mode: asm; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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, 0x7ff + 136, %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
+        stx     %i1, [%fp + 0x7ff + 136]
+        stx     %i2, [%fp + 0x7ff + 144]
+        stx     %i3, [%fp + 0x7ff + 152]
+        stx     %i4, [%fp + 0x7ff + 160]
+        stx     %i5, [%fp + 0x7ff + 168]
+! now we can build our own stack frame
+        save    %sp,-(128 + 64),%sp    ! room for the register window and
+                                       ! struct pointer, rounded up to 0 % 64
+! 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/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc64_linux.cpp b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc64_linux.cpp
new file mode 100644
index 0000000..a84def3
--- /dev/null
+++ b/mozilla-esr17/xpcom/reflect/xptcall/src/md/unix/xptcstubs_sparc64_linux.cpp
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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
+PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
+{
+
+#define PARAM_BUFFER_COUNT     16
+
+    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
+    nsXPTCMiniVariant* dispatchParams = NULL;
+    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");
+    if (!dispatchParams)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    uint64_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())
+        {
+            dp->val.p = (void*) *ap;
+            continue;
+        }
+        // else
+        switch(type)
+        {
+        case nsXPTType::T_BOOL   : dp->val.b   = *((int64_t*)  ap);      break;
+        case nsXPTType::T_CHAR   : dp->val.c   = *((uint64_t*) ap);      break;
+        case nsXPTType::T_WCHAR  : dp->val.wc  = *((int64_t*) ap);       break;
+        case nsXPTType::T_I8     : dp->val.i8  = *((int64_t*)  ap);      break;
+        case nsXPTType::T_I16    : dp->val.i16 = *((int64_t*) ap);       break;
+        case nsXPTType::T_I32    : dp->val.i32 = *((int64_t*) ap);       break;
+        case nsXPTType::T_I64    : dp->val.i64 = *((int64_t*) ap);       break;
+        case nsXPTType::T_U8     : dp->val.u8  = *((uint64_t*) ap);      break;
+        case nsXPTType::T_U16    : dp->val.u16 = *((uint64_t*)ap);       break;
+        case nsXPTType::T_U32    : dp->val.u32 = *((uint64_t*)ap);       break;
+        case nsXPTType::T_U64    : dp->val.u64 = *((uint64_t*) ap);      break;
+        case nsXPTType::T_FLOAT  : dp->val.f   = ((float*)   ap)[1];     break;
+        case nsXPTType::T_DOUBLE : dp->val.d   = *((double*) 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" int 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 -up xulrunner-17.0.10/mozilla-esr17/ipc/chromium/src/build/build_config.h.orig xulrunner-17.0.10/mozilla-esr17/ipc/chromium/src/build/build_config.h
--- xulrunner-17.0.10/mozilla-esr17/ipc/chromium/src/build/build_config.h.orig	2013-10-22 18:52:31.000000000 -0700
+++ xulrunner-17.0.10/mozilla-esr17/ipc/chromium/src/build/build_config.h	2014-02-23 18:37:59.237545340 -0800
@@ -65,7 +65,7 @@
 #elif defined(__ppc__) || defined(__powerpc__)
 #define ARCH_CPU_PPC 1
 #define ARCH_CPU_32_BITS 1
-#elif defined(__sparc64__)
+#elif (defined(__sparc64__) || defined(__sparc_v9__))
 #define ARCH_CPU_SPARC 1
 #define ARCH_CPU_64_BITS 1
 #elif defined(__sparc__)
diff -up xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in.orig xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in
--- xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in.orig	2013-10-22 18:52:56.000000000 -0700
+++ xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in	2014-02-23 18:37:59.241545340 -0800
@@ -261,7 +261,7 @@ static const bool config_ivsalloc =
 #  ifdef __alpha__
 #    define LG_QUANTUM		4
 #  endif
-#  ifdef __sparc64__
+#  if (defined(__sparc64__) || defined(__sparc_v9__))
 #    define LG_QUANTUM		4
 #  endif
 #  if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64))
diff -up xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/mb.h.orig xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/mb.h
--- xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/mb.h.orig	2013-10-22 18:52:56.000000000 -0700
+++ xulrunner-17.0.10/mozilla-esr17/memory/jemalloc/src/include/jemalloc/internal/mb.h	2014-02-23 18:37:59.241545340 -0800
@@ -76,7 +76,7 @@ mb_write(void)
 	    : "memory" /* Clobbers. */
 	    );
 }
-#elif defined(__sparc64__)
+#elif (defined(__sparc64__) || defined(__sparc_v9__))
 JEMALLOC_INLINE void
 mb_write(void)
 {
diff -up xulrunner-17.0.10/mozilla-esr17/memory/mozjemalloc/jemalloc.c.orig xulrunner-17.0.10/mozilla-esr17/memory/mozjemalloc/jemalloc.c
--- xulrunner-17.0.10/mozilla-esr17/memory/mozjemalloc/jemalloc.c.orig	2014-02-23 18:36:51.149546784 -0800
+++ xulrunner-17.0.10/mozilla-esr17/memory/mozjemalloc/jemalloc.c	2014-02-23 18:47:22.477533388 -0800
@@ -482,7 +482,7 @@ static const bool isthreaded = true;
 #  define SIZEOF_PTR_2POW	3
 #  define NO_TLS
 #endif
-#ifdef __sparc64__
+#if (defined(__sparc64__) || defined( __sparc_v9__))
 #  define QUANTUM_2POW_MIN	4
 #  define SIZEOF_PTR_2POW	3
 #  define NO_TLS
@@ -5674,6 +5674,7 @@ malloc_init_hard(void)
 		_malloc_message(_getprogname(),
 				"Compile-time page size does not divide the runtime one.\n",
 				"", "");
+                malloc_printf("#-# pagesize=[%d], (size_t) result=[%d] #-#\n", pagesize, result);
 		abort();
 	}
 #else	
diff -up xulrunner-17.0.10/mozilla-esr17/other-licenses/android/getaddrinfo.c.orig xulrunner-17.0.10/mozilla-esr17/other-licenses/android/getaddrinfo.c
--- xulrunner-17.0.10/mozilla-esr17/other-licenses/android/getaddrinfo.c.orig	2013-10-22 18:53:02.000000000 -0700
+++ xulrunner-17.0.10/mozilla-esr17/other-licenses/android/getaddrinfo.c	2014-02-23 18:37:59.245545340 -0800
@@ -1062,7 +1062,7 @@ get_ai(const struct addrinfo *pai, const
 #endif
 
 	ai->ai_addrlen = afd->a_socklen;
-#if defined (__alpha__) || (defined(__i386__) && defined(_LP64)) || defined(__sparc64__)
+#if defined (__alpha__) || (defined(__i386__) && defined(_LP64)) || (defined(__sparc64__) || define(__sparc_v9__))
 	ai->__ai_pad0 = 0;
 #endif
 	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
--- xulrunner-17.0.10/mozilla-esr17/memory/mozjemalloc/jemalloc.c.orig	2014-02-23 18:51:55.197527601 -0800
+++ xulrunner-17.0.10/mozilla-esr17/memory/mozjemalloc/jemalloc.c	2014-02-23 19:46:22.625458269 -0800
@@ -1101,7 +1101,14 @@
  * VM page size. It must divide the runtime CPU page size or the code
  * will abort.
  */
+#if (defined(SOLARIS) || defined(__FreeBSD__) || defined(__linux__)) && \
+    (defined(__sparc) || defined(__sparcv9) || defined(__sparc_v9__) || defined(__ia64))
+#define pagesize_2pow			((size_t) 13)
+#elif defined(__powerpc64__) || defined(__aarch64__)
+#define pagesize_2pow			((size_t) 16)
+#else
 #define pagesize_2pow			((size_t) 12)
+#endif
 #define pagesize			((size_t) 1 << pagesize_2pow)
 #define pagesize_mask			(pagesize - 1)
 
diff -up xulrunner-17.0.10/mozilla-esr17/js/src/gc/Heap.h.orig xulrunner-17.0.10/mozilla-esr17/js/src/gc/Heap.h
--- xulrunner-17.0.10/mozilla-esr17/js/src/gc/Heap.h.orig	2014-02-24 05:45:49.996695068 -0800
+++ xulrunner-17.0.10/mozilla-esr17/js/src/gc/Heap.h	2014-02-24 05:47:29.824692950 -0800
@@ -110,7 +110,7 @@ struct Cell
  * Bug 692267: Move page size definition to gc/Memory.h and include it
  *             directly once jsgc.h is no longer an installed header.
  */
-#if defined(SOLARIS) && (defined(__sparc) || defined(__sparcv9))
+#if (defined(SOLARIS) || defined(linux)) && (defined(__sparc) || defined(__sparcv9) || defined(__sparc_v9__))
 const size_t PageShift = 13;
 const size_t ArenaShift = PageShift;
 #elif defined(__powerpc__)
diff -up xulrunner-17.0.10/mozilla-esr17/js/src/jsscript.h.orig xulrunner-17.0.10/mozilla-esr17/js/src/jsscript.h
--- xulrunner-17.0.10/mozilla-esr17/js/src/jsscript.h.orig	2014-02-25 05:35:48.271122078 -0800
+++ xulrunner-17.0.10/mozilla-esr17/js/src/jsscript.h	2014-02-25 05:38:59.107118029 -0800
@@ -52,6 +52,9 @@ struct JSTryNote {
     uint8_t         kind;       /* one of JSTryNoteKind */
     uint8_t         padding;    /* explicit padding on uint16_t boundary */
     uint16_t        stackDepth; /* stack depth upon exception handler entry */
+#if defined(__sparc__)
+    uint32_t        pad1;	/* Padding required for alignment on sparc */
+#endif
     uint32_t        start;      /* start of the try statement or for-in loop
                                    relative to script->main */
     uint32_t        length;     /* length of the try statement or for-in loop */
--- firefox-46.0.1.orig/ipc/chromium/src/build/build_config.h
+++ firefox-46.0.1/ipc/chromium/src/build/build_config.h
@@ -81,7 +81,7 @@
 #elif defined(__ppc__) || defined(__powerpc__)
 #define ARCH_CPU_PPC 1
 #define ARCH_CPU_32_BITS 1
-#elif defined(__sparc64__)
+#elif (defined(__sparc64__) || defined(__sparc_v9__))
 #define ARCH_CPU_SPARC 1
 #define ARCH_CPU_64_BITS 1
 #elif defined(__sparc__)
--- firefox-46.0.1.orig/js/src/jsscript.h
+++ firefox-46.0.1/js/src/jsscript.h
@@ -92,6 +92,10 @@ enum JSTryNoteKind {
 struct JSTryNote {
     uint8_t         kind;       /* one of JSTryNoteKind */
     uint32_t        stackDepth; /* stack depth upon exception handler entry */
+#if defined(__sparc__)
+    uint8_t         pad1;
+    uint16_t        pad2;
+#endif
     uint32_t        start;      /* start of the try statement or loop
                                    relative to script->main */
     uint32_t        length;     /* length of the try statement or loop */
--- firefox-46.0.1.orig/memory/jemalloc/src/include/jemalloc/internal/mb.h
+++ firefox-46.0.1/memory/jemalloc/src/include/jemalloc/internal/mb.h
@@ -76,7 +76,7 @@ mb_write(void)
 	    : "memory" /* Clobbers. */
 	    );
 }
-#elif defined(__sparc64__)
+#elif (defined(__sparc64__) || defined(__sparc_v9__))
 JEMALLOC_INLINE void
 mb_write(void)
 {
--- firefox-46.0.1.orig/memory/mozjemalloc/jemalloc.c
+++ firefox-46.0.1/memory/mozjemalloc/jemalloc.c
@@ -485,7 +485,7 @@ static const bool isthreaded = true;
 #  define SIZEOF_PTR_2POW	3
 #  define NO_TLS
 #endif
-#ifdef __sparc64__
+#if (defined(__sparc64__) || defined( __sparc_v9__))
 #  define QUANTUM_2POW_MIN	4
 #  define SIZEOF_PTR_2POW	3
 #  define NO_TLS
@@ -1100,8 +1100,8 @@ static const bool config_recycle = false
  * will abort.
  * Platform specific page size conditions copied from js/public/HeapAPI.h
  */
-#if (defined(SOLARIS) || defined(__FreeBSD__)) && \
-    (defined(__sparc) || defined(__sparcv9) || defined(__ia64))
+#if (defined(SOLARIS) || defined(__FreeBSD__)) defined(__linux__) &&	\
+    (defined(__sparc) || defined(__sparcv9) || defined(__sparc_v9__) defined(__ia64))
 #define pagesize_2pow			((size_t) 13)
 #elif defined(__powerpc64__) || defined(__aarch64__)
 #define pagesize_2pow			((size_t) 16)
@@ -5615,6 +5615,7 @@ malloc_init_hard(void)
 		_malloc_message(_getprogname(),
 				"Compile-time page size does not divide the runtime one.\n",
 				"", "");
+                malloc_printf("#-# pagesize=[%d], (size_t) result=[%d] #-#\n", pagesize, result);
 		abort();
 	}
 #else	
--- firefox-46.0.1.orig/other-licenses/android/getaddrinfo.c
+++ firefox-46.0.1/other-licenses/android/getaddrinfo.c
@@ -1089,7 +1089,7 @@ get_ai(const struct addrinfo *pai, const
 #endif
 
 	ai->ai_addrlen = afd->a_socklen;
-#if defined (__alpha__) || (defined(__i386__) && defined(_LP64)) || defined(__sparc64__)
+#if defined (__alpha__) || (defined(__i386__) && defined(_LP64)) || (defined(__sparc64__) || define(__sparc_v9__))
 	ai->__ai_pad0 = 0;
 #endif
 	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
--- firefox-46.0.1.orig/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
+++ firefox-46.0.1/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
@@ -67,7 +67,7 @@
 #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
 #elif defined(sparc)
 #define GOOGLE_PROTOBUF_ARCH_SPARC 1
-#ifdef SOLARIS_64BIT_ENABLED
+#if defined(SOLARIS_64BIT_ENABLED) || defined(__arch64__)
 #define GOOGLE_PROTOBUF_ARCH_64_BIT 1
 #else
 #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
--- firefox-46.0.1.orig/xpcom/reflect/xptcall/md/unix/Makefile.in
+++ firefox-46.0.1/xpcom/reflect/xptcall/md/unix/Makefile.in
@@ -76,4 +76,9 @@ xptcstubsdef_asm.solx86: $(DIST)/include
 	$(DIST)/include/xptcstubsdef.inc > $@
 endif
 endif
+# Linux/SPARC 64bit (borrow openbsd code) (OS_ARCH=Linux OS_TEST=sparc64)
+ifdef HAVE_64BIT_OS
+ASFILES		:= xptcinvoke_asm_sparc64_linux.s xptcstubs_asm_sparc64_linux.s
+CPPSRCS		:= xptcinvoke_sparc64_linux.cpp xptcstubs_sparc64_linux.cpp 
+endif
 endif
--- /dev/null
+++ firefox-46.0.1/xpcom/reflect/xptcall/md/unix/xptcinvoke_asm_sparc64_linux.s
@@ -0,0 +1,86 @@
+/* -*- Mode: asm; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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 sparcv9 GNU/Linux.
+
+    See the SPARC Compliance Definition (SCD) Chapter 3
+    for more information about what is going on here, including
+    the use of BIAS (0x7ff).
+    The SCD is available from http://www.sparc.com/.
+*/
+
+        .global NS_InvokeByIndex_P
+        .type   NS_InvokeByIndex_P, #function
+
+/*
+    NS_InvokeByIndex_P(nsISupports* that, uint32_t methodIndex,
+                     uint32_t paramCount, nsXPTCVariant* params);
+    
+*/
+NS_InvokeByIndex_P:
+        save    %sp,-(128 + 64),%sp ! room for the register window and
+                                    ! struct pointer, rounded up to 0 % 64
+        sll     %i2,4,%l0           ! assume the worst case
+                                    ! paramCount * 2 * 8 bytes
+        cmp     %l0, 0              ! are there any args? If not,
+        be      .invoke             ! no need to copy args to stack
+        nop
+
+        sub     %sp,%l0,%sp         ! create the additional stack space
+        add     %sp,0x7ff+136,%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
+
+!
+!   load arguments from stack into the outgoing registers
+!   BIAS is 0x7ff (2047)
+!
+
+!   load the %o1..5 64bit (extended word) output registers registers 
+        ldx     [%sp + 0x7ff + 136],%o1    ! %i1
+        ldx     [%sp + 0x7ff + 144],%o2    ! %i2
+        ldx     [%sp + 0x7ff + 152],%o3    ! %i3
+        ldx     [%sp + 0x7ff + 160],%o4    ! %i4
+        ldx     [%sp + 0x7ff + 168],%o5    ! %i5
+
+!   load the even number double registers starting with %f2
+        ldd     [%sp + 0x7ff + 136],%f2
+        ldd     [%sp + 0x7ff + 144],%f4
+        ldd     [%sp + 0x7ff + 152],%f6
+        ldd     [%sp + 0x7ff + 160],%f8
+        ldd     [%sp + 0x7ff + 168],%f10
+        ldd     [%sp + 0x7ff + 176],%f12
+        ldd     [%sp + 0x7ff + 184],%f14
+        ldd     [%sp + 0x7ff + 192],%f16
+        ldd     [%sp + 0x7ff + 200],%f18
+        ldd     [%sp + 0x7ff + 208],%f20
+        ldd     [%sp + 0x7ff + 216],%f22
+        ldd     [%sp + 0x7ff + 224],%f24
+        ldd     [%sp + 0x7ff + 232],%f26
+        ldd     [%sp + 0x7ff + 240],%f28
+        ldd     [%sp + 0x7ff + 248],%f30
+
+!
+!   calculate the target address from the vtable
+!
+.invoke:
+        sll     %i1,3,%l0           ! index *= 8
+!       add     %l0,16,%l0          ! there are 2 extra entries in the vTable (16bytes)
+        ldx     [%i0],%l1           ! *that --> address of vtable
+        ldx     [%l0 + %l1],%l0     ! that->vtable[index * 8 + 16] --> address
+
+        jmpl    %l0,%o7             ! call the routine
+        mov     %i0,%o0             ! move 'this' pointer to out register
+
+        mov     %o0,%i0             ! propagate return value
+        ret
+        restore
+
+        .size    NS_InvokeByIndex_P, .-NS_InvokeByIndex_P
--- /dev/null
+++ firefox-46.0.1/xpcom/reflect/xptcall/md/unix/xptcinvoke_sparc64_linux.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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"
+
+#if !defined(__sparc) && !defined(__sparc__)
+#error "This code is for Sparc only"
+#endif
+
+extern "C" uint64_t
+invoke_copy_to_stack(uint64_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.
+  */
+  uint64_t *l_d = d;
+  nsXPTCVariant *l_s = s;
+  uint64_t l_paramCount = paramCount;
+  uint64_t regCount = 0;  // return the number of registers to load from the stack
+
+  for(uint64_t i = 0; i < l_paramCount; i++, l_d++, l_s++)
+  {
+    if (regCount < 5) regCount++;
+
+    if (l_s->IsPtrData())
+    {
+      *l_d = (uint64_t)l_s->ptr;
+      continue;
+    }
+    switch (l_s->type)
+    {
+      case nsXPTType::T_I8    : *((int64_t*)l_d)     = l_s->val.i8;    break;
+      case nsXPTType::T_I16   : *((int64_t*)l_d)     = l_s->val.i16;   break;
+      case nsXPTType::T_I32   : *((int64_t*)l_d)     = l_s->val.i32;   break;
+      case nsXPTType::T_I64   : *((int64_t*)l_d)     = l_s->val.i64;   break;
+      
+      case nsXPTType::T_U8    : *((uint64_t*)l_d)    = l_s->val.u8;    break;
+      case nsXPTType::T_U16   : *((uint64_t*)l_d)    = l_s->val.u16;   break;
+      case nsXPTType::T_U32   : *((uint64_t*)l_d)    = l_s->val.u32;   break;
+      case nsXPTType::T_U64   : *((uint64_t*)l_d)    = l_s->val.u64;   break;
+
+      /* in the case of floats, we want to put the bits in to the
+         64bit space right justified... floats in the parameter array on
+         sparcv9 use odd numbered registers.. %f1, %f3, so we have to skip
+         the space that would be occupied by %f0, %f2, etc.
+      */
+      case nsXPTType::T_FLOAT : *(((float*)l_d) + 1) = l_s->val.f;     break;
+      case nsXPTType::T_DOUBLE: *((double*)l_d)      = l_s->val.d;     break;
+      case nsXPTType::T_BOOL  : *((int64_t*)l_d)     = l_s->val.b;     break;
+      case nsXPTType::T_CHAR  : *((uint64_t*)l_d)    = l_s->val.c;     break;
+      case nsXPTType::T_WCHAR : *((int64_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;
+}
--- /dev/null
+++ firefox-46.0.1/xpcom/reflect/xptcall/md/unix/xptcstubs_asm_sparc64_linux.s
@@ -0,0 +1,50 @@
+/* -*- Mode: asm; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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, 0x7ff + 136, %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
+        stx     %i1, [%fp + 0x7ff + 136]
+        stx     %i2, [%fp + 0x7ff + 144]
+        stx     %i3, [%fp + 0x7ff + 152]
+        stx     %i4, [%fp + 0x7ff + 160]
+        stx     %i5, [%fp + 0x7ff + 168]
+! now we can build our own stack frame
+        save    %sp,-(128 + 64),%sp    ! room for the register window and
+                                       ! struct pointer, rounded up to 0 % 64
+! 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
--- /dev/null
+++ firefox-46.0.1/xpcom/reflect/xptcall/md/unix/xptcstubs_sparc64_linux.cpp
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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
+PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
+{
+
+#define PARAM_BUFFER_COUNT     16
+
+    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
+    nsXPTCMiniVariant* dispatchParams = NULL;
+    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");
+    if (!dispatchParams)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    uint64_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())
+        {
+            dp->val.p = (void*) *ap;
+            continue;
+        }
+        // else
+        switch(type)
+        {
+        case nsXPTType::T_BOOL   : dp->val.b   = *((int64_t*)  ap);      break;
+        case nsXPTType::T_CHAR   : dp->val.c   = *((uint64_t*) ap);      break;
+        case nsXPTType::T_WCHAR  : dp->val.wc  = *((int64_t*) ap);       break;
+        case nsXPTType::T_I8     : dp->val.i8  = *((int64_t*)  ap);      break;
+        case nsXPTType::T_I16    : dp->val.i16 = *((int64_t*) ap);       break;
+        case nsXPTType::T_I32    : dp->val.i32 = *((int64_t*) ap);       break;
+        case nsXPTType::T_I64    : dp->val.i64 = *((int64_t*) ap);       break;
+        case nsXPTType::T_U8     : dp->val.u8  = *((uint64_t*) ap);      break;
+        case nsXPTType::T_U16    : dp->val.u16 = *((uint64_t*)ap);       break;
+        case nsXPTType::T_U32    : dp->val.u32 = *((uint64_t*)ap);       break;
+        case nsXPTType::T_U64    : dp->val.u64 = *((uint64_t*) ap);      break;
+        case nsXPTType::T_FLOAT  : dp->val.f   = ((float*)   ap)[1];     break;
+        case nsXPTType::T_DOUBLE : dp->val.d   = *((double*) 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" int 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__ */

Reply to: