1133819Stjr/* $FreeBSD: releng/10.3/sys/amd64/linux32/linux32_locore.s 294368 2016-01-20 01:09:53Z jhb $ */
2133819Stjr
3133819Stjr#include "linux32_assym.h"			/* system definitions */
4133819Stjr#include <machine/asmacros.h>			/* miscellaneous asm macros */
5133819Stjr
6133819Stjr#include <amd64/linux32/linux32_syscall.h>	/* system call numbers */
7133819Stjr
8293516Sdchagin.data
9293516Sdchagin
10293516Sdchagin	.globl linux_platform
11293516Sdchaginlinux_platform:
12293516Sdchagin	.asciz "i686"
13293516Sdchagin
14133819Stjr.text
15133819Stjr.code32
16133819Stjr
17293514Sdchagin/*
18293514Sdchagin * To avoid excess stack frame the signal trampoline code emulates
19293514Sdchagin * the 'call' instruction.
20293514Sdchagin */
21293514SdchaginNON_GPROF_ENTRY(linux32_sigcode)
22293514Sdchagin	movl	%esp, %ebx			/* preserve sigframe */
23293514Sdchagin	call .getip0
24293514Sdchagin.getip0:
25293514Sdchagin	popl	%eax
26293514Sdchagin	add	$.startsigcode-.getip0, %eax	/* ret address */
27293514Sdchagin	push	%eax
28293514Sdchagin	jmp	*LINUX_SIGF_HANDLER(%ebx)
29293514Sdchagin.startsigcode:
30293514Sdchagin	popl	%eax
31294368Sjhb	movl	$LINUX32_SYS_linux_sigreturn,%eax	/* linux_sigreturn() */
32133819Stjr	int	$0x80				/* enter kernel with args */
33293514Sdchagin.endsigcode:
34133819Stjr0:	jmp	0b
35293514Sdchagin
36293514SdchaginNON_GPROF_ENTRY(linux32_rt_sigcode)
37133819Stjr	leal	LINUX_RT_SIGF_UC(%esp),%ebx	/* linux ucp */
38182849Skib	leal	LINUX_RT_SIGF_SC(%ebx),%ecx	/* linux sigcontext */
39293514Sdchagin	movl	%esp, %edi
40293514Sdchagin	call	.getip1
41293514Sdchagin.getip1:
42293514Sdchagin	popl	%eax
43293514Sdchagin	add	$.startrtsigcode-.getip1, %eax	/* ret address */
44293514Sdchagin	push	%eax
45293514Sdchagin	jmp	*LINUX_RT_SIGF_HANDLER(%edi)
46293514Sdchagin.startrtsigcode:
47294368Sjhb	movl	$LINUX32_SYS_linux_rt_sigreturn,%eax   /* linux_rt_sigreturn() */
48133819Stjr	int	$0x80				/* enter kernel with args */
49293514Sdchagin.endrtsigcode:
50133819Stjr0:	jmp	0b
51133819Stjr
52293514SdchaginNON_GPROF_ENTRY(linux32_vsyscall)
53293514Sdchagin.startvsyscall:
54293514Sdchagin	int $0x80
55293514Sdchagin	ret
56293514Sdchagin.endvsyscall:
57293514Sdchagin
58293536Sdchagin#if 0
59293514Sdchagin	.section .note.Linux, "a",@note
60293514Sdchagin	.long 2f - 1f		/* namesz */
61293514Sdchagin	.balign 4
62293514Sdchagin	.long 4f - 3f		/* descsz */
63293514Sdchagin	.long 0
64293514Sdchagin1:
65293514Sdchagin	.asciz "Linux"
66293514Sdchagin2:
67293514Sdchagin	.balign 4
68293514Sdchagin3:
69293514Sdchagin	.long LINUX_VERSION_CODE
70293514Sdchagin4:
71293514Sdchagin	.balign 4
72293514Sdchagin	.previous
73293536Sdchagin#endif
74293514Sdchagin
75293514Sdchagin#define do_cfa_expr(offset)                                             \
76293514Sdchagin	.byte 0x0f;			/* DW_CFA_def_cfa_expression */ \
77293514Sdchagin	.uleb128 11f-10f;		/*   length */                  \
78293514Sdchagin10:	.byte 0x74;			/*     DW_OP_breg4 */           \
79293514Sdchagin	.sleb128 offset;		/*      offset */               \
80293514Sdchagin	.byte 0x06;			/*     DW_OP_deref */           \
81293514Sdchagin11:
82293514Sdchagin
83293514Sdchagin
84293514Sdchagin	/* CIE */
85293514Sdchagin	.section .eh_frame,"a",@progbits
86293514Sdchagin.LSTARTFRAMEDLSI1:
87293514Sdchagin	.long .LENDCIEDLSI1-.LSTARTCIEDLSI1
88293514Sdchagin.LSTARTCIEDLSI1:
89293514Sdchagin	.long 0					/* CIE ID */
90293514Sdchagin	.byte 1					/* Version number */
91293514Sdchagin	.string "zRS"				/* NULL-terminated
92293514Sdchagin						 * augmentation string
93293514Sdchagin						 */
94293514Sdchagin	.uleb128 1				/* Code alignment factor */
95293514Sdchagin	.sleb128 -4				/* Data alignment factor */
96293514Sdchagin	.byte 8					/* Return address
97293514Sdchagin						 * register column
98293514Sdchagin						 */
99293514Sdchagin	.uleb128 1				/* Augmentation value length */
100293514Sdchagin	.byte 0x1b				/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
101293514Sdchagin	.byte 0					/* DW_CFA_nop */
102293514Sdchagin	.align 4
103293514Sdchagin.LENDCIEDLSI1:
104293514Sdchagin
105293514Sdchagin	/* FDE */
106293514Sdchagin	.long .LENDFDEDLSI1-.LSTARTFDEDLSI1	/* Length FDE */
107293514Sdchagin.LSTARTFDEDLSI1:
108293514Sdchagin	.long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */
109293514Sdchagin	.long .startsigcode-.			/* PC-relative start address */
110293514Sdchagin	.long .endsigcode-.startsigcode
111293514Sdchagin	.uleb128 0				/* Augmentation */
112293514Sdchagin	do_cfa_expr(LINUX_SIGF_SC-8)
113293514Sdchagin	.align 4
114293514Sdchagin.LENDFDEDLSI1:
115293514Sdchagin
116293514Sdchagin	.long .LENDFDEDLSI2-.LSTARTFDEDLSI2	/* Length FDE */
117293514Sdchagin.LSTARTFDEDLSI2:
118293514Sdchagin	.long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1	/* CIE pointer */
119293514Sdchagin	.long .startrtsigcode-.			/* PC-relative start address */
120293514Sdchagin	.long .endrtsigcode-.startrtsigcode
121293514Sdchagin	.uleb128 0				/* Augmentation */
122293514Sdchagin	do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP)
123293514Sdchagin	.align 4
124293514Sdchagin.LENDFDEDLSI2:
125293514Sdchagin	.previous
126293514Sdchagin
127293514Sdchagin	.section .eh_frame,"a",@progbits
128293514Sdchagin.LSTARTFRAMEDLSI2:
129293514Sdchagin	.long .LENDCIEDLSI2-.LSTARTCIEDLSI2
130293514Sdchagin.LSTARTCIEDLSI2:
131293514Sdchagin	.long 0					/* CIE ID */
132293514Sdchagin	.byte 1					/* Version number */
133293514Sdchagin	.string "zR"				/* NULL-terminated
134293514Sdchagin						 * augmentation string
135293514Sdchagin						 */
136293514Sdchagin	.uleb128 1				/* Code alignment factor */
137293514Sdchagin	.sleb128 -4				/* Data alignment factor */
138293514Sdchagin	.byte 8					/* Return address register column */
139293514Sdchagin	.uleb128 1				/* Augmentation value length */
140293514Sdchagin	.byte 0x1b				/* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
141293514Sdchagin	.byte 0x0c				/* DW_CFA_def_cfa */
142293514Sdchagin	.uleb128 4
143293514Sdchagin	.uleb128 4
144293514Sdchagin	.byte 0x88				/* DW_CFA_offset, column 0x8 */
145293514Sdchagin	.uleb128 1
146293514Sdchagin	.align 4
147293514Sdchagin.LENDCIEDLSI2:
148293514Sdchagin	.long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */
149293514Sdchagin.LSTARTFDEDLSI3:
150293514Sdchagin	.long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */
151293514Sdchagin	.long .startvsyscall-.			/* PC-relative start address */
152293514Sdchagin	.long .endvsyscall-.startvsyscall
153293514Sdchagin	.uleb128 0
154293514Sdchagin	.align 4
155293514Sdchagin.LENDFDEDLSI3:
156293514Sdchagin	.previous
157