config/external/ffi/moz.build
author Nathan Froyd <froydnj@mozilla.com>
Thu, 27 Jun 2019 13:36:48 +0000
changeset 480349 dcae89181bb2f880af70b17048a56230406fa5f4
parent 460147 4767ef1dd263b316bfe7926b420dec4e5f64d5f2
permissions -rw-r--r--
Bug 1561088 - emit unwind information for libffi aarch64/win assembly; r=dmajor,gsvelto The hand-written assembly for libffi on aarch64/windows doesn't emit unwind information. If we ever tried to unwind through these functions, they'd look like leaf functions, which is decidedly not true and would cause great pain. For whatever reason, the original aarch64 libffi functions used x21/x22/x23/x24 as their (callee-saved) scratch registers. This convention works on windows as well, but the unwind information on windows mandates that we start saving callee-saved registers starting from x19, rather than x21. Rather than rewriting the assembly to use x19/x20 instead of x21/x22, which would be a large change, we chose instead to simply save/restore extra registers in the prolog/epilog. This change does make the stack frame sizes slightly bigger, but an extra 16 bytes in libffi stack frames should not matter. The `-TC` change is necessary to make the compiler play nicely with .asm file suffixes. Differential Revision: https://phabricator.services.mozilla.com/D35714

# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.

FINAL_LIBRARY = 'js'

if CONFIG['MOZ_SYSTEM_FFI']:
    OS_LIBS += CONFIG['MOZ_FFI_LIBS']
