Description: Fix build on sparc64
Author: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Forwarded: https://bugzilla.mozilla.org/show_bug.cgi?id=1275204
Last-Update: 2016-12-30

--- firefox-50.1.0.orig/image/decoders/nsIconDecoder.cpp
+++ firefox-50.1.0/image/decoders/nsIconDecoder.cpp
@@ -97,7 +97,8 @@ nsIconDecoder::ReadRowOfPixels(const cha
       return AsVariant(WriteState::NEED_MORE_DATA);  // Done with this row.
     }
 
-    uint32_t pixel = *reinterpret_cast<const uint32_t*>(aData);
+    uint32_t pixel;
+    memcpy(&pixel, aData, sizeof(pixel));
     aData += 4;
     aLength -= 4;
 
--- firefox-50.1.0.orig/ipc/chromium/src/build/build_config.h
+++ firefox-50.1.0/ipc/chromium/src/build/build_config.h
@@ -83,7 +83,7 @@
 #elif defined(__ppc__) || defined(__powerpc__)
 #define ARCH_CPU_PPC 1
 #define ARCH_CPU_32_BITS 1
-#elif defined(__sparc64__)
+#elif defined(__sparc__) && defined(__arch64__)
 #define ARCH_CPU_SPARC 1
 #define ARCH_CPU_64_BITS 1
 #elif defined(__sparc__)
--- firefox-50.1.0.orig/js/src/gc/Memory.cpp
+++ firefox-50.1.0/js/src/gc/Memory.cpp
@@ -490,7 +490,7 @@ static inline void*
 MapMemoryAt(void* desired, size_t length, int prot = PROT_READ | PROT_WRITE,
             int flags = MAP_PRIVATE | MAP_ANON, int fd = -1, off_t offset = 0)
 {
-#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__)) || defined(__aarch64__)
+#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && (defined(__NetBSD__) || defined(__linux__))) || defined(__aarch64__)
     MOZ_ASSERT((0xffff800000000000ULL & (uintptr_t(desired) + length - 1)) == 0);
 #endif
     void* region = mmap(desired, length, prot, flags, fd, offset);
@@ -513,7 +513,7 @@ static inline void*
 MapMemory(size_t length, int prot = PROT_READ | PROT_WRITE,
           int flags = MAP_PRIVATE | MAP_ANON, int fd = -1, off_t offset = 0)
 {
-#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__))
+#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__NetBSD__))
     /*
      * The JS engine assumes that all allocated pointers have their high 17 bits clear,
      * which ia64's mmap doesn't support directly. However, we can emulate it by passing
@@ -540,7 +540,7 @@ MapMemory(size_t length, int prot = PROT
         return nullptr;
     }
     return region;
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__))
    /*
     * There might be similar virtual address issue on arm64 which depends on
     * hardware and kernel configurations. But the work around is slightly
--- firefox-50.1.0.orig/js/src/jsapi-tests/testGCAllocator.cpp
+++ firefox-50.1.0/js/src/jsapi-tests/testGCAllocator.cpp
@@ -312,7 +312,7 @@ void unmapPages(void* p, size_t size) {
 void*
 mapMemoryAt(void* desired, size_t length)
 {
-#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__)) || defined(__aarch64__)
+#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && (defined(__NetBSD__) || defined(__linux__))) || defined(__aarch64__)
     MOZ_RELEASE_ASSERT(0xffff800000000000ULL & (uintptr_t(desired) + length - 1) == 0);
 #endif
     void* region = mmap(desired, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
@@ -334,7 +334,7 @@ mapMemory(size_t length)
     int fd = -1;
     off_t offset = 0;
     // The test code must be aligned with the implementation in gc/Memory.cpp.
-#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__))
+#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__NetBSD__))
     void* region = mmap((void*)0x0000070000000000, length, prot, flags, fd, offset);
     if (region == MAP_FAILED)
         return nullptr;
@@ -344,7 +344,7 @@ mapMemory(size_t length)
         return nullptr;
     }
     return region;
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__))
     const uintptr_t start = UINT64_C(0x0000070000000000);
     const uintptr_t end   = UINT64_C(0x0000800000000000);
     const uintptr_t step  = js::gc::ChunkSize;
--- firefox-50.1.0.orig/media/webrtc/trunk/build/build_config.h
+++ firefox-50.1.0/media/webrtc/trunk/build/build_config.h
@@ -129,7 +129,7 @@
 #define ARCH_CPU_PPC 1
 #define ARCH_CPU_32_BITS 1
 #define ARCH_CPU_BIG_ENDIAN 1
-#elif defined(__sparc64__)
+#elif defined(__sparc__) && defined(__arch64__)
 #define ARCH_CPU_SPARC_FAMILY 1
 #define ARCH_CPU_SPARC 1
 #define ARCH_CPU_64_BITS 1
--- firefox-50.1.0.orig/media/webrtc/trunk/webrtc/typedefs.h
+++ firefox-50.1.0/media/webrtc/trunk/webrtc/typedefs.h
@@ -61,7 +61,7 @@
 #define WEBRTC_ARCH_BIG_ENDIAN
 #define WEBRTC_BIG_ENDIAN
 #endif
-#elif defined(__sparc64__)
+#elif defined(__sparc__) && defined(__arch64__)
 #define WEBRTC_ARCH_SPARC 1
 #define WEBRTC_ARCH_64_BITS 1
 #define WEBRTC_ARCH_BIG_ENDIAN
--- firefox-50.1.0.orig/memory/jemalloc/src/include/jemalloc/internal/mb.h
+++ firefox-50.1.0/memory/jemalloc/src/include/jemalloc/internal/mb.h
@@ -76,7 +76,7 @@ mb_write(void)
 	    : "memory" /* Clobbers. */
 	    );
 }
