github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/runtime/rt0_linux_arm.s (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "textflag.h" 6 7 TEXT _rt0_arm_linux(SB),NOSPLIT,$-4 8 MOVW (R13), R0 // argc 9 MOVW $4(R13), R1 // argv 10 MOVW $_rt0_arm_linux1(SB), R4 11 B (R4) 12 13 // When building with -buildmode=c-shared, this symbol is called when the shared 14 // library is loaded. 15 TEXT _rt0_arm_linux_lib(SB),NOSPLIT,$40 16 // Preserve callee-save registers. Raspberry Pi's dlopen(), for example, 17 // actually cares that R11 is preserved. 18 MOVW R4, 16(R13) 19 MOVW R5, 20(R13) 20 MOVW R6, 24(R13) 21 MOVW R7, 28(R13) 22 MOVW R8, 32(R13) 23 MOVW R11, 36(R13) 24 25 // Save argc/argv. 26 MOVW R0, _rt0_arm_linux_lib_argc<>(SB) 27 MOVW R1, _rt0_arm_linux_lib_argv<>(SB) 28 29 // Create a new thread to do the runtime initialization. 30 MOVW _cgo_sys_thread_create(SB), R2 31 CMP $0, R2 32 BEQ nocgo 33 MOVW $_rt0_arm_linux_lib_go<>(SB), R0 34 MOVW $0, R1 35 BL (R2) 36 B rr 37 nocgo: 38 MOVW $0x800000, R0 // stacksize = 8192KB 39 MOVW $_rt0_arm_linux_lib_go<>(SB), R1 // fn 40 MOVW $0, R2 // fnarg 41 MOVW R0, 4(R13) 42 MOVW R1, 8(R13) 43 MOVW R2, 12(R13) 44 BL runtime·newosproc0(SB) 45 rr: 46 // Restore callee-save registers and return. 47 MOVW 16(R13), R4 48 MOVW 20(R13), R5 49 MOVW 24(R13), R6 50 MOVW 28(R13), R7 51 MOVW 32(R13), R8 52 MOVW 36(R13), R11 53 RET 54 55 TEXT _rt0_arm_linux_lib_go<>(SB),NOSPLIT,$8 56 MOVW _rt0_arm_linux_lib_argc<>(SB), R0 57 MOVW _rt0_arm_linux_lib_argv<>(SB), R1 58 MOVW R0, 0(R13) 59 MOVW R1, 4(R13) 60 B runtime·rt0_go(SB) 61 62 DATA _rt0_arm_linux_lib_argc<>(SB)/4,$0 63 GLOBL _rt0_arm_linux_lib_argc<>(SB),NOPTR,$4 64 DATA _rt0_arm_linux_lib_argv<>(SB)/4,$0 65 GLOBL _rt0_arm_linux_lib_argv<>(SB),NOPTR,$4 66 67 TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4 68 // We first need to detect the kernel ABI, and warn the user 69 // if the system only supports OABI 70 // The strategy here is to call some EABI syscall to see if 71 // SIGILL is received. 72 // To catch SIGILL, we have to first setup sigaction, this is 73 // a chicken-and-egg problem, because we can't do syscall if 74 // we don't know the kernel ABI... Oh, not really, we can do 75 // syscall in Thumb mode. 76 77 // Save argc and argv 78 MOVM.DB.W [R0-R1], (R13) 79 80 // Thumb mode OABI check disabled because there are some 81 // EABI systems that do not support Thumb execution. 82 // We can run on them except for this check! 83 84 // // set up sa_handler 85 // MOVW $bad_abi<>(SB), R0 // sa_handler 86 // MOVW $0, R1 // sa_flags 87 // MOVW $0, R2 // sa_restorer 88 // MOVW $0, R3 // sa_mask 89 // MOVM.DB.W [R0-R3], (R13) 90 // MOVW $4, R0 // SIGILL 91 // MOVW R13, R1 // sa 92 // SUB $16, R13 93 // MOVW R13, R2 // old_sa 94 // MOVW $8, R3 // c 95 // MOVW $174, R7 // sys_sigaction 96 // BL oabi_syscall<>(SB) 97 98 // do an EABI syscall 99 MOVW $20, R7 // sys_getpid 100 SWI $0 // this will trigger SIGILL on OABI systems 101 102 // MOVW $4, R0 // SIGILL 103 // MOVW R13, R1 // sa 104 // MOVW $0, R2 // old_sa 105 // MOVW $8, R3 // c 106 // MOVW $174, R7 // sys_sigaction 107 // SWI $0 // restore signal handler 108 // ADD $32, R13 109 110 B runtime·rt0_go(SB) 111 112 TEXT bad_abi<>(SB),NOSPLIT,$-4 113 // give diagnosis and exit 114 MOVW $2, R0 // stderr 115 MOVW $bad_abi_msg(SB), R1 // data 116 MOVW $45, R2 // len 117 MOVW $4, R7 // sys_write 118 BL oabi_syscall<>(SB) 119 MOVW $1, R0 120 MOVW $1, R7 // sys_exit 121 BL oabi_syscall<>(SB) 122 B 0(PC) 123 124 DATA bad_abi_msg+0x00(SB)/8, $"This pro" 125 DATA bad_abi_msg+0x08(SB)/8, $"gram can" 126 DATA bad_abi_msg+0x10(SB)/8, $" only be" 127 DATA bad_abi_msg+0x18(SB)/8, $" run on " 128 DATA bad_abi_msg+0x20(SB)/8, $"EABI ker" 129 DATA bad_abi_msg+0x28(SB)/4, $"nels" 130 DATA bad_abi_msg+0x2c(SB)/1, $0xa 131 GLOBL bad_abi_msg(SB), RODATA, $45 132 133 TEXT oabi_syscall<>(SB),NOSPLIT,$-4 134 ADD $1, R15, R4 // R15 is hardware PC 135 WORD $0xe12fff14 //BX (R4) // enter thumb mode 136 // TODO(minux): only supports little-endian CPUs 137 WORD $0x4770df01 // swi $1; bx lr 138 139 TEXT main(SB),NOSPLIT,$-4 140 MOVW $_rt0_arm_linux1(SB), R4 141 B (R4) 142