else:
    AllowCompilerWarnings()
    NoVisibilityFlags()

    CONFIGURE_DEFINE_FILES += [
        '../../../js/src/ctypes/libffi/fficonfig.h',
    ]
    GENERATED_FILES += [
        '../../../js/src/ctypes/libffi/include/ffi.h',
    ]
    ffi_h = GENERATED_FILES['../../../js/src/ctypes/libffi/include/ffi.h']
    ffi_h.script = 'subst_header.py'
    ffi_h.inputs = ['../../../js/src/ctypes/libffi/include/ffi.h.in']

    LOCAL_INCLUDES += [
        '!/js/src/ctypes/libffi',
        '!/js/src/ctypes/libffi/include',
        '/js/src/ctypes/libffi/include',
        '/js/src/ctypes/libffi/src/%s' % CONFIG['FFI_TARGET_DIR'],
    ]

    DEFINES.update({
        'TARGET': CONFIG['FFI_TARGET'],
        CONFIG['FFI_TARGET']: True,
        'FFI_NO_RAW_API': True,
        'HAVE_AS_ASCII_PSEUDO_OP': True,
        'HAVE_AS_STRING_PSEUDO_OP': True,
        'HAVE_AS_X86_64_UNWIND_SECTION_TYPE': True,
    })

    if CONFIG['MOZ_DEBUG']:
        DEFINES['FFI_DEBUG'] = True
        if not CONFIG['MOZ_NO_DEBUG_RTL']:
            DEFINES['USE_DEBUG_RTL'] = True
        SOURCES += [
            '/js/src/ctypes/libffi/src/debug.c',
        ]

    if CONFIG['OS_TARGET'] not in ('WINNT', 'Darwin'):
        DEFINES['HAVE_HIDDEN_VISIBILITY_ATTRIBUTE'] = True

    if CONFIG['INTEL_ARCHITECTURE']:
        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':
        if CONFIG['FFI_TARGET'] == 'ARM':
            DEFINES['EH_FRAME_FLAGS'] = '"aw"'
        else:
            DEFINES['EH_FRAME_FLAGS'] = '"a"'

    # Common source files.
    SOURCES += [
        '/js/src/ctypes/libffi/src/closures.c',
        '/js/src/ctypes/libffi/src/java_raw_api.c',
        '/js/src/ctypes/libffi/src/prep_cif.c',
        '/js/src/ctypes/libffi/src/raw_api.c',
        '/js/src/ctypes/libffi/src/types.c',
    ]

    # Per-platform sources and flags.
    ffi_srcs = ()
    if CONFIG['FFI_TARGET'] == 'ARM':
        ffi_srcs = ('sysv.S', 'ffi.c')
        if CONFIG['CC_TYPE'] == 'clang':
            ASFLAGS += ['-no-integrated-as']
    elif CONFIG['FFI_TARGET'] == 'AARCH64':
        ffi_srcs = ('sysv.S', 'ffi.c')
    elif CONFIG['FFI_TARGET'] == 'ARM64_WIN64':
        ffi_srcs = ['ffi.c']

        GENERATED_FILES += ['win64_aarch.asm']
        asm = GENERATED_FILES['win64_aarch.asm']
        asm.inputs = [
            '/js/src/ctypes/libffi/src/aarch64/win64.asm',
            '!../../../js/src/ctypes/libffi/fficonfig.h',
            '!../../../js/src/ctypes/libffi/include/ffi.h',
        ]
        asm.script = 'preprocess_libffi_asm.py'
        asm.flags = ['$(DEFINES)', '$(LOCAL_INCLUDES)']
        SOURCES += ['!win64_aarch.asm']
    elif CONFIG['FFI_TARGET'] == 'X86':
        ffi_srcs = ('ffi.c', 'sysv.S', 'win32.S')
    elif CONFIG['FFI_TARGET'] == 'X86_64':
        ffi_srcs = ('ffi64.c', 'unix64.S', 'ffi.c', 'sysv.S')
    elif CONFIG['FFI_TARGET'] == 'X86_WIN32':
        ffi_srcs = ['ffi.c']
        # MinGW Build for 32 bit
        if CONFIG['CC_TYPE'] in ('gcc', 'clang'):
            DEFINES['SYMBOL_UNDERSCORE'] = True
            ffi_srcs += ['win32.S']
        else:
            # libffi asm needs to be preprocessed for MSVC
            GENERATED_FILES += ['win32.asm']
            asm = GENERATED_FILES['win32.asm']
            asm.inputs = [
                '/js/src/ctypes/libffi/src/x86/win32.S',
                '!../../../js/src/ctypes/libffi/fficonfig.h',
                '!../../../js/src/ctypes/libffi/include/ffi.h',
            ]
            asm.script = 'preprocess_libffi_asm.py'
            asm.flags = ['$(DEFINES)', '$(LOCAL_INCLUDES)']
            SOURCES += ['!win32.asm']
            ASFLAGS += ['-safeseh']
    elif CONFIG['FFI_TARGET'] == 'X86_WIN64':
        ffi_srcs = ['ffi.c']
        if CONFIG['CC_TYPE'] in ('gcc', 'clang'):
            ffi_srcs += ['win64.S']
        else:
            # libffi asm needs to be preprocessed for MSVC
            GENERATED_FILES += ['win64.asm']
            asm = GENERATED_FILES['win64.asm']
            asm.inputs = [
                '/js/src/ctypes/libffi/src/x86/win64.S',
                '!../../../js/src/ctypes/libffi/fficonfig.h',
                '!../../../js/src/ctypes/libffi/include/ffi.h',
            ]
            asm.script = 'preprocess_libffi_asm.py'
            asm.flags = ['$(DEFINES)', '$(LOCAL_INCLUDES)']
            SOURCES += ['!win64.asm']
    elif CONFIG['FFI_TARGET'] == 'X86_DARWIN':
        DEFINES['FFI_MMAP_EXEC_WRIT'] = True
        if CONFIG['CPU_ARCH'] == 'x86':
            ffi_srcs = ('ffi.c', 'darwin.S', 'ffi64.c', 'darwin64.S',
                        'win32.S')
            DEFINES['SYMBOL_UNDERSCORE'] = True
        else:
            ffi_srcs = ('ffi.c', 'darwin.S', 'ffi64.c', 'darwin64.S')

    SOURCES += [
        '/js/src/ctypes/libffi/src/%s/%s' % (CONFIG['FFI_TARGET_DIR'], s)
        for s in sorted(ffi_srcs)
    ]