--- mozilla-esr38/configure.in +++ mozilla-esr38-uclibc/configure.in @@ -1781,7 +1781,11 @@ Android) ;; Linux) case "${CPU_ARCH}" in - x86 | x86_64) ;; + x86 | x86_64) + if test "${LIBC}" = "uclibc"; then + MOZ_ENABLE_PROFILER_SPS= + fi + ;; *) MOZ_ENABLE_PROFILER_SPS= esac --- mozilla-esr38/dom/system/OSFileConstants.cpp +++ mozilla-esr38-uclibc/dom/system/OSFileConstants.cpp @@ -18,7 +18,9 @@ #define statvfs statfs #else #include "sys/statvfs.h" +#if !defined(__UCLIBC__) #include +#endif // !defined(__UCLIBC__) #endif // defined(ANDROID) #endif // defined(XP_UNIX) @@ -588,7 +590,7 @@ static const dom::ConstantSpec gLibcProp // The size of |fsblkcnt_t|. { "OSFILE_SIZEOF_FSBLKCNT_T", INT_TO_JSVAL(sizeof (fsblkcnt_t)) }, -#if !defined(ANDROID) +#if !defined(ANDROID) && !defined(__UCLIBC__) // The size of |posix_spawn_file_actions_t|. { "OSFILE_SIZEOF_POSIX_SPAWN_FILE_ACTIONS_T", INT_TO_JSVAL(sizeof (posix_spawn_file_actions_t)) }, #endif // !defined(ANDROID) @@ -683,7 +683,10 @@ static const dom::ConstantSpec gLibcProp // Similar feature for Linux #if defined(_STAT_VER) +// There is no versioned stat system call on uclibc. _STAT_VER is fake +#if !defined(__UCLIBC__) INT_CONSTANT(_STAT_VER), +#endif #endif // defined(_STAT_VER) PROP_END --- mozilla-esr38/memory/mozalloc/mozalloc.cpp +++ mozilla-esr38-uclibc/memory/mozalloc/mozalloc.cpp @@ -28,7 +28,7 @@ #include "mozilla/mozalloc_oom.h" // for mozalloc_handle_oom /* Windows doesn't have malloc_usable_size, but jemalloc has */ -#if defined(MOZ_MEMORY_WINDOWS) +#if defined(MOZ_MEMORY_WINDOWS) || defined(__UCLIBC__) extern "C" size_t malloc_usable_size(const void *ptr); #endif @@ -206,7 +206,9 @@ moz_malloc_usable_size(void *ptr) if (!ptr) return 0; -#if defined(XP_MACOSX) +#if defined(__UCLIBC__) + return 0; +#elif defined(XP_MACOSX) return malloc_size(ptr); #elif defined(HAVE_MALLOC_USABLE_SIZE) || defined(MOZ_MEMORY) return malloc_usable_size(ptr); --- mozilla-esr38/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S +++ mozilla-esr38-uclibc/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext.S @@ -34,7 +34,7 @@ /* int getcontext (ucontext_t *ucp) */ -#ifdef __arm__ +#if defined(__arm__) .text .global breakpad_getcontext @@ -50,7 +50,7 @@ breakpad_getcontext: /* r12 is a scratch register, don't save it */ - /* Save sp and lr explicitely. */ + /* Save sp and lr explicitly. */ /* - sp can't be stored with stmia in Thumb-2 */ /* - STM instructions that store sp and pc are deprecated in ARM */ str sp, [r0, #(MCONTEXT_GREGS_OFFSET + 13*4)] @@ -59,7 +59,7 @@ breakpad_getcontext: /* Save the caller's address in 'pc' */ str lr, [r0, #(MCONTEXT_GREGS_OFFSET + 15*4)] - /* Save ucontext_t* pointer accross next call */ + /* Save ucontext_t* pointer across next call */ mov r4, r0 /* Call sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ @@ -88,6 +88,93 @@ breakpad_getcontext: .fnend .size breakpad_getcontext, . - breakpad_getcontext +#elif defined(__aarch64__) + +#define _NSIG 64 +#define __NR_rt_sigprocmask 135 + + .text + .global breakpad_getcontext + .hidden breakpad_getcontext + .type breakpad_getcontext, #function + .align 4 + .cfi_startproc +breakpad_getcontext: + + /* The saved context will return to the getcontext() call point + with a return value of 0 */ + str xzr, [x0, MCONTEXT_GREGS_OFFSET + 0 * REGISTER_SIZE] + + stp x18, x19, [x0, MCONTEXT_GREGS_OFFSET + 18 * REGISTER_SIZE] + stp x20, x21, [x0, MCONTEXT_GREGS_OFFSET + 20 * REGISTER_SIZE] + stp x22, x23, [x0, MCONTEXT_GREGS_OFFSET + 22 * REGISTER_SIZE] + stp x24, x25, [x0, MCONTEXT_GREGS_OFFSET + 24 * REGISTER_SIZE] + stp x26, x27, [x0, MCONTEXT_GREGS_OFFSET + 26 * REGISTER_SIZE] + stp x28, x29, [x0, MCONTEXT_GREGS_OFFSET + 28 * REGISTER_SIZE] + str x30, [x0, MCONTEXT_GREGS_OFFSET + 30 * REGISTER_SIZE] + + /* Place LR into the saved PC, this will ensure that when + switching to this saved context with setcontext() control + will pass back to the caller of getcontext(), we have + already arranged to return the appropriate return value in x0 + above. */ + str x30, [x0, MCONTEXT_PC_OFFSET] + + /* Save the current SP */ + mov x2, sp + str x2, [x0, MCONTEXT_SP_OFFSET] + + /* Initialize the pstate. */ + str xzr, [x0, MCONTEXT_PSTATE_OFFSET] + + /* Figure out where to place the first context extension + block. */ + add x2, x0, #MCONTEXT_EXTENSION_OFFSET + + /* Write the context extension fpsimd header. */ + mov w3, #(FPSIMD_MAGIC & 0xffff) + movk w3, #(FPSIMD_MAGIC >> 16), lsl #16 + str w3, [x2, #FPSIMD_CONTEXT_MAGIC_OFFSET] + mov w3, #FPSIMD_CONTEXT_SIZE + str w3, [x2, #FPSIMD_CONTEXT_SIZE_OFFSET] + + /* Fill in the FP SIMD context. */ + add x3, x2, #(FPSIMD_CONTEXT_VREGS_OFFSET + 8 * SIMD_REGISTER_SIZE) + stp d8, d9, [x3], #(2 * SIMD_REGISTER_SIZE) + stp d10, d11, [x3], #(2 * SIMD_REGISTER_SIZE) + stp d12, d13, [x3], #(2 * SIMD_REGISTER_SIZE) + stp d14, d15, [x3], #(2 * SIMD_REGISTER_SIZE) + + add x3, x2, FPSIMD_CONTEXT_FPSR_OFFSET + + mrs x4, fpsr + str w4, [x3] + + mrs x4, fpcr + str w4, [x3, FPSIMD_CONTEXT_FPCR_OFFSET - FPSIMD_CONTEXT_FPSR_OFFSET] + + /* Write the termination context extension header. */ + add x2, x2, #FPSIMD_CONTEXT_SIZE + + str xzr, [x2, #FPSIMD_CONTEXT_MAGIC_OFFSET] + str xzr, [x2, #FPSIMD_CONTEXT_SIZE_OFFSET] + + /* Grab the signal mask */ + /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ + add x2, x0, #UCONTEXT_SIGMASK_OFFSET + mov x0, #0 /* SIG_BLOCK */ + mov x1, #0 /* NULL */ + mov x3, #(_NSIG / 8) + mov x8, #__NR_rt_sigprocmask + svc 0 + + /* Return x0 for success */ + mov x0, 0 + ret + + .cfi_endproc + .size breakpad_getcontext, . - breakpad_getcontext + #elif defined(__i386__) .text @@ -140,6 +227,166 @@ breakpad_getcontext: .size breakpad_getcontext, . - breakpad_getcontext +#elif defined(__mips__) + +#if _MIPS_SIM != _ABIO32 +#error "Unsupported mips ISA. Only mips o32 is supported." +#endif + +// This implementation is inspired by implementation of getcontext in glibc. +#include +#include +#include +#include // for __NR_rt_sigprocmask + +#define _NSIG8 128 / 8 +#define SIG_BLOCK 1 + + + .text +LOCALS_NUM = 2 // save gp and ra on stack +FRAME_SIZE = ((LOCALS_NUM * SZREG) + ALSZ) & ALMASK +RA_FRAME_OFFSET = FRAME_SIZE - (1 * SZREG) +GP_FRAME_OFFSET = FRAME_SIZE - (2 * SZREG) +MCONTEXT_REG_SIZE = 8 + +NESTED (breakpad_getcontext, FRAME_SIZE, ra) + .mask 0x00000000, 0 + .fmask 0x00000000, 0 + + .set noreorder + .cpload t9 + .set reorder + + move a2, sp +#define _SP a2 + + addiu sp, -FRAME_SIZE + sw ra, RA_FRAME_OFFSET(sp) + sw gp, GP_FRAME_OFFSET(sp) + + sw s0, (16 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s1, (17 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s2, (18 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s3, (19 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s4, (20 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s5, (21 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s6, (22 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw s7, (23 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw _SP, (29 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw fp, (30 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw ra, (31 * MCONTEXT_REG_SIZE + MCONTEXT_GREGS_OFFSET)(a0) + sw ra, MCONTEXT_PC_OFFSET(a0) + +#ifdef __mips_hard_float + s.d fs0, (20 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs1, (22 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs2, (24 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs3, (26 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs4, (28 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + s.d fs5, (30 * MCONTEXT_REG_SIZE + MCONTEXT_FPREGS_OFFSET)(a0) + + cfc1 v1, fcr31 + sw v1, MCONTEXT_FPC_CSR(a0) +#endif // __mips_hard_float + + /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ + li a3, _NSIG8 + addu a2, a0, UCONTEXT_SIGMASK_OFFSET + move a1, zero + li a0, SIG_BLOCK + li v0, __NR_rt_sigprocmask + syscall + + lw ra, RA_FRAME_OFFSET(sp) + lw gp, GP_FRAME_OFFSET(sp) + addiu sp, FRAME_SIZE + jr ra + +END (breakpad_getcontext) + +#elif defined(__x86_64__) +/* The x64 implementation of breakpad_getcontext was derived in part + from the implementation of libunwind which requires the following + notice. */ +/* libunwind - a platform-independent unwind library + Copyright (C) 2008 Google, Inc + Contributed by Paul Pluzhnikov + Copyright (C) 2010 Konstantin Belousov + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + .text + .global breakpad_getcontext + /*.hidden breakpad_getcontext*/ + .align 4 + .type breakpad_getcontext, @function + +breakpad_getcontext: + .cfi_startproc + + /* Callee saved: RBX, RBP, R12-R15 */ + movq %r12, MCONTEXT_GREGS_R12(%rdi) + movq %r13, MCONTEXT_GREGS_R13(%rdi) + movq %r14, MCONTEXT_GREGS_R14(%rdi) + movq %r15, MCONTEXT_GREGS_R15(%rdi) + movq %rbp, MCONTEXT_GREGS_RBP(%rdi) + movq %rbx, MCONTEXT_GREGS_RBX(%rdi) + + /* Save argument registers (not strictly needed, but setcontext + restores them, so don't restore garbage). */ + movq %r8, MCONTEXT_GREGS_R8(%rdi) + movq %r9, MCONTEXT_GREGS_R9(%rdi) + movq %rdi, MCONTEXT_GREGS_RDI(%rdi) + movq %rsi, MCONTEXT_GREGS_RSI(%rdi) + movq %rdx, MCONTEXT_GREGS_RDX(%rdi) + movq %rax, MCONTEXT_GREGS_RAX(%rdi) + movq %rcx, MCONTEXT_GREGS_RCX(%rdi) + + /* Save fp state (not needed, except for setcontext not + restoring garbage). */ + leaq MCONTEXT_FPREGS_MEM(%rdi),%r8 + movq %r8, MCONTEXT_FPREGS_PTR(%rdi) + fnstenv (%r8) + stmxcsr FPREGS_OFFSET_MXCSR(%r8) + + leaq 8(%rsp), %rax /* exclude this call. */ + movq %rax, MCONTEXT_GREGS_RSP(%rdi) + + movq 0(%rsp), %rax + movq %rax, MCONTEXT_GREGS_RIP(%rdi) + + /* Save signal mask: sigprocmask(SIGBLOCK, NULL, &uc->uc_sigmask) */ + leaq UCONTEXT_SIGMASK_OFFSET(%rdi), %rdx // arg3 + xorq %rsi, %rsi // arg2 NULL + xorq %rdi, %rdi // arg1 SIGBLOCK == 0 + call sigprocmask@PLT + + /* Always return 0 for success, even if sigprocmask failed. */ + xorl %eax, %eax + ret + .cfi_endproc + .size breakpad_getcontext, . - breakpad_getcontext + #else #error "This file has not been ported for your CPU!" #endif --- mozilla-esr38/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext_unittest.cc +++ mozilla-esr38-uclibc/toolkit/crashreporter/google-breakpad/src/common/android/breakpad_getcontext_unittest.cc @@ -27,17 +27,45 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#if defined(__x86_64__) +#include +#endif + #include #include "breakpad_googletest_includes.h" #include "common/android/ucontext_constants.h" +template +struct CompileAssertEquals { + // a compilation error here indicates left and right are not equal. + char left_too_large[right - left]; + // a compilation error here indicates left and right are not equal. + char right_too_large[left - right]; +}; + +#define COMPILE_ASSERT_EQ(left, right, tag) \ + CompileAssertEquals tag; + TEST(AndroidUContext, GRegsOffset) { -#ifdef __arm__ +#if defined(__arm__) // There is no gregs[] array on ARM, so compare to the offset of // first register fields, since they're stored in order. ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), offsetof(ucontext_t,uc_mcontext.arm_r0)); +#elif defined(__aarch64__) + // There is no gregs[] array on ARM, so compare to the offset of + // first register fields, since they're stored in order. + ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), + offsetof(ucontext_t,uc_mcontext.regs[0])); + ASSERT_EQ(static_cast(MCONTEXT_SP_OFFSET), + offsetof(ucontext_t,uc_mcontext.sp)); + ASSERT_EQ(static_cast(MCONTEXT_PC_OFFSET), + offsetof(ucontext_t,uc_mcontext.pc)); + ASSERT_EQ(static_cast(MCONTEXT_PSTATE_OFFSET), + offsetof(ucontext_t,uc_mcontext.pstate)); + ASSERT_EQ(static_cast(MCONTEXT_EXTENSION_OFFSET), + offsetof(ucontext_t,uc_mcontext.__reserved)); #elif defined(__i386__) ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), offsetof(ucontext_t,uc_mcontext.gregs)); @@ -69,6 +97,83 @@ TEST(AndroidUContext, GRegsOffset) { ASSERT_EQ(static_cast(UCONTEXT_FPREGS_MEM_OFFSET), offsetof(ucontext_t,__fpregs_mem)); +#elif defined(__mips__) + ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), + offsetof(ucontext_t,uc_mcontext.gregs)); + + // PC for mips is not part of gregs. + ASSERT_EQ(static_cast(MCONTEXT_PC_OFFSET), + offsetof(ucontext_t,uc_mcontext.pc)); + + ASSERT_EQ(static_cast(MCONTEXT_FPREGS_OFFSET), + offsetof(ucontext_t,uc_mcontext.fpregs)); + + ASSERT_EQ(static_cast(MCONTEXT_FPC_CSR), + offsetof(ucontext_t,uc_mcontext.fpc_csr)); +#elif defined(__x86_64__) + + COMPILE_ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), + offsetof(ucontext_t,uc_mcontext.gregs), + mcontext_gregs_offset); +#define CHECK_REG(x) \ + COMPILE_ASSERT_EQ(static_cast(MCONTEXT_GREGS_##x), \ + offsetof(ucontext_t,uc_mcontext.gregs[REG_##x]), reg_##x) + CHECK_REG(R8); + CHECK_REG(R9); + CHECK_REG(R10); + CHECK_REG(R11); + CHECK_REG(R12); + CHECK_REG(R13); + CHECK_REG(R14); + CHECK_REG(R15); + CHECK_REG(RDI); + CHECK_REG(RSI); + CHECK_REG(RBP); + CHECK_REG(RBX); + CHECK_REG(RDX); + CHECK_REG(RAX); + CHECK_REG(RCX); + CHECK_REG(RSP); + CHECK_REG(RIP); + + // sigcontext is an analog to mcontext_t. The layout should be the same. + COMPILE_ASSERT_EQ(offsetof(mcontext_t,fpregs), + offsetof(sigcontext,fpstate), sigcontext_fpstate); + // Check that _fpstate from asm/sigcontext.h is essentially the same + // as _libc_fpstate. + COMPILE_ASSERT_EQ(sizeof(_libc_fpstate), sizeof(_fpstate), + sigcontext_fpstate_size); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,cwd),offsetof(_fpstate,cwd), + sigcontext_fpstate_cwd); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,swd),offsetof(_fpstate,swd), + sigcontext_fpstate_swd); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,ftw),offsetof(_fpstate,twd), + sigcontext_fpstate_twd); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,fop),offsetof(_fpstate,fop), + sigcontext_fpstate_fop); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,rip),offsetof(_fpstate,rip), + sigcontext_fpstate_rip); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,rdp),offsetof(_fpstate,rdp), + sigcontext_fpstate_rdp); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,mxcsr),offsetof(_fpstate,mxcsr), + sigcontext_fpstate_mxcsr); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,mxcr_mask), + offsetof(_fpstate,mxcsr_mask), + sigcontext_fpstate_mxcsr_mask); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,_st), offsetof(_fpstate,st_space), + sigcontext_fpstate_stspace); + COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,_xmm), offsetof(_fpstate,xmm_space), + sigcontext_fpstate_xmm_space); + + COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_PTR, + offsetof(ucontext_t,uc_mcontext.fpregs), + mcontext_fpregs_ptr); + COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_MEM, offsetof(ucontext_t,__fpregs_mem), + mcontext_fpregs_mem); + COMPILE_ASSERT_EQ(FPREGS_OFFSET_MXCSR, offsetof(_libc_fpstate,mxcsr), + fpregs_offset_mxcsr); + COMPILE_ASSERT_EQ(UCONTEXT_SIGMASK_OFFSET, offsetof(ucontext_t, uc_sigmask), + ucontext_sigmask); #else ASSERT_EQ(static_cast(MCONTEXT_GREGS_OFFSET), offsetof(ucontext_t,uc_mcontext.gregs)); --- mozilla-esr38/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/ucontext.h +++ mozilla-esr38-uclibc/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/ucontext.h @@ -62,6 +62,20 @@ typedef struct ucontext { // Other fields are not used by Google Breakpad. Don't define them. } ucontext_t; +#elif defined(__aarch64__) + +#include +typedef struct sigcontext mcontext_t; + +typedef struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + sigset_t uc_sigmask; + char __padding[128 - sizeof(sigset_t)]; + mcontext_t uc_mcontext; +} ucontext_t; + #elif defined(__i386__) /* 80-bit floating-point register */ @@ -128,7 +142,6 @@ typedef struct ucontext { #elif defined(__mips__) -// Not supported by Google Breakpad at this point, but just in case. typedef struct { uint32_t regmask; uint32_t status; @@ -162,6 +175,73 @@ typedef struct ucontext { // Other fields are not used by Google Breakpad. Don't define them. } ucontext_t; +#elif defined(__x86_64__) +enum { + REG_R8 = 0, + REG_R9, + REG_R10, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15, + REG_RDI, + REG_RSI, + REG_RBP, + REG_RBX, + REG_RDX, + REG_RAX, + REG_RCX, + REG_RSP, + REG_RIP, + REG_EFL, + REG_CSGSFS, + REG_ERR, + REG_TRAPNO, + REG_OLDMASK, + REG_CR2, + NGREG +}; + +// This struct is essentially the same as _fpstate in asm/sigcontext.h +// except that the individual field names are chosen here to match the +// ones used in breakpad for other x86_64 platforms. +struct _libc_fpstate { + /* 64-bit FXSAVE format. */ + uint16_t cwd; + uint16_t swd; + uint16_t ftw; + uint16_t fop; + uint64_t rip; + uint64_t rdp; + uint32_t mxcsr; + uint32_t mxcr_mask; + uint32_t _st[32]; // 128 bytes for the ST/MM registers 0-7 + uint32_t _xmm[64]; // 256 bytes for the XMM registers 0-7 + uint32_t padding[24]; // 96 bytes +}; + +typedef long greg_t; +typedef greg_t gregset_t[NGREG]; + +typedef struct _libc_fpstate* fpregset_t; + +typedef struct { + gregset_t gregs; + fpregset_t fpregs; + uint64_t __reserved1[8]; +} mcontext_t; + +typedef struct ucontext { + unsigned long uc_flags; + struct ucontext* uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + sigset_t uc_sigmask; + uint64_t __padding[15]; + _libc_fpstate __fpregs_mem; +} ucontext_t; + #else # error "Unsupported Android CPU ABI!" #endif --- mozilla-esr38/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/user.h +++ mozilla-esr38-uclibc/toolkit/crashreporter/google-breakpad/src/common/android/include/sys/user.h @@ -75,6 +75,11 @@ struct user_vfpregs { unsigned long fpscr; }; +#elif defined(__aarch64__) + +// aarch64 does not have user_regs definitions in , instead +// use the definitions in , which we don't need to redefine here. + #elif defined(__i386__) #define _I386_USER_H 1 // Prevent conflicts @@ -120,8 +125,45 @@ struct user { #elif defined(__mips__) -// TODO: Provide some useful definitions here, once the rest of Breakpad -// requires them. +#define _ASM_USER_H 1 // Prevent conflicts + +struct user_regs_struct { + unsigned long long regs[32]; + unsigned long long lo; + unsigned long long hi; + unsigned long long epc; + unsigned long long badvaddr; + unsigned long long status; + unsigned long long cause; +}; + +struct user_fpregs_struct { + unsigned long long regs[32]; + unsigned int fpcsr; + unsigned int fir; +}; + +#elif defined(__x86_64__) +#include +#include_next + +// This struct is essentially the same as user_i387_struct in sys/user.h +// except that the struct name and individual field names are chosen here +// to match the ones used in breakpad for other x86_64 platforms. + +struct user_fpregs_struct { + __u16 cwd; + __u16 swd; + __u16 ftw; + __u16 fop; + __u64 rip; + __u64 rdp; + __u32 mxcsr; + __u32 mxcr_mask; + __u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + __u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */ + __u32 padding[24]; +}; #else # error "Unsupported Android CPU ABI" --- mozilla-esr38/toolkit/crashreporter/google-breakpad/src/common/android/ucontext_constants.h +++ mozilla-esr38-uclibc/toolkit/crashreporter/google-breakpad/src/common/android/ucontext_constants.h @@ -45,6 +45,28 @@ #define MCONTEXT_GREGS_OFFSET 32 #define UCONTEXT_SIGMASK_OFFSET 104 +#elif defined(__aarch64__) + +#define UCONTEXT_SIGMASK_OFFSET 40 + +#define MCONTEXT_GREGS_OFFSET 184 +#define MCONTEXT_SP_OFFSET 432 +#define MCONTEXT_PC_OFFSET 440 +#define MCONTEXT_PSTATE_OFFSET 448 +#define MCONTEXT_EXTENSION_OFFSET 464 + +#define FPSIMD_MAGIC 0x46508001 + +#define FPSIMD_CONTEXT_MAGIC_OFFSET 0 +#define FPSIMD_CONTEXT_SIZE_OFFSET 4 +#define FPSIMD_CONTEXT_FPSR_OFFSET 8 +#define FPSIMD_CONTEXT_FPCR_OFFSET 12 +#define FPSIMD_CONTEXT_VREGS_OFFSET 16 +#define FPSIMD_CONTEXT_SIZE 528 + +#define REGISTER_SIZE 8 +#define SIMD_REGISTER_SIZE 16 + #elif defined(__i386__) #define MCONTEXT_GREGS_OFFSET 20 @@ -75,8 +97,37 @@ #elif defined(__mips__) -#define MCONTEXT_GREGS_OFFSET 0 -#define UCONTEXT_SIGMASK_OFFSET 0 +#define MCONTEXT_PC_OFFSET 32 +#define MCONTEXT_GREGS_OFFSET 40 +#define MCONTEXT_FPREGS_OFFSET 296 +#define MCONTEXT_FPC_CSR 556 +#define UCONTEXT_SIGMASK_OFFSET 616 + +#elif defined(__x86_64__) + +#define MCONTEXT_GREGS_OFFSET 40 +#define UCONTEXT_SIGMASK_OFFSET 296 + +#define MCONTEXT_GREGS_R8 40 +#define MCONTEXT_GREGS_R9 48 +#define MCONTEXT_GREGS_R10 56 +#define MCONTEXT_GREGS_R11 64 +#define MCONTEXT_GREGS_R12 72 +#define MCONTEXT_GREGS_R13 80 +#define MCONTEXT_GREGS_R14 88 +#define MCONTEXT_GREGS_R15 96 +#define MCONTEXT_GREGS_RDI 104 +#define MCONTEXT_GREGS_RSI 112 +#define MCONTEXT_GREGS_RBP 120 +#define MCONTEXT_GREGS_RBX 128 +#define MCONTEXT_GREGS_RDX 136 +#define MCONTEXT_GREGS_RAX 144 +#define MCONTEXT_GREGS_RCX 152 +#define MCONTEXT_GREGS_RSP 160 +#define MCONTEXT_GREGS_RIP 168 +#define MCONTEXT_FPREGS_PTR 224 +#define MCONTEXT_FPREGS_MEM 424 +#define FPREGS_OFFSET_MXCSR 24 #else #error "This header has not been ported for your CPU" --- mozilla-esr38/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build +++ mozilla-esr38-uclibc/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build @@ -41,6 +41,12 @@ FINAL_LIBRARY = 'xul' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': DEFINES['ELFSIZE'] = 32 +if CONFIG['TARGET_OS'] == 'linux-uclibc': + if ['HAVE_64BIT_OS'] == '1': + DEFINES['ELFSIZE'] = 64 + else: + DEFINES['ELFSIZE'] = 32 + DEFINES['NO_STABS_SUPPORT'] = True LOCAL_INCLUDES += [ --- mozilla-esr38/toolkit/crashreporter/google-breakpad/src/common/moz.build +++ mozilla-esr38-uclibc/toolkit/crashreporter/google-breakpad/src/common/moz.build @@ -38,6 +38,8 @@ if CONFIG['OS_ARCH'] == 'Linux': if CONFIG['OS_TARGET'] == 'Android': pass +#elif CONFIG['TARGET_OS'] == 'linux-uclibc': +# pass else: if CONFIG['OS_TARGET'] != 'WINNT': UNIFIED_SOURCES += [ --- mozilla-esr38-orig/toolkit/crashreporter/google-breakpad/src/stab.h +++ mozilla-esr38/toolkit/crashreporter/google-breakpad/src/stab.h @@ -0,0 +1,71 @@ +/* $OpenBSD: stab.h,v 1.3 2003/06/02 19:34:12 millert Exp $ */ +/* $NetBSD: stab.h,v 1.4 1994/10/26 00:56:25 cgd Exp $ */ + +/*- + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)stab.h 5.2 (Berkeley) 4/4/91 + */ + +#ifndef _STAB_H_ +#define _STAB_H_ + +/* + * The following are symbols used by various debuggers and by the Pascal + * compiler. Each of them must have one (or more) of the bits defined by + * the N_STAB mask set. + */ + +#define N_GSYM 0x20 /* global symbol */ +#define N_FNAME 0x22 /* F77 function name */ +#define N_FUN 0x24 /* procedure name */ +#define N_STSYM 0x26 /* data segment variable */ +#define N_LCSYM 0x28 /* bss segment variable */ +#define N_MAIN 0x2a /* main function name */ +#define N_PC 0x30 /* global Pascal symbol */ +#define N_RSYM 0x40 /* register variable */ +#define N_SLINE 0x44 /* text segment line number */ +#define N_DSLINE 0x46 /* data segment line number */ +#define N_BSLINE 0x48 /* bss segment line number */ +#define N_SSYM 0x60 /* structure/union element */ +#define N_SO 0x64 /* main source file name */ +#define N_LSYM 0x80 /* stack variable */ +#define N_BINCL 0x82 /* include file beginning */ +#define N_SOL 0x84 /* included source file name */ +#define N_PSYM 0xa0 /* parameter variable */ +#define N_EINCL 0xa2 /* include file end */ +#define N_ENTRY 0xa4 /* alternate entry point */ +#define N_LBRAC 0xc0 /* left bracket */ +#define N_EXCL 0xc2 /* deleted include file */ +#define N_RBRAC 0xe0 /* right bracket */ +#define N_BCOMM 0xe2 /* begin common */ +#define N_ECOMM 0xe4 /* end common */ +#define N_ECOML 0xe8 /* end common (local name) */ +#define N_LENG 0xfe /* length of preceding entry */ + +#endif /* !_STAB_H_ */ --- mozilla-esr38/tools/profiler/LulElfInt.h +++ mozilla-esr38-uclibc/tools/profiler/LulElfInt.h @@ -55,7 +55,7 @@ // elfutils.h: Utilities for dealing with ELF files. // -#if defined(LUL_OS_android) +#if defined(LUL_OS_android) || defined(__UCLIBC__) // From toolkit/crashreporter/google-breakpad/src/common/android/include/elf.h // The Android headers don't always define this constant. --- mozilla-esr38/tools/profiler/LulPlatformMacros.h +++ mozilla-esr38-uclibc/tools/profiler/LulPlatformMacros.h @@ -26,6 +26,14 @@ #undef LUL_OS_android #undef LUL_OS_linux +#ifndef ELFSIZE +# if defined(__x86_64__) +# define ELFSIZE 64 +# else +# define ELFSIZE 32 +# endif +#endif + #if defined(__linux__) && defined(__x86_64__) # define LUL_PLAT_x64_linux 1 # define LUL_ARCH_x64 1 --- mozilla-esr38/tools/profiler/moz.build +++ mozilla-esr38-uclibc/tools/profiler/moz.build @@ -62,6 +62,10 @@ if CONFIG['MOZ_ENABLE_PROFILER_SPS']: 'platform-linux.cc', 'shared-libraries-linux.cc', ] + if CONFIG['GNU_CXX']: + CXXFLAGS += [ + '-fPIC', + ] if CONFIG['CPU_ARCH'] == 'arm': UNIFIED_SOURCES += [ 'LulExidx.cpp', --- mozilla-esr38/tools/profiler/platform-linux.cc +++ mozilla-esr38-uclibc/tools/profiler/platform-linux.cc @@ -90,6 +90,10 @@ #include "ipc/Nuwa.h" #endif +#ifdef __UCLIBC__ +#include "common/android/include/ucontext.h" +#endif + #define SIGNAL_SAVE_PROFILE SIGUSR2 #if defined(__GLIBC__) @@ -652,10 +656,12 @@ void TickSample::PopulateContext(void* a { MOZ_ASSERT(aContext); ucontext_t* pContext = reinterpret_cast(aContext); +#ifndef __UCLIBC__ if (!getcontext(pContext)) { context = pContext; SetSampleContext(this, aContext); } +#endif } void OS::SleepMicro(int microseconds) --- mozilla-esr38/xpcom/ds/nsMathUtils.h +++ mozilla-esr38-uclibc/xpcom/ds/nsMathUtils.h @@ -104,7 +104,7 @@ NS_finite(double aNum) #ifdef WIN32 // NOTE: '!!' casts an int to bool without spamming MSVC warning C4800. return !!_finite(aNum); -#elif defined(XP_DARWIN) +#elif defined(XP_DARWIN) || defined(__UCLIBC__) // Darwin has deprecated |finite| and recommends |isfinite|. The former is // not present in the iOS SDK. return std::isfinite(aNum); --- mozilla-esr38/xpcom/io/nsLocalFileUnix.cpp +++ mozilla-esr38-uclibc/xpcom/io/nsLocalFileUnix.cpp @@ -1408,8 +1408,13 @@ nsLocalFile::GetDiskSpaceAvailable(int64 && dq.dqb_bhardlimit) { int64_t QuotaSpaceAvailable = 0; // dqb_bhardlimit is count of BLOCK_SIZE blocks, dqb_curspace is bytes +#ifdef __UCLIBC__ + if (dq.dqb_bhardlimit > dq.dqb_curblocks) + QuotaSpaceAvailable = int64_t(BLOCK_SIZE * (dq.dqb_bhardlimit - dq.dqb_curblocks)); +#else if ((BLOCK_SIZE * dq.dqb_bhardlimit) > dq.dqb_curspace) QuotaSpaceAvailable = int64_t(BLOCK_SIZE * dq.dqb_bhardlimit - dq.dqb_curspace); +#endif if (QuotaSpaceAvailable < *aDiskSpaceAvailable) { *aDiskSpaceAvailable = QuotaSpaceAvailable; }