1220297Sadrian/* $FreeBSD: releng/10.3/sys/i386/linux/linux_locore.s 293536 2016-01-09 16:25:30Z dchagin $ */
2220297Sadrian
3220297Sadrian#include "linux_assym.h"			/* system definitions */
4220297Sadrian#include <machine/asmacros.h>			/* miscellaneous asm macros */
5220297Sadrian
6220297Sadrian#include <i386/linux/linux_syscall.h>		/* system call numbers */
7220297Sadrian
8220297Sadrian#include "assym.s"
9220297Sadrian
10220297Sadrian/*
11220297Sadrian * To avoid excess stack frame the signal trampoline code emulates
12220297Sadrian * the 'call' instruction.
13220297Sadrian */
14220297SadrianNON_GPROF_ENTRY(linux_sigcode)
15220297Sadrian	movl	%esp, %ebx			/* preserve sigframe */
16220297Sadrian	call .getip0
17220297Sadrian.getip0:
18220297Sadrian	popl	%eax
19220297Sadrian	add	$.startsigcode-.getip0, %eax	/* ret address */
20220297Sadrian	push	%eax
21220297Sadrian	jmp	*LINUX_SIGF_HANDLER(%ebx)
22220297Sadrian.startsigcode:
23220297Sadrian	popl	%eax				/* gcc unwind code need this */
24220297Sadrian	movl	$LINUX_SYS_linux_sigreturn,%eax	/* linux_sigreturn() */
25220297Sadrian	int	$0x80				/* enter kernel with args */
26220297Sadrian.endsigcode:
27220297Sadrian0:	jmp	0b
28220297Sadrian
29220297SadrianNON_GPROF_ENTRY(linux_rt_sigcode)
30220297Sadrian	leal	LINUX_RT_SIGF_UC(%esp),%ebx	/* linux ucp */
31220297Sadrian	leal	LINUX_RT_SIGF_SC(%ebx),%ecx	/* linux sigcontext */
32220297Sadrian	movl	%esp, %edi
33220297Sadrian	call	.getip1
34220297Sadrian.getip1:
35220297Sadrian	popl	%eax
36220297Sadrian	add	$.startrtsigcode-.getip1, %eax	/* ret address */
37220297Sadrian	push	%eax
38220297Sadrian	jmp	*LINUX_RT_SIGF_HANDLER(%edi)
39220297Sadrian.startrtsigcode:
40220297Sadrian	movl	$LINUX_SYS_linux_rt_sigreturn,%eax   /* linux_rt_sigreturn() */
41220297Sadrian	int	$0x80				/* enter kernel with args */
42220297Sadrian.endrtsigcode:
43220297Sadrian0:	jmp	0b
44220297Sadrian
45220297SadrianNON_GPROF_ENTRY(linux_vsyscall)
46220297Sadrian.startvsyscall:
47220297Sadrian	int $0x80
48220297Sadrian	ret
49220297Sadrian.endvsyscall:
50220297Sadrian
51220297Sadrian#if 0
52220297Sadrian	.section .note.Linux, "a",@note
53220297Sadrian	.long 2f - 1f		/* namesz */
54220297Sadrian	.balign 4
55220297Sadrian	.long 4f - 3f		/* descsz */
56220297Sadrian	.long 0
57220297Sadrian1:
58220297Sadrian	.asciz "Linux"
59220297Sadrian2:
60220297Sadrian	.balign 4
61220297Sadrian3:
62220297Sadrian	.long LINUX_VERSION_CODE
63220297Sadrian4:
64220297Sadrian	.balign 4
65220297Sadrian	.previous
66220297Sadrian#endif
67220297Sadrian
68220297Sadrian#define do_cfa_expr(offset)                                             \
69220297Sadrian	.byte 0x0f;			/* DW_CFA_def_cfa_expression */ \
70220297Sadrian	.uleb128 11f-10f;		/*   length */                  \
71220297Sadrian10:	.byte 0x74;			/*     DW_OP_breg4 */           \
72220297Sadrian	.sleb128 offset;		/*      offset */               \
73220297Sadrian	.byte 0x06;			/*     DW_OP_deref */           \
74220297Sadrian11:
75220297Sadrian
76220297Sadrian
77220297Sadrian	/* CIE */
78220297Sadrian	.section .eh_frame,"a",@progbits
79220297Sadrian.LSTARTFRAMEDLSI1:
80220297Sadrian	.long .LENDCIEDLSI1-.LSTARTCIEDLSI1
81220297Sadrian.LSTARTCIEDLSI1:
82220297Sadrian	.long 0					/* CIE ID */
83220297Sadrian	.byte 1					/* Version number */
84220297Sadrian	.string "zRS"				/* NULL-terminated
85220297Sadrian						 * augmentation string
86220297Sadrian						 */
87220297Sadrian	.uleb128 1				/* Code alignment factor */
88220297Sadrian	.sleb128 -4				/* Data alignment factor */
89220297Sadrian	.byte 8					/* Return address
90220297Sadrian						 * register column
91220297Sadrian						 */
92220297Sadrian	.uleb128 1				/* Augmentation value length */
93220297Sadrian	.byte 0x1b				/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
94220297Sadrian	.byte 0					/* DW_CFA_nop */
95220297Sadrian	.align 4
96220297Sadrian.LENDCIEDLSI1:
97220297Sadrian
98220297Sadrian	/* FDE */
99220297Sadrian	.long .LENDFDEDLSI1-.LSTARTFDEDLSI1	/* Length FDE */
100220297Sadrian.LSTARTFDEDLSI1:
101220297Sadrian	.long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */
102220297Sadrian	.long .startsigcode-.			/* PC-relative start address */
103220297Sadrian	.long .endsigcode-.startsigcode
104220297Sadrian	.uleb128 0				/* Augmentation */
105220297Sadrian	do_cfa_expr(LINUX_SIGF_SC-8)
106220297Sadrian	.align 4
107220297Sadrian.LENDFDEDLSI1:
108220297Sadrian
109220297Sadrian	.long .LENDFDEDLSI2-.LSTARTFDEDLSI2	/* Length FDE */
110220297Sadrian.LSTARTFDEDLSI2:
111220297Sadrian	.long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1	/* CIE pointer */
112220297Sadrian	.long .startrtsigcode-.			/* PC-relative start address */
113220297Sadrian	.long .endrtsigcode-.startrtsigcode
114220297Sadrian	.uleb128 0				/* Augmentation */
115220297Sadrian	do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP)
116220297Sadrian	.align 4
117220297Sadrian.LENDFDEDLSI2:
118220297Sadrian	.previous
119220297Sadrian
120220297Sadrian	.section .eh_frame,"a",@progbits
121220297Sadrian.LSTARTFRAMEDLSI2:
122220297Sadrian	.long .LENDCIEDLSI2-.LSTARTCIEDLSI2
123220297Sadrian.LSTARTCIEDLSI2:
124220297Sadrian	.long 0					/* CIE ID */
125220297Sadrian	.byte 1					/* Version number */
126220297Sadrian	.string "zR"				/* NULL-terminated
127220297Sadrian						 * augmentation string
128220297Sadrian						 */
129220297Sadrian	.uleb128 1				/* Code alignment factor */
130220297Sadrian	.sleb128 -4				/* Data alignment factor */
131220297Sadrian	.byte 8					/* Return address register column */
132220297Sadrian	.uleb128 1				/* Augmentation value length */
133220297Sadrian	.byte 0x1b				/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
134220297Sadrian	.byte 0x0c				/* DW_CFA_def_cfa */
135220297Sadrian	.uleb128 4
136220297Sadrian	.uleb128 4
137220297Sadrian	.byte 0x88				/* DW_CFA_offset, column 0x8 */
138220297Sadrian	.uleb128 1
139220297Sadrian	.align 4
140220297Sadrian.LENDCIEDLSI2:
141220297Sadrian	.long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */
142220297Sadrian.LSTARTFDEDLSI3:
143220297Sadrian	.long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */
144220297Sadrian	.long .startvsyscall-.			/* PC-relative start address */
145220297Sadrian	.long .endvsyscall-.startvsyscall
146220297Sadrian	.uleb128 0
147220297Sadrian	.align 4
148220297Sadrian.LENDFDEDLSI3:
149220297Sadrian	.previous
150220297Sadrian