зеркало из https://github.com/mozilla/gecko-dev.git
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 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
be0d5d0e09
Коммит
03e51146b9
|
@ -78,7 +78,18 @@ else:
|
|||
elif CONFIG['FFI_TARGET'] == 'AARCH64':
|
||||
ffi_srcs = ('sysv.S', 'ffi.c')
|
||||
elif CONFIG['FFI_TARGET'] == 'ARM64_WIN64':
|
||||
ffi_srcs = ('win64.asm', 'ffi.c')
|
||||
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':
|
||||
|
|
|
@ -15,7 +15,8 @@ def main(output, input_asm, ffi_h, ffi_config_h, defines, includes):
|
|||
defines = shlex.split(defines)
|
||||
includes = shlex.split(includes)
|
||||
# CPP uses -E which generates #line directives. -EP suppresses them.
|
||||
cpp = buildconfig.substs['CPP'] + ['-EP']
|
||||
# -TC forces the compiler to treat the input as C.
|
||||
cpp = buildconfig.substs['CPP'] + ['-EP'] + ['-TC']
|
||||
input_asm = mozpath.relpath(input_asm, os.getcwd())
|
||||
args = cpp + defines + includes + [input_asm]
|
||||
print(' '.join(args))
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "ksarm64.h"
|
||||
|
||||
;; Hand-converted from the sysv.S file in this directory.
|
||||
|
||||
AREA |.text|, CODE, ARM64
|
||||
TEXTAREA
|
||||
|
||||
;; ffi_call_SYSV()
|
||||
|
||||
|
@ -58,30 +60,26 @@
|
|||
;; This function uses the following stack frame layout:
|
||||
|
||||
;; ==
|
||||
;; saved x30(lr)
|
||||
;; x29(fp)-> saved x29(fp)
|
||||
;; saved x24
|
||||
;; saved x23
|
||||
;; saved x22
|
||||
;; sp' -> saved x21
|
||||
;; saved x21
|
||||
;; saved x20
|
||||
;; saved x19
|
||||
;; saved x30(lr)
|
||||
;; x29(fp)-> saved x29(fp)
|
||||
;; ...
|
||||
;; sp -> (constructed callee stack arguments)
|
||||
;; ==
|
||||
|
||||
;; Voila!
|
||||
|
||||
EXPORT |ffi_call_SYSV|
|
||||
NESTED_ENTRY |ffi_call_SYSV|
|
||||
|
||||
|ffi_call_SYSV| PROC
|
||||
;#define ffi_call_SYSV_FS (8 * 4)
|
||||
|
||||
stp x29, x30, [sp, #-16]!
|
||||
|
||||
mov x29, sp
|
||||
sub sp, sp, #32 ; ffi_call_SYSV_FS
|
||||
|
||||
stp x21, x22, [sp, #0]
|
||||
stp x23, x24, [sp, #16]
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-64!
|
||||
PROLOG_SAVE_REG_PAIR x19, x20, #16
|
||||
PROLOG_SAVE_REG_PAIR x21, x22, #32
|
||||
PROLOG_SAVE_REG_PAIR x23, x24, #48
|
||||
|
||||
mov x21, x1
|
||||
mov x22, x2
|
||||
|
@ -145,19 +143,14 @@ noload_call
|
|||
|
||||
nosave_call
|
||||
; All done, unwind our stack frame.
|
||||
ldp x21, x22, [x29, # - 32] ; ffi_call_SYSV_FS
|
||||
EPILOG_STACK_RESTORE
|
||||
EPILOG_RESTORE_REG_PAIR x19, x20, #16
|
||||
EPILOG_RESTORE_REG_PAIR x21, x22, #32
|
||||
EPILOG_RESTORE_REG_PAIR x23, x24, #48
|
||||
EPILOG_RESTORE_REG_PAIR x29, x30, #64!
|
||||
EPILOG_RETURN
|
||||
|
||||
ldp x23, x24, [x29, # - 32 + 16] ; ffi_call_SYSV_FS
|
||||
|
||||
mov sp, x29
|
||||
|
||||
ldp x29, x30, [sp], #16
|
||||
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
; #define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE)
|
||||
NESTED_END |ffi_call_SYSV|
|
||||
|
||||
;; ffi_closure_SYSV
|
||||
|
||||
|
@ -186,10 +179,12 @@ nosave_call
|
|||
;; This function uses the following stack frame layout:
|
||||
|
||||
;; ==
|
||||
;; saved x30(lr)
|
||||
;; x29(fp)-> saved x29(fp)
|
||||
;; saved x22
|
||||
;; saved x21
|
||||
;; saved x20
|
||||
;; saved x19
|
||||
;; saved x30(lr)
|
||||
;; x29(fp)-> saved x29(fp)
|
||||
;; ...
|
||||
;; sp -> call_context
|
||||
;; ==
|
||||
|
@ -197,16 +192,14 @@ nosave_call
|
|||
;; Voila!
|
||||
|
||||
IMPORT |ffi_closure_SYSV_inner|
|
||||
EXPORT |ffi_closure_SYSV|
|
||||
|
||||
|ffi_closure_SYSV| PROC
|
||||
stp x29, x30, [sp, #-16]!
|
||||
NESTED_ENTRY |ffi_closure_SYSV|
|
||||
|
||||
mov x29, sp
|
||||
PROLOG_SAVE_REG_PAIR fp, lr, #-48!
|
||||
PROLOG_SAVE_REG_PAIR x19, x20, #16
|
||||
PROLOG_SAVE_REG_PAIR x21, x22, #32
|
||||
|
||||
sub sp, sp, #256+512+16
|
||||
|
||||
stp x21, x22, [x29, #-16]
|
||||
sub sp, sp, #256+512
|
||||
|
||||
; Load x21 with &call_context.
|
||||
mov x21, sp
|
||||
|
@ -260,13 +253,12 @@ noload_closure
|
|||
; Note nothing useful is returned in x8.
|
||||
|
||||
; We are done, unwind our frame.
|
||||
ldp x21, x22, [x29, #-16]
|
||||
EPILOG_STACK_RESTORE
|
||||
EPILOG_RESTORE_REG_PAIR x19, x20, #16
|
||||
EPILOG_RESTORE_REG_PAIR x21, x22, #32
|
||||
EPILOG_RESTORE_REG_PAIR x29, x30, #48!
|
||||
EPILOG_RETURN
|
||||
|
||||
mov sp, x29
|
||||
NESTED_END |ffi_closure_SYSV|
|
||||
|
||||
ldp x29, x30, [sp], #16
|
||||
|
||||
ret
|
||||
|
||||
ENDP
|
||||
END
|
||||
END
|
||||
|
|
Загрузка…
Ссылка в новой задаче