Browse Source

MoonchildProductions#1251 - Part 23: Allow AMD64 build to work.

https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Compiling_32-bit_Firefox_on_a_Linux_64-bit_OS

Setting this up turned out to be easier than I thought it would be. All I had to do was apply these instructions in reverse and add the following to my .mozconfig file:

CC="gcc -m64"
CXX="g++ -m64"
AS="gas --64"
ac_add_options --target=x86_64-pc-solaris2.11
export PKG_CONFIG_PATH=/usr/lib/amd64/pkgconfig
ac_add_options --libdir=/usr/lib/amd64
ac_add_options --x-libraries=/usr/lib/amd64

Most of these changes were fairly trivial, just requiring me to make a few of the changes I made earlier conditional on a 32-bit build. The biggest challenge was figuring out why the JavaScript engine triggered a segfault everytime it tried to allocate memory. But this patch fixes it:

https://github.com/OpenIndiana/oi-userland/blob/oi/hipster/components/web/firefox/patches/patch-js_src_gc_Memory.cpp.patch

Turns out that Solaris on AMD64 handles memory management in a fairly unusual way with a segmented memory model, but it's not that different from what we see on other 64-bit processors. In fact, I saw a SPARC crash for a similar reason, and noticed that it looked just like mine except the numbers in the first segment were reversed. Having played around with hex editors before, I had a feeling I might be dealing with a little-endian version of a big-endian problem, but I didn't expect that knowledge to actually yield an easy solution.

https://bugzilla.mozilla.org/show_bug.cgi?id=577056

https://www.oracle.com/technetwork/server-storage/solaris10/solaris-memory-135224.html

As far as I can tell, this was the last barrier to an AMD64 Solaris build of Pale Moon.
pull/24/head
athenian200 3 years ago committed by Roy Tam
parent
commit
0239eb8ac9
  1. 9
      config/external/ffi/moz.build
  2. 1
      config/external/nspr/pr/moz.build
  3. 2
      ipc/chromium/src/base/message_pump_libevent.cc
  4. 4
      ipc/chromium/src/third_party/libevent/solaris/event2/event-config.h
  5. 11
      js/src/gc/Memory.cpp
  6. 2
      xpcom/reflect/xptcall/md/unix/moz.build
  7. 75
      xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_solaris.cpp
  8. 9
      xpcom/string/nsTSubstring.h

9
config/external/ffi/moz.build vendored

@ -64,13 +64,20 @@ else:
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['OS_TARGET'] != 'SunOS':
DEFINES['HAVE_AS_X86_PCREL'] = True
# Which is why they apparently don't do this anymore on amd64.
if CONFIG['FFI_TARGET'] == 'X86_64' and CONFIG['OS_TARGET'] == 'SunOS':
DEFINES['HAVE_AS_X86_PCREL'] = True
# Don't bother setting EH_FRAME_FLAGS on Windows.
# Quoted defines confuse msvcc.sh, and the value isn't used there.
if CONFIG['OS_TARGET'] != 'WINNT':
# Solaris seems to require EH_FRAME to be writable even on x86.
# It works fine most of the time and there's no rule against it,
# but it causes a lot of weird problems.
if CONFIG['FFI_TARGET'] == 'ARM' or CONFIG['OS_ARCH'] == 'SunOS':
if CONFIG['FFI_TARGET'] == 'ARM':
DEFINES['EH_FRAME_FLAGS'] = '"aw"'
elif CONFIG['FFI_TARGET'] == 'X86' and CONFIG['OS_TARGET'] == 'SunOS':
DEFINES['EH_FRAME_FLAGS'] = '"aw"'
else:
DEFINES['EH_FRAME_FLAGS'] = '"a"'

1
config/external/nspr/pr/moz.build vendored

@ -62,6 +62,7 @@ elif CONFIG['OS_TARGET'] == 'SunOS':
SOURCES += ['/nsprpub/pr/src/md/unix/solaris.c']
if CONFIG['CPU_ARCH'] == 'x86_64':
SOURCES += ['/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s']
DEFINES['USE_64'] = True
elif CONFIG['CPU_ARCH'] == 'x86':
SOURCES += ['/nsprpub/pr/src/md/unix/os_SunOS_x86.s']
elif CONFIG['OS_TARGET'] == 'WINNT':

2
ipc/chromium/src/base/message_pump_libevent.cc

