github.com/fenixara/go@v0.0.0-20170127160404-96ea0918e670/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,$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    runtime·goarm(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	$runtime·libpreinit(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	runtime·newosproc0(SB)
    60  rr:
    61  	// Restore callee-save registers and return.
    62  	MOVB    runtime·goarm(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	runtime·rt0_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	runtime·rt0_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