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,$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