From d92aaa970791472a1657e878bf686fe802943ebe Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 13 Oct 2017 13:52:57 -0700 Subject: [PATCH] runtime: unify arm entry point code Change-Id: Id51a2d63f7199b3ff71cedd415345ad20e5bd981 Reviewed-on: https://go-review.googlesource.com/70791 Reviewed-by: Austin Clements --- src/cmd/vet/all/whitelist/arm.txt | 3 - src/runtime/asm_arm.s | 102 +++++++++++++++++++++++++++++- src/runtime/rt0_android_arm.s | 5 +- src/runtime/rt0_darwin_arm.s | 94 ++------------------------- src/runtime/rt0_freebsd_arm.s | 13 ++-- src/runtime/rt0_linux_arm.s | 90 ++------------------------ src/runtime/rt0_nacl_arm.s | 4 -- src/runtime/rt0_netbsd_arm.s | 10 +-- src/runtime/rt0_openbsd_arm.s | 10 +-- src/runtime/rt0_plan9_arm.s | 2 - 10 files changed, 124 insertions(+), 209 deletions(-) diff --git a/src/cmd/vet/all/whitelist/arm.txt b/src/cmd/vet/all/whitelist/arm.txt index 3560afec7b..839346c2d4 100644 --- a/src/cmd/vet/all/whitelist/arm.txt +++ b/src/cmd/vet/all/whitelist/arm.txt @@ -18,7 +18,4 @@ runtime/tls_arm.s: [arm] save_g: function save_g missing Go declaration runtime/tls_arm.s: [arm] load_g: function load_g missing Go declaration runtime/tls_arm.s: [arm] _initcgo: function _initcgo missing Go declaration -// Clearer using FP than SP, but that requires named offsets. -runtime/asm_arm.s: [arm] rt0_go: use of 4(R13) points beyond argument frame - runtime/internal/atomic/asm_arm.s: [arm] cas: function cas missing Go declaration diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s index 9aea2a6e94..47fa565c52 100644 --- a/src/runtime/asm_arm.s +++ b/src/runtime/asm_arm.s @@ -7,14 +7,112 @@ #include "funcdata.h" #include "textflag.h" +// _rt0_arm is common startup code for most ARM systems when using +// internal linking. This is the entry point for the program from the +// kernel for an ordinary -buildmode=exe program. The stack holds the +// number of arguments and the C-style argv. +TEXT _rt0_arm(SB),NOSPLIT,$-4 + MOVW (R13), R0 // argc + MOVW $4(R13), R1 // argv + B runtime·rt0_go(SB) + +// main is common startup code for most ARM systems when using +// external linking. The C startup code will call the symbol "main" +// passing argc and argv in the usual C ABI registers R0 and R1. +TEXT main(SB),NOSPLIT,$-4 + B runtime·rt0_go(SB) + +// _rt0_arm_lib is common startup code for most ARM systems when +// using -buildmode=c-archive or -buildmode=c-shared. The linker will +// arrange to invoke this function as a global constructor (for +// c-archive) or when the shared library is loaded (for c-shared). +// We expect argc and argv to be passed in the usual C ABI registers +// R0 and R1. +TEXT _rt0_arm_lib(SB),NOSPLIT,$104 + // Preserve callee-save registers. Raspberry Pi's dlopen(), for example, + // actually cares that R11 is preserved. + MOVW R4, 12(R13) + MOVW R5, 16(R13) + MOVW R6, 20(R13) + MOVW R7, 24(R13) + MOVW R8, 28(R13) + MOVW R11, 32(R13) + + // Skip floating point registers on GOARM < 6. + MOVB runtime·goarm(SB), R11 + CMP $6, R11 + BLT skipfpsave + MOVD F8, (32+8*1)(R13) + MOVD F9, (32+8*2)(R13) + MOVD F10, (32+8*3)(R13) + MOVD F11, (32+8*4)(R13) + MOVD F12, (32+8*5)(R13) + MOVD F13, (32+8*6)(R13) + MOVD F14, (32+8*7)(R13) + MOVD F15, (32+8*8)(R13) +skipfpsave: + // Save argc/argv. + MOVW R0, _rt0_arm_lib_argc<>(SB) + MOVW R1, _rt0_arm_lib_argv<>(SB) + + // Synchronous initialization. + CALL runtime·libpreinit(SB) + + // Create a new thread to do the runtime initialization. + MOVW _cgo_sys_thread_create(SB), R2 + CMP $0, R2 + BEQ nocgo + MOVW $_rt0_arm_lib_go<>(SB), R0 + MOVW $0, R1 + BL (R2) + B rr +nocgo: + MOVW $0x800000, R0 // stacksize = 8192KB + MOVW $_rt0_arm_lib_go<>(SB), R1 // fn + MOVW R0, 4(R13) + MOVW R1, 8(R13) + BL runtime·newosproc0(SB) +rr: + // Restore callee-save registers and return. + MOVB runtime·goarm(SB), R11 + CMP $6, R11 + BLT skipfprest + MOVD (32+8*1)(R13), F8 + MOVD (32+8*2)(R13), F9 + MOVD (32+8*3)(R13), F10 + MOVD (32+8*4)(R13), F11 + MOVD (32+8*5)(R13), F12 + MOVD (32+8*6)(R13), F13 + MOVD (32+8*7)(R13), F14 + MOVD (32+8*8)(R13), F15 +skipfprest: + MOVW 12(R13), R4 + MOVW 16(R13), R5 + MOVW 20(R13), R6 + MOVW 24(R13), R7 + MOVW 28(R13), R8 + MOVW 32(R13), R11 + RET + +// _rt0_arm_lib_go initializes the Go runtime. +// This is started in a separate thread by _rt0_arm_lib. +TEXT _rt0_arm_lib_go<>(SB),NOSPLIT,$8 + MOVW _rt0_arm_lib_argc<>(SB), R0 + MOVW _rt0_arm_lib_argv<>(SB), R1 + B runtime·rt0_go(SB) + +DATA _rt0_arm_lib_argc<>(SB)/4,$0 +GLOBL _rt0_arm_lib_argc<>(SB),NOPTR,$4 +DATA _rt0_arm_lib_argv<>(SB)/4,$0 +GLOBL _rt0_arm_lib_argv<>(SB),NOPTR,$4 + // using frame size $-4 means do not save LR on stack. +// argc is in R0, argv is in R1. TEXT runtime·rt0_go(SB),NOSPLIT,$-4 MOVW $0xcafebabe, R12 // copy arguments forward on an even stack // use R13 instead of SP to avoid linker rewriting the offsets - MOVW 0(R13), R0 // argc - MOVW 4(R13), R1 // argv SUB $64, R13 // plenty of scratch AND $~7, R13 MOVW R0, 60(R13) // save argc, argv away diff --git a/src/runtime/rt0_android_arm.s b/src/runtime/rt0_android_arm.s index 189e290e35..1246238be0 100644 --- a/src/runtime/rt0_android_arm.s +++ b/src/runtime/rt0_android_arm.s @@ -10,13 +10,10 @@ TEXT _rt0_arm_android(SB),NOSPLIT,$-4 MOVW $_rt0_arm_linux1(SB), R4 B (R4) -// When building with -buildmode=c-shared, this symbol is called when the shared -// library is loaded. TEXT _rt0_arm_android_lib(SB),NOSPLIT,$0 MOVW $1, R0 // argc MOVW $_rt0_arm_android_argv(SB), R1 // **argv - BL _rt0_arm_linux_lib(SB) - RET + B _rt0_arm_lib(SB) DATA _rt0_arm_android_argv+0x00(SB)/4,$_rt0_arm_android_argv0(SB) DATA _rt0_arm_android_argv+0x04(SB)/4,$0 // end argv diff --git a/src/runtime/rt0_darwin_arm.s b/src/runtime/rt0_darwin_arm.s index 526d88f13d..71fbe5f68a 100644 --- a/src/runtime/rt0_darwin_arm.s +++ b/src/runtime/rt0_darwin_arm.s @@ -4,94 +4,8 @@ #include "textflag.h" -TEXT _rt0_arm_darwin(SB),7,$-4 - // prepare arguments for main (_rt0_go) - MOVW (R13), R0 // argc - MOVW $4(R13), R1 // argv - MOVW $main(SB), R4 - B (R4) +TEXT _rt0_arm_darwin(SB),7,$0 + B _rt0_asm(SB) -// When linking with -buildmode=c-archive or -buildmode=c-shared, -// this symbol is called from a global initialization function. -// -// Note that all currently shipping darwin/arm platforms require -// cgo and do not support c-shared. -TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$104 - // Preserve callee-save registers. - MOVW R4, 12(R13) - MOVW R5, 16(R13) - MOVW R6, 20(R13) - MOVW R7, 24(R13) - MOVW R8, 28(R13) - MOVW R11, 32(R13) - - MOVD F8, (32+8*1)(R13) - MOVD F9, (32+8*2)(R13) - MOVD F10, (32+8*3)(R13) - MOVD F11, (32+8*4)(R13) - MOVD F12, (32+8*5)(R13) - MOVD F13, (32+8*6)(R13) - MOVD F14, (32+8*7)(R13) - MOVD F15, (32+8*8)(R13) - - MOVW R0, _rt0_arm_darwin_lib_argc<>(SB) - MOVW R1, _rt0_arm_darwin_lib_argv<>(SB) - - // Synchronous initialization. - MOVW $runtime·libpreinit(SB), R3 - CALL (R3) - - // Create a new thread to do the runtime initialization and return. - MOVW _cgo_sys_thread_create(SB), R3 - CMP $0, R3 - B.EQ nocgo - MOVW $_rt0_arm_darwin_lib_go(SB), R0 - MOVW $0, R1 - BL (R3) - B rr -nocgo: - MOVW $0x400000, R0 - MOVW R0, (R13) // stacksize - MOVW $_rt0_arm_darwin_lib_go(SB), R0 - MOVW R0, 4(R13) // fn - MOVW $0, R0 - MOVW R0, 8(R13) // fnarg - MOVW $runtime·newosproc0(SB), R3 - BL (R3) -rr: - // Restore callee-save registers and return. - MOVW 12(R13), R4 - MOVW 16(R13), R5 - MOVW 20(R13), R6 - MOVW 24(R13), R7 - MOVW 28(R13), R8 - MOVW 32(R13), R11 - MOVD (32+8*1)(R13), F8 - MOVD (32+8*2)(R13), F9 - MOVD (32+8*3)(R13), F10 - MOVD (32+8*4)(R13), F11 - MOVD (32+8*5)(R13), F12 - MOVD (32+8*6)(R13), F13 - MOVD (32+8*7)(R13), F14 - MOVD (32+8*8)(R13), F15 - RET - - -TEXT _rt0_arm_darwin_lib_go(SB),NOSPLIT,$0 - MOVW _rt0_arm_darwin_lib_argc<>(SB), R0 - MOVW _rt0_arm_darwin_lib_argv<>(SB), R1 - MOVW R0, (R13) - MOVW R1, 4(R13) - MOVW $runtime·rt0_go(SB), R4 - B (R4) - -DATA _rt0_arm_darwin_lib_argc<>(SB)/4, $0 -GLOBL _rt0_arm_darwin_lib_argc<>(SB),NOPTR, $4 -DATA _rt0_arm_darwin_lib_argv<>(SB)/4, $0 -GLOBL _rt0_arm_darwin_lib_argv<>(SB),NOPTR, $4 - -TEXT main(SB),NOSPLIT,$-8 - // save argc and argv onto stack - MOVM.DB.W [R0-R1], (R13) - MOVW $runtime·rt0_go(SB), R4 - B (R4) +TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0 + B _rt0_arm_lib(SB) diff --git a/src/runtime/rt0_freebsd_arm.s b/src/runtime/rt0_freebsd_arm.s index e1bb13d53a..62ecd9aeb5 100644 --- a/src/runtime/rt0_freebsd_arm.s +++ b/src/runtime/rt0_freebsd_arm.s @@ -4,13 +4,8 @@ #include "textflag.h" -TEXT _rt0_arm_freebsd(SB),NOSPLIT,$-4 - MOVW (R13), R0 // argc - MOVW $4(R13), R1 // argv - MOVM.DB.W [R0-R1], (R13) - B runtime·rt0_go(SB) +TEXT _rt0_arm_freebsd(SB),NOSPLIT,$0 + B _rt0_arm(SB) -TEXT main(SB),NOSPLIT,$-4 - MOVM.DB.W [R0-R1], (R13) - MOVW $runtime·rt0_go(SB), R4 - B (R4) +TEXT _rt0_arm_freebsd_lib(SB),NOSPLIT,$0 + B _rt0_arm_lib(SB) diff --git a/src/runtime/rt0_linux_arm.s b/src/runtime/rt0_linux_arm.s index b56ec75071..ba4ca2b10a 100644 --- a/src/runtime/rt0_linux_arm.s +++ b/src/runtime/rt0_linux_arm.s @@ -12,84 +12,8 @@ TEXT _rt0_arm_linux(SB),NOSPLIT,$-4 // When building with -buildmode=c-shared, this symbol is called when the shared // library is loaded. -TEXT _rt0_arm_linux_lib(SB),NOSPLIT,$104 - // Preserve callee-save registers. Raspberry Pi's dlopen(), for example, - // actually cares that R11 is preserved. - MOVW R4, 12(R13) - MOVW R5, 16(R13) - MOVW R6, 20(R13) - MOVW R7, 24(R13) - MOVW R8, 28(R13) - MOVW R11, 32(R13) - - // Skip floating point registers on GOARM < 6. - MOVB runtime·goarm(SB), R11 - CMP $6, R11 - BLT skipfpsave - MOVD F8, (32+8*1)(R13) - MOVD F9, (32+8*2)(R13) - MOVD F10, (32+8*3)(R13) - MOVD F11, (32+8*4)(R13) - MOVD F12, (32+8*5)(R13) - MOVD F13, (32+8*6)(R13) - MOVD F14, (32+8*7)(R13) - MOVD F15, (32+8*8)(R13) -skipfpsave: - // Save argc/argv. - MOVW R0, _rt0_arm_linux_lib_argc<>(SB) - MOVW R1, _rt0_arm_linux_lib_argv<>(SB) - - // Synchronous initialization. - MOVW $runtime·libpreinit(SB), R2 - CALL (R2) - - // Create a new thread to do the runtime initialization. - MOVW _cgo_sys_thread_create(SB), R2 - CMP $0, R2 - BEQ nocgo - MOVW $_rt0_arm_linux_lib_go<>(SB), R0 - MOVW $0, R1 - BL (R2) - B rr -nocgo: - MOVW $0x800000, R0 // stacksize = 8192KB - MOVW $_rt0_arm_linux_lib_go<>(SB), R1 // fn - MOVW R0, 4(R13) - MOVW R1, 8(R13) - BL runtime·newosproc0(SB) -rr: - // Restore callee-save registers and return. - MOVB runtime·goarm(SB), R11 - CMP $6, R11 - BLT skipfprest - MOVD (32+8*1)(R13), F8 - MOVD (32+8*2)(R13), F9 - MOVD (32+8*3)(R13), F10 - MOVD (32+8*4)(R13), F11 - MOVD (32+8*5)(R13), F12 - MOVD (32+8*6)(R13), F13 - MOVD (32+8*7)(R13), F14 - MOVD (32+8*8)(R13), F15 -skipfprest: - MOVW 12(R13), R4 - MOVW 16(R13), R5 - MOVW 20(R13), R6 - MOVW 24(R13), R7 - MOVW 28(R13), R8 - MOVW 32(R13), R11 - RET - -TEXT _rt0_arm_linux_lib_go<>(SB),NOSPLIT,$8 - MOVW _rt0_arm_linux_lib_argc<>(SB), R0 - MOVW _rt0_arm_linux_lib_argv<>(SB), R1 - MOVW R0, 0(R13) - MOVW R1, 4(R13) - B runtime·rt0_go(SB) - -DATA _rt0_arm_linux_lib_argc<>(SB)/4,$0 -GLOBL _rt0_arm_linux_lib_argc<>(SB),NOPTR,$4 -DATA _rt0_arm_linux_lib_argv<>(SB)/4,$0 -GLOBL _rt0_arm_linux_lib_argv<>(SB),NOPTR,$4 +TEXT _rt0_arm_linux_lib(SB),NOSPLIT,$0 + B _rt0_arm_lib(SB) TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4 // We first need to detect the kernel ABI, and warn the user @@ -98,16 +22,12 @@ TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4 // SIGILL is received. // If you get a SIGILL here, you have the wrong kernel. - // Save argc and argv + // Save argc and argv (syscall will clobber at least R0). MOVM.DB.W [R0-R1], (R13) // do an EABI syscall MOVW $20, R7 // sys_getpid SWI $0 // this will trigger SIGILL on OABI systems - - B runtime·rt0_go(SB) - -TEXT main(SB),NOSPLIT,$-4 - MOVW $_rt0_arm_linux1(SB), R4 - B (R4) + MOVM.IA.W (R13), [R0-R1] + B runtime·rt0_go(SB) diff --git a/src/runtime/rt0_nacl_arm.s b/src/runtime/rt0_nacl_arm.s index eadb4782dd..2be8a0730f 100644 --- a/src/runtime/rt0_nacl_arm.s +++ b/src/runtime/rt0_nacl_arm.s @@ -13,8 +13,4 @@ TEXT _rt0_arm_nacl(SB),NOSPLIT,$-4 MOVW 8(R13), R0 MOVW $12(R13), R1 - MOVM.DB.W [R0-R1], (R13) - B main(SB) - -TEXT main(SB),NOSPLIT,$0 B runtime·rt0_go(SB) diff --git a/src/runtime/rt0_netbsd_arm.s b/src/runtime/rt0_netbsd_arm.s index 2cb1182c06..503c32adac 100644 --- a/src/runtime/rt0_netbsd_arm.s +++ b/src/runtime/rt0_netbsd_arm.s @@ -4,8 +4,8 @@ #include "textflag.h" -TEXT _rt0_arm_netbsd(SB),NOSPLIT,$-4 - MOVW (R13), R0 // argc - MOVW $4(R13), R1 // argv - MOVM.DB.W [R0-R1], (R13) - B runtime·rt0_go(SB) +TEXT _rt0_arm_netbsd(SB),NOSPLIT,$0 + B _rt0_arm(SB) + +TEXT _rt0_arm_netbsd_lib(SB),NOSPLIT,$0 + B _rt0_arm_lib(SB) diff --git a/src/runtime/rt0_openbsd_arm.s b/src/runtime/rt0_openbsd_arm.s index 6207e55982..3511c96abc 100644 --- a/src/runtime/rt0_openbsd_arm.s +++ b/src/runtime/rt0_openbsd_arm.s @@ -4,8 +4,8 @@ #include "textflag.h" -TEXT _rt0_arm_openbsd(SB),NOSPLIT,$-4 - MOVW (R13), R0 // argc - MOVW $4(R13), R1 // argv - MOVM.DB.W [R0-R1], (R13) - B runtime·rt0_go(SB) +TEXT _rt0_arm_openbsd(SB),NOSPLIT,$0 + B _rt0_arm(SB) + +TEXT _rt0_arm_openbsd_lib(SB),NOSPLIT,$0 + B _rt0_arm_lib(SB) diff --git a/src/runtime/rt0_plan9_arm.s b/src/runtime/rt0_plan9_arm.s index 2a35e4ef66..d6174a4df5 100644 --- a/src/runtime/rt0_plan9_arm.s +++ b/src/runtime/rt0_plan9_arm.s @@ -10,8 +10,6 @@ TEXT _rt0_arm_plan9(SB),NOSPLIT,$-4 MOVW R0, _tos(SB) MOVW 0(R13), R0 MOVW $4(R13), R1 - MOVW.W R1, -4(R13) - MOVW.W R0, -4(R13) B runtime·rt0_go(SB) GLOBL _tos(SB), NOPTR, $4 -- 2.48.1