-#elif defined(__sparc64__)
+#elif defined(__sparc__) && defined(__arch64__)
 JEMALLOC_INLINE void
 mb_write(void)
 {
--- firefox-50.1.0.orig/memory/mozjemalloc/jemalloc.c
+++ firefox-50.1.0/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(__sparc__) && defined(__arch64__)
 #  define QUANTUM_2POW_MIN	4
 #  define SIZEOF_PTR_2POW	3
 #  define NO_TLS
@@ -2412,7 +2412,7 @@ static void *
 pages_map(void *addr, size_t size)
 {
 	void *ret;
-#if defined(__ia64__)
+#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__))
         /*
          * The JS engine assumes that all allocated pointers have their high 17 bits clear,
          * which ia64's mmap doesn't support directly. However, we can emulate it by passing
@@ -2433,6 +2433,29 @@ pages_map(void *addr, size_t size)
 	}
 #endif
 
+#if defined(__sparc__) && defined(__arch64__) && defined(__linux__)
+    const uintptr_t start = UINT64_C(0x0000070000000000);
+    const uintptr_t end   = UINT64_C(0x0000800000000000);
+    const uintptr_t step  = 8 << 20; /* This is supposed to be ChunkSize */
+
+    /* Copied from js/src/Memory.cpp and adapted for this source */
+
+    uintptr_t hint;
+    void* region = MAP_FAILED;
+    for (hint = start; region == MAP_FAILED && hint + size <= end; hint += step) {
+           region = mmap((void*)hint, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+           if (region != MAP_FAILED) {
+                   if (((size_t) region + (size - 1)) & 0xffff800000000000) {
+                           if (munmap(region, size)) {
+                                   MOZ_ASSERT(errno == ENOMEM);
+                           }
+                           region = MAP_FAILED;
+                   }
+           }
+    }
+    ret = region;
+#else
+
 	/*
 	 * We don't use MAP_FIXED here, because it can cause the *replacement*
 	 * of existing mappings, and we only want to create new mappings.
@@ -2440,11 +2463,11 @@ pages_map(void *addr, size_t size)
 	ret = mmap(addr, size, PROT_READ | PROT_WRITE,
 		MAP_PRIVATE | MAP_ANON, -1, 0);
 	assert(ret != NULL);
-
+#endif
 	if (ret == MAP_FAILED) {
 		ret = NULL;
 	}
-#if defined(__ia64__)
+#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__))
         /* 
          * If the allocated memory doesn't have its upper 17 bits clear, consider it 
          * as out of memory.
@@ -2477,7 +2500,7 @@ pages_map(void *addr, size_t size)
 		MozTagAnonymousMemory(ret, size, "jemalloc");
 	}
 
-#if defined(__ia64__)
+#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__linux__))
 	assert(ret == NULL || (!check_placement && ret != NULL)
 	    || (check_placement && ret == addr));
 #else
--- firefox-50.1.0.orig/modules/woff2/src/store_bytes.h
+++ firefox-50.1.0/modules/woff2/src/store_bytes.h
@@ -34,10 +34,11 @@ inline size_t StoreU32(uint8_t* dst, siz
 
 inline size_t Store16(uint8_t* dst, size_t offset, int x) {
 #if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
-  *reinterpret_cast<uint16_t*>(dst + offset) =
-      ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
+  uint16_t v = ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
+  memcpy(dst + offset, &v, 2);
 #elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
-  *reinterpret_cast<uint16_t*>(dst + offset) = static_cast<uint16_t>(x);
+  uint16_t v = static_cast<uint16_t>(x);
+  memcpy(dst + offset, &v, 2);
 #else
   dst[offset] = x >> 8;
   dst[offset + 1] = x;
@@ -54,11 +55,13 @@ inline void StoreU32(uint32_t val, size_
 
 inline void Store16(int val, size_t* offset, uint8_t* dst) {
 #if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
-  *reinterpret_cast<uint16_t*>(dst + *offset) =
+  uint16_t v = ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8);
+  memcpy(dst + *offset, &v, 2);
       ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8);
   *offset += 2;
 #elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
-  *reinterpret_cast<uint16_t*>(dst + *offset) = static_cast<uint16_t>(val);
+  uint16_t v = static_cast<uint16_t>(val);
+  memcpy(dst + *offset, &v, 2);
   *offset += 2;
 #else
   dst[(*offset)++] = val >> 8;
--- firefox-50.1.0.orig/modules/woff2/src/woff2_common.cc
+++ firefox-50.1.0/modules/woff2/src/woff2_common.cc
@@ -25,12 +25,13 @@ uint32_t ComputeULongSum(const uint8_t*
   uint32_t checksum = 0;
   size_t aligned_size = size & ~3;
   for (size_t i = 0; i < aligned_size; i += 4) {
+    uint32_t v;
+    memcpy(&v, buf + i, 4);
 #if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
-    uint32_t v = *reinterpret_cast<const uint32_t*>(buf + i);
     checksum += (((v & 0xFF) << 24) | ((v & 0xFF00) << 8) |
       ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24));
 #elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
-    checksum += *reinterpret_cast<const uint32_t*>(buf + i);
+    checksum += v;
 #else
     checksum += (buf[i] << 24) | (buf[i + 1] << 16) |
       (buf[i + 2] << 8) | buf[i + 3];
--- firefox-50.1.0.orig/toolkit/components/protobuf/m-c-changes.patch
+++ firefox-50.1.0/toolkit/components/protobuf/m-c-changes.patch
@@ -408,3 +408,16 @@ diff --git a/toolkit/components/protobuf
  //      return result;
  //
  // I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+diff --git a/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h b/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
+index 7956d076dcd5..1bd67d436331 100644
+--- a/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
++++ b/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(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__)
+ #define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+ #else
+ #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
--- firefox-50.1.0.orig/toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h
+++ firefox-50.1.0/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(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__)
 #define GOOGLE_PROTOBUF_ARCH_64_BIT 1
 #else
 #define GOOGLE_PROTOBUF_ARCH_32_BIT 1
--- firefox-50.1.0.orig/xpcom/reflect/xptcall/md/unix/moz.build
+++ firefox-50.1.0/xpcom/reflect/xptcall/md/unix/moz.build
@@ -232,7 +232,7 @@ if CONFIG['OS_ARCH'] == 'OpenBSD' and CO
         'xptcstubs_ppc_openbsd.cpp',
     ]
 
-if CONFIG['OS_ARCH'] == 'Linux' and 'sparc' in CONFIG['OS_TEST']:
+if CONFIG['OS_ARCH'] == 'Linux' and CONFIG['OS_TEST'] == 'sparc':
     SOURCES += [
         'xptcinvoke_asm_sparc_linux_GCC3.s',
         'xptcinvoke_sparc_solaris.cpp',
@@ -256,7 +256,7 @@ if CONFIG['OS_ARCH'] == 'OpenBSD' and CO
         'xptcstubs_sparc_openbsd.cpp',
     ]
 
-if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD') and CONFIG['OS_TEST'] == 'sparc64':
+if CONFIG['OS_ARCH'] in ('OpenBSD', 'FreeBSD', 'Linux') and CONFIG['OS_TEST'] == 'sparc64':
     SOURCES += [
         'xptcinvoke_asm_sparc64_openbsd.s',
         'xptcinvoke_sparc64_openbsd.cpp',