@ -24,7 +24,7 @@
#include "mozilla/UniquePtr.h"
// This macro checks that the _EVENT_SIZEOF_* constants defined in
// ipc/chromiume/src/third_party/<platform>/event2/event-config.h are correct.
// ipc/chromium/src/third_party/<platform>/event2/event-config.h are correct.
#if defined(_EVENT_SIZEOF_SHORT)
#define CHECK_EVENT_SIZEOF(TYPE, type) \
static_assert(_EVENT_SIZEOF_##TYPE == sizeof(type), \

4
ipc/chromium/src/third_party/libevent/solaris/event2/event-config.h vendored

@ -417,11 +417,7 @@
#define _EVENT_SIZEOF_LONG_LONG 8
/* The size of `pthread_t', as computed by sizeof. */
#ifdef __LP64__
#define _EVENT_SIZEOF_PTHREAD_T 8
#else
#define _EVENT_SIZEOF_PTHREAD_T 4
#endif
/* The size of `short', as computed by sizeof. */
#define _EVENT_SIZEOF_SHORT 2

11
js/src/gc/Memory.cpp

@ -415,8 +415,15 @@ InitMemorySubsystem()
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)
// Solaris manages 64-bit address space in a different manner from every other
// AMD64 operating system, but fortunately the fix is the same one
// required for every operating system on 64-bit SPARC, Itanium, and ARM.
// Most people's intuition failed them here and they thought this couldn't
// possibly be correct on AMD64, but for Solaris/illumos it is.
{
#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__)) || defined(__aarch64__)
#if defined(__ia64__) || (defined(__sparc64__) && defined(__NetBSD__)) || defined(__aarch64__) || (defined(__sun) && defined(__x86_64__))
MOZ_ASSERT((0xffff800000000000ULL & (uintptr_t(desired) + length - 1)) == 0);
#endif
void* region = mmap(desired, length, prot, flags, fd, offset);
@ -466,7 +473,7 @@ MapMemory(size_t length, int prot = PROT_READ | PROT_WRITE,
return nullptr;
}
return region;
#elif defined(__aarch64__)
#elif defined(__aarch64__) || (defined(__sun) && defined(__x86_64__))
/*
* There might be similar virtual address issue on arm64 which depends on
* hardware and kernel configurations. But the work around is slightly

2
xpcom/reflect/xptcall/md/unix/moz.build

@ -53,7 +53,7 @@ if CONFIG['OS_ARCH'] == 'SunOS':
if CONFIG['OS_TEST'] == 'x86_64':
SOURCES += [
'xptcinvoke_asm_x86_64_unix.S',
'xptcinvoke_x86_64_unix.cpp',
'xptcinvoke_x86_64_solaris.cpp',
'xptcstubs_x86_64_linux.cpp'
]
elif '86' in CONFIG['OS_TEST']:

75
xpcom/reflect/xptcall/md/unix/xptcinvoke_x86_64_solaris.cpp

@ -0,0 +1,75 @@
/* -*- 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"
// 6 integral parameters are passed in registers, but 1 is |this| which isn't
// considered here.
const uint32_t GPR_COUNT = 5;
// 8 floating point parameters are passed in SSE registers
const uint32_t FPR_COUNT = 8;
extern "C" void
InvokeCopyToStack(uint64_t * gpregs, double * fpregs,
uint32_t paramCount, nsXPTCVariant * s,
uint64_t* d)
{
uint32_t nr_gpr = 0u; // skip one GP register for 'that'
uint32_t nr_fpr = 0u;
uint64_t value = 0u;
for (uint32_t i = 0; i < paramCount; i++, s++) {
if (s->IsPtrData())
value = (uint64_t) s->ptr;
else {
switch (s->type) {
case nsXPTType::T_FLOAT: break;
case nsXPTType::T_DOUBLE: break;
case nsXPTType::T_I8: value = s->val.i8; break;
case nsXPTType::T_I16: value = s->val.i16; break;
case nsXPTType::T_I32: value = s->val.i32; break;
case nsXPTType::T_I64: value = s->val.i64; break;
case nsXPTType::T_U8: value = s->val.u8; break;
case nsXPTType::T_U16: value = s->val.u16; break;
case nsXPTType::T_U32: value = s->val.u32; break;
case nsXPTType::T_U64: value = s->val.u64; break;
case nsXPTType::T_BOOL: value = s->val.b; break;
case nsXPTType::T_CHAR: value = s->val.c; break;
case nsXPTType::T_WCHAR: value = s->val.wc; break;
default: value = (uint64_t) s->val.p; break;
}
}
if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) {
if (nr_fpr < FPR_COUNT)
fpregs[nr_fpr++] = s->val.d;
else {
*((double *)d) = s->val.d;
d++;
}
}
else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) {
if (nr_fpr < FPR_COUNT)
// The value in %xmm register is already prepared to
// be retrieved as a float. Therefore, we pass the
// value verbatim, as a double without conversion.
fpregs[nr_fpr++] = s->val.d;
else {
*((float *)d) = s->val.f;
d++;
}
}
else {
if (nr_gpr < GPR_COUNT)
gpregs[nr_gpr++] = value;
else
*d++ = value;
}
}
}

9
xpcom/string/nsTSubstring.h

@ -9,7 +9,12 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/IntegerTypeTraits.h"
#include "mozilla/Span.h"
#ifdef XP_SOLARIS
// Solaris defines pid_t to be long on ILP32 and int on LP64. I checked in
// sys/types.h. AMD64 and SPARC64 builds don't need this fix at all,
// while all 32-bit builds do.
#if defined(XP_SOLARIS) && !defined(__LP64__)
#include <unistd.h>
#endif
@ -590,7 +595,7 @@ public:
const char* fmt = aRadix == 10 ? "%d" : aRadix == 8 ? "%o" : "%x";
AppendPrintf(fmt, aInteger);
}
#ifdef XP_SOLARIS
#if defined(XP_SOLARIS) && !defined(__LP64__)
void AppendInt(pid_t aInteger)
{
AppendPrintf("%lu", aInteger);

Loading…
Cancel
Save