Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Common code for the sigreturn entry points on the vsyscall page. | |
3 | * So far this code is the same for both int80 and sysenter versions. | |
4 | * This file is #include'd by vsyscall-*.S to define them after the | |
5 | * vsyscall entry point. The kernel assumes that the addresses of these | |
6 | * routines are constant for all vsyscall implementations. | |
7 | */ | |
8 | ||
9 | #include <asm/unistd.h> | |
86feeaa8 | 10 | #include <asm/asm-offsets.h> |
1da177e4 LT |
11 | |
12 | ||
13 | /* XXX | |
14 | Should these be named "_sigtramp" or something? | |
15 | */ | |
16 | ||
17 | .text | |
2a0694d1 | 18 | .org __kernel_vsyscall+32,0x90 |
1da177e4 LT |
19 | .globl __kernel_sigreturn |
20 | .type __kernel_sigreturn,@function | |
21 | __kernel_sigreturn: | |
22 | .LSTART_sigreturn: | |
23 | popl %eax /* XXX does this mean it needs unwind info? */ | |
24 | movl $__NR_sigreturn, %eax | |
25 | int $0x80 | |
26 | .LEND_sigreturn: | |
27 | .size __kernel_sigreturn,.-.LSTART_sigreturn | |
28 | ||
29 | .balign 32 | |
30 | .globl __kernel_rt_sigreturn | |
31 | .type __kernel_rt_sigreturn,@function | |
32 | __kernel_rt_sigreturn: | |
33 | .LSTART_rt_sigreturn: | |
34 | movl $__NR_rt_sigreturn, %eax | |
35 | int $0x80 | |
36 | .LEND_rt_sigreturn: | |
37 | .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn | |
2a0694d1 | 38 | .balign 32 |
1da177e4 LT |
39 | .previous |
40 | ||
41 | .section .eh_frame,"a",@progbits | |
42 | .LSTARTFRAMEDLSI1: | |
43 | .long .LENDCIEDLSI1-.LSTARTCIEDLSI1 | |
44 | .LSTARTCIEDLSI1: | |
45 | .long 0 /* CIE ID */ | |
46 | .byte 1 /* Version number */ | |
47 | .string "zR" /* NUL-terminated augmentation string */ | |
48 | .uleb128 1 /* Code alignment factor */ | |
49 | .sleb128 -4 /* Data alignment factor */ | |
50 | .byte 8 /* Return address register column */ | |
51 | .uleb128 1 /* Augmentation value length */ | |
52 | .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ | |
53 | .byte 0 /* DW_CFA_nop */ | |
54 | .align 4 | |
55 | .LENDCIEDLSI1: | |
56 | .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */ | |
57 | .LSTARTFDEDLSI1: | |
58 | .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */ | |
59 | /* HACK: The dwarf2 unwind routines will subtract 1 from the | |
60 | return address to get an address in the middle of the | |
61 | presumed call instruction. Since we didn't get here via | |
62 | a call, we need to include the nop before the real start | |
63 | to make up for it. */ | |
64 | .long .LSTART_sigreturn-1-. /* PC-relative start address */ | |
65 | .long .LEND_sigreturn-.LSTART_sigreturn+1 | |
66 | .uleb128 0 /* Augmentation */ | |
67 | /* What follows are the instructions for the table generation. | |
68 | We record the locations of each register saved. This is | |
69 | complicated by the fact that the "CFA" is always assumed to | |
70 | be the value of the stack pointer in the caller. This means | |
71 | that we must define the CFA of this body of code to be the | |
72 | saved value of the stack pointer in the sigcontext. Which | |
73 | also means that there is no fixed relation to the other | |
74 | saved registers, which means that we must use DW_CFA_expression | |
75 | to compute their addresses. It also means that when we | |
76 | adjust the stack with the popl, we have to do it all over again. */ | |
77 | ||
78 | #define do_cfa_expr(offset) \ | |
79 | .byte 0x0f; /* DW_CFA_def_cfa_expression */ \ | |
80 | .uleb128 1f-0f; /* length */ \ | |
81 | 0: .byte 0x74; /* DW_OP_breg4 */ \ | |
82 | .sleb128 offset; /* offset */ \ | |
83 | .byte 0x06; /* DW_OP_deref */ \ | |
84 | 1: | |
85 | ||
86 | #define do_expr(regno, offset) \ | |
87 | .byte 0x10; /* DW_CFA_expression */ \ | |
88 | .uleb128 regno; /* regno */ \ | |
89 | .uleb128 1f-0f; /* length */ \ | |
90 | 0: .byte 0x74; /* DW_OP_breg4 */ \ | |
91 | .sleb128 offset; /* offset */ \ | |
92 | 1: | |
93 | ||
94 | do_cfa_expr(SIGCONTEXT_esp+4) | |
95 | do_expr(0, SIGCONTEXT_eax+4) | |
96 | do_expr(1, SIGCONTEXT_ecx+4) | |
97 | do_expr(2, SIGCONTEXT_edx+4) | |
98 | do_expr(3, SIGCONTEXT_ebx+4) | |
99 | do_expr(5, SIGCONTEXT_ebp+4) | |
100 | do_expr(6, SIGCONTEXT_esi+4) | |
101 | do_expr(7, SIGCONTEXT_edi+4) | |
102 | do_expr(8, SIGCONTEXT_eip+4) | |
103 | ||
104 | .byte 0x42 /* DW_CFA_advance_loc 2 -- nop; popl eax. */ | |
105 | ||
106 | do_cfa_expr(SIGCONTEXT_esp) | |
107 | do_expr(0, SIGCONTEXT_eax) | |
108 | do_expr(1, SIGCONTEXT_ecx) | |
109 | do_expr(2, SIGCONTEXT_edx) | |
110 | do_expr(3, SIGCONTEXT_ebx) | |
111 | do_expr(5, SIGCONTEXT_ebp) | |
112 | do_expr(6, SIGCONTEXT_esi) | |
113 | do_expr(7, SIGCONTEXT_edi) | |
114 | do_expr(8, SIGCONTEXT_eip) | |
115 | ||
116 | .align 4 | |
117 | .LENDFDEDLSI1: | |
118 | ||
119 | .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */ | |
120 | .LSTARTFDEDLSI2: | |
121 | .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */ | |
122 | /* HACK: See above wrt unwind library assumptions. */ | |
123 | .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ | |
124 | .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 | |
125 | .uleb128 0 /* Augmentation */ | |
126 | /* What follows are the instructions for the table generation. | |
127 | We record the locations of each register saved. This is | |
128 | slightly less complicated than the above, since we don't | |
129 | modify the stack pointer in the process. */ | |
130 | ||
131 | do_cfa_expr(RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_esp) | |
132 | do_expr(0, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_eax) | |
133 | do_expr(1, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ecx) | |
134 | do_expr(2, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_edx) | |
135 | do_expr(3, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ebx) | |
136 | do_expr(5, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_ebp) | |
137 | do_expr(6, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_esi) | |
138 | do_expr(7, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_edi) | |
139 | do_expr(8, RT_SIGFRAME_sigcontext-4 + SIGCONTEXT_eip) | |
140 | ||
141 | .align 4 | |
142 | .LENDFDEDLSI2: | |
143 | .previous |