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,$32 16 // Preserve callee-save registers. Raspberry Pi's dlopen(), for example, 17 // actually cares that R11 is preserved. 18 MOVW R4, 12(R13) 19 MOVW R5, 16(R13) 20 MOVW R6, 20(R13) 21 MOVW R7, 24(R13) 22 MOVW R8, 28(R13) 23 MOVW R11, 32(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 R0, 4(R13) 41 MOVW R1, 8(R13) 42 BL runtimenewosproc0(SB) 43 rr: 44 // Restore callee-save registers and return. 45 MOVW 12(R13), R4 46 MOVW 16(R13), R5 47 MOVW 20(R13), R6 48 MOVW 24(R13), R7 49 MOVW 28(R13), R8 50 MOVW 32(R13), R11 51 RET 52 53 TEXT _rt0_arm_linux_lib_go<>(SB),NOSPLIT,$8 54 MOVW _rt0_arm_linux_lib_argc<>(SB), R0 55 MOVW _rt0_arm_linux_lib_argv<>(SB), R1 56 MOVW R0, 0(R13) 57 MOVW R1, 4(R13) 58 B runtimert0_go(SB) 59 60 DATA _rt0_arm_linux_lib_argc<>(SB)/4,$0 61 GLOBL _rt0_arm_linux_lib_argc<>(SB),NOPTR,$4 62 DATA _rt0_arm_linux_lib_argv<>(SB)/4,$0 63 GLOBL _rt0_arm_linux_lib_argv<>(SB),NOPTR,$4 64 65 TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4 66 // We first need to detect the kernel ABI, and warn the user 67 // if the system only supports OABI 68 // The strategy here is to call some EABI syscall to see if 69 // SIGILL is received. 70 // To catch SIGILL, we have to first setup sigaction, this is 71 // a chicken-and-egg problem, because we can't do syscall if 72 // we don't know the kernel ABI... Oh, not really, we can do 73 // syscall in Thumb mode. 74 75 // Save argc and argv 76 MOVM.DB.W [R0-R1], (R13) 77 78 // Thumb mode OABI check disabled because there are some 79 // EABI systems that do not support Thumb execution. 80 // We can run on them except for this check! 81 82 // // set up sa_handler 83 // MOVW $bad_abi<>(SB), R0 // sa_handler 84 // MOVW $0, R1 // sa_flags 85 // MOVW $0, R2 // sa_restorer 86 // MOVW $0, R3 // sa_mask 87 // MOVM.DB.W [R0-R3], (R13) 88 // MOVW $4, R0 // SIGILL 89 // MOVW R13, R1 // sa 90 // SUB $16, R13 91 // MOVW R13, R2 // old_sa 92 // MOVW $8, R3 // c 93 // MOVW $174, R7 // sys_sigaction 94 // BL oabi_syscall<>(SB) 95 96 // do an EABI syscall 97 MOVW $20, R7 // sys_getpid 98 SWI $0 // this will trigger SIGILL on OABI systems 99 100 // MOVW $4, R0 // SIGILL 101 // MOVW R13, R1 // sa 102 // MOVW $0, R2 // old_sa 103 // MOVW $8, R3 // c 104 // MOVW $174, R7 // sys_sigaction 105 // SWI $0 // restore signal handler 106 // ADD $32, R13 107 108 B runtimert0_go(SB) 109 110 TEXT bad_abi<>(SB),NOSPLIT,$-4 111 // give diagnosis and exit 112 MOVW $2, R0 // stderr 113 MOVW $bad_abi_msg(SB), R1 // data 114 MOVW $45, R2 // len 115 MOVW $4, R7 // sys_write 116 BL oabi_syscall<>(SB) 117 MOVW $1, R0 118 MOVW $1, R7 // sys_exit 119 BL oabi_syscall<>(SB) 120 B 0(PC) 121 122 DATA bad_abi_msg+0x00(SB)/8, $"This pro" 123 DATA bad_abi_msg+0x08(SB)/8, $"gram can" 124 DATA bad_abi_msg+0x10(SB)/8, $" only be" 125 DATA bad_abi_msg+0x18(SB)/8, $" run on " 126 DATA bad_abi_msg+0x20(SB)/8, $"EABI ker" 127 DATA bad_abi_msg+0x28(SB)/4, $"nels" 128 DATA bad_abi_msg+0x2c(SB)/1, $0xa 129 GLOBL bad_abi_msg(SB), RODATA, $45 130 131 TEXT oabi_syscall<>(SB),NOSPLIT,$-4 132 ADD $1, R15, R4 // R15 is hardware PC 133 WORD $0xe12fff14 //BX (R4) // enter thumb mode 134 // TODO(minux): only supports little-endian CPUs 135 WORD $0x4770df01 // swi $1; bx lr 136 137 TEXT main(SB),NOSPLIT,$-4 138 MOVW $_rt0_arm_linux1(SB), R4 139 B (R4) 140 141