xref: /linux/arch/loongarch/include/asm/linkage.h (revision e80948062dcfff0543c5c60ba8654e825bf73b5a)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_LINKAGE_H
3 #define __ASM_LINKAGE_H
4 
5 #define __ALIGN		.align 2
6 #define __ALIGN_STR	__stringify(__ALIGN)
7 
8 #define SYM_FUNC_START(name)				\
9 	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)	\
10 	.cfi_startproc;
11 
12 #define SYM_FUNC_START_NOALIGN(name)			\
13 	SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE)	\
14 	.cfi_startproc;
15 
16 #define SYM_FUNC_START_LOCAL(name)			\
17 	SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)	\
18 	.cfi_startproc;
19 
20 #define SYM_FUNC_START_LOCAL_NOALIGN(name)		\
21 	SYM_START(name, SYM_L_LOCAL, SYM_A_NONE)	\
22 	.cfi_startproc;
23 
24 #define SYM_FUNC_START_WEAK(name)			\
25 	SYM_START(name, SYM_L_WEAK, SYM_A_ALIGN)	\
26 	.cfi_startproc;
27 
28 #define SYM_FUNC_START_WEAK_NOALIGN(name)		\
29 	SYM_START(name, SYM_L_WEAK, SYM_A_NONE)		\
30 	.cfi_startproc;
31 
32 #define SYM_FUNC_END(name)				\
33 	.cfi_endproc;					\
34 	SYM_END(name, SYM_T_FUNC)
35 
36 #define SYM_CODE_START(name)				\
37 	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)	\
38 	.cfi_startproc;
39 
40 #define SYM_CODE_END(name)				\
41 	.cfi_endproc;					\
42 	SYM_END(name, SYM_T_NONE)
43 
44 /*
45  * This is for the signal handler trampoline, which is used as the return
46  * address of the signal handlers in userspace instead of called normally.
47  * The long standing libgcc bug https://gcc.gnu.org/PR124050 requires a
48  * nop between .cfi_startproc and the actual address of the trampoline, so
49  * we cannot simply use SYM_FUNC_START.
50  *
51  * This wrapper also contains all the .cfi_* directives for recovering
52  * the content of the GPRs and the "return address" (where the rt_sigreturn
53  * syscall will jump to), assuming there is a struct rt_sigframe (where
54  * a struct sigcontext containing those information we need to recover) at
55  * $sp.  The "DWARF for the LoongArch(TM) Architecture" manual states
56  * column 0 is for $zero, but it does not make too much sense to
57  * save/restore the hardware zero register.  Repurpose this column here
58  * for the return address (here it's not the content of $ra we cannot use
59  * the default column 3).
60  */
61 #define SYM_SIGFUNC_START(name)				\
62 	.cfi_startproc;					\
63 	.cfi_signal_frame;				\
64 	.cfi_def_cfa 3, RT_SIGFRAME_SC;			\
65 	.cfi_return_column 0;				\
66 	.cfi_offset 0, SC_PC;				\
67 							\
68 	.irp num, 1,  2,  3,  4,  5,  6,  7,  8, 	\
69 		  9,  10, 11, 12, 13, 14, 15, 16,	\
70 		  17, 18, 19, 20, 21, 22, 23, 24,	\
71 		  25, 26, 27, 28, 29, 30, 31;		\
72 	.cfi_offset \num, SC_REGS + \num * 8;		\
73 	.endr;						\
74 							\
75 	nop;						\
76 	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
77 
78 #define SYM_SIGFUNC_END(name) SYM_FUNC_END(name)
79 
80 #endif
81