Home | History | Annotate | Download | only in runtime
      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,$104
     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 	// Skip floating point registers on GOARM < 6.
     26 	MOVB    runtimegoarm(SB), R11
     27 	CMP $6, R11
     28 	BLT skipfpsave
     29 	MOVD	F8, (32+8*1)(R13)
     30 	MOVD	F9, (32+8*2)(R13)
     31 	MOVD	F10, (32+8*3)(R13)
     32 	MOVD	F11, (32+8*4)(R13)
     33 	MOVD	F12, (32+8*5)(R13)
     34 	MOVD	F13, (32+8*6)(R13)
     35 	MOVD	F14, (32+8*7)(R13)
     36 	MOVD	F15, (32+8*8)(R13)
     37 skipfpsave:
     38 	// Save argc/argv.
     39 	MOVW	R0, _rt0_arm_linux_lib_argc<>(SB)
     40 	MOVW	R1, _rt0_arm_linux_lib_argv<>(SB)
     41 
     42 	// Synchronous initialization.
     43 	MOVW	$runtimelibpreinit(SB), R2
     44 	CALL	(R2)
     45 
     46 	// Create a new thread to do the runtime initialization.
     47 	MOVW	_cgo_sys_thread_create(SB), R2
     48 	CMP	$0, R2
     49 	BEQ	nocgo
     50 	MOVW	$_rt0_arm_linux_lib_go<>(SB), R0
     51 	MOVW	$0, R1
     52 	BL	(R2)
     53 	B	rr
     54 nocgo:
     55 	MOVW	$0x800000, R0                     // stacksize = 8192KB
     56 	MOVW	$_rt0_arm_linux_lib_go<>(SB), R1  // fn
     57 	MOVW	R0, 4(R13)
     58 	MOVW	R1, 8(R13)
     59 	BL	runtimenewosproc0(SB)
     60 rr:
     61 	// Restore callee-save registers and return.
     62 	MOVB    runtimegoarm(SB), R11
     63 	CMP $6, R11
     64 	BLT skipfprest
     65 	MOVD	(32+8*1)(R13), F8
     66 	MOVD	(32+8*2)(R13), F9
     67 	MOVD	(32+8*3)(R13), F10
     68 	MOVD	(32+8*4)(R13), F11
     69 	MOVD	(32+8*5)(R13), F12
     70 	MOVD	(32+8*6)(R13), F13
     71 	MOVD	(32+8*7)(R13), F14
     72 	MOVD	(32+8*8)(R13), F15
     73 skipfprest:
     74 	MOVW	12(R13), R4
     75 	MOVW	16(R13), R5
     76 	MOVW	20(R13), R6
     77 	MOVW	24(R13), R7
     78 	MOVW	28(R13), R8
     79 	MOVW	32(R13), R11
     80 	RET
     81 
     82 TEXT _rt0_arm_linux_lib_go<>(SB),NOSPLIT,$8
     83 	MOVW	_rt0_arm_linux_lib_argc<>(SB), R0
     84 	MOVW	_rt0_arm_linux_lib_argv<>(SB), R1
     85 	MOVW	R0, 0(R13)
     86 	MOVW	R1, 4(R13)
     87 	B	runtimert0_go(SB)
     88 
     89 DATA _rt0_arm_linux_lib_argc<>(SB)/4,$0
     90 GLOBL _rt0_arm_linux_lib_argc<>(SB),NOPTR,$4
     91 DATA _rt0_arm_linux_lib_argv<>(SB)/4,$0
     92 GLOBL _rt0_arm_linux_lib_argv<>(SB),NOPTR,$4
     93 
     94 TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4
     95 	// We first need to detect the kernel ABI, and warn the user
     96 	// if the system only supports OABI
     97 	// The strategy here is to call some EABI syscall to see if
     98 	// SIGILL is received.
     99 	// To catch SIGILL, we have to first setup sigaction, this is
    100 	// a chicken-and-egg problem, because we can't do syscall if
    101 	// we don't know the kernel ABI... Oh, not really, we can do
    102 	// syscall in Thumb mode.
    103 
    104 	// Save argc and argv
    105 	MOVM.DB.W [R0-R1], (R13)
    106 
    107 	// Thumb mode OABI check disabled because there are some
    108 	// EABI systems that do not support Thumb execution.
    109 	// We can run on them except for this check!
    110 
    111 	// // set up sa_handler
    112 	// MOVW	$bad_abi<>(SB), R0 // sa_handler
    113 	// MOVW	$0, R1 // sa_flags
    114 	// MOVW	$0, R2 // sa_restorer
    115 	// MOVW	$0, R3 // sa_mask
    116 	// MOVM.DB.W [R0-R3], (R13)
    117 	// MOVW	$4, R0 // SIGILL
    118 	// MOVW	R13, R1 // sa
    119 	// SUB	$16, R13
    120 	// MOVW	R13, R2 // old_sa
    121 	// MOVW	$8, R3 // c
    122 	// MOVW	$174, R7 // sys_sigaction
    123 	// BL	oabi_syscall<>(SB)
    124 
    125 	// do an EABI syscall
    126 	MOVW	$20, R7 // sys_getpid
    127 	SWI	$0 // this will trigger SIGILL on OABI systems
    128 
    129 	// MOVW	$4, R0  // SIGILL
    130 	// MOVW	R13, R1 // sa
    131 	// MOVW	$0, R2 // old_sa
    132 	// MOVW	$8, R3 // c
    133 	// MOVW	$174, R7 // sys_sigaction
    134 	// SWI	$0 // restore signal handler
    135 	// ADD	$32, R13
    136 
    137 	B	runtimert0_go(SB)
    138 
    139 TEXT bad_abi<>(SB),NOSPLIT,$-4
    140 	// give diagnosis and exit
    141 	MOVW	$2, R0 // stderr
    142 	MOVW	$bad_abi_msg(SB), R1 // data
    143 	MOVW	$45, R2 // len
    144 	MOVW	$4, R7 // sys_write
    145 	BL	oabi_syscall<>(SB)
    146 	MOVW	$1, R0
    147 	MOVW	$1, R7 // sys_exit
    148 	BL	oabi_syscall<>(SB)
    149 	B  	0(PC)
    150 
    151 DATA bad_abi_msg+0x00(SB)/8, $"This pro"
    152 DATA bad_abi_msg+0x08(SB)/8, $"gram can"
    153 DATA bad_abi_msg+0x10(SB)/8, $" only be"
    154 DATA bad_abi_msg+0x18(SB)/8, $" run on "
    155 DATA bad_abi_msg+0x20(SB)/8, $"EABI ker"
    156 DATA bad_abi_msg+0x28(SB)/4, $"nels"
    157 DATA bad_abi_msg+0x2c(SB)/1, $0xa
    158 GLOBL bad_abi_msg(SB), RODATA, $45
    159 
    160 TEXT oabi_syscall<>(SB),NOSPLIT,$-4
    161 	ADD $1, R15, R4 // R15 is hardware PC
    162 	WORD $0xe12fff14 //BX	(R4) // enter thumb mode
    163 	// TODO(minux): only supports little-endian CPUs
    164 	WORD $0x4770df01 // swi $1; bx lr
    165 
    166 TEXT main(SB),NOSPLIT,$-4
    167 	MOVW	$_rt0_arm_linux1(SB), R4
    168 	B		(R4)
    169 
    170