vfs: check userland buffers before reading them.
[haiku.git] / src / libs / libunwind / ia64 / Ginstall_cursor.S
blob6fb4401faa23739cc4a8480eb3bba71b3b57d895
1 /* libunwind - a platform-independent unwind library
2    Copyright (C) 2001-2003 Hewlett-Packard Co
3         Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of libunwind.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
26 #include "ucontext_i.h"
28 #ifdef UNW_LOCAL_ONLY
29 # include "Lcursor_i.h"
30 # define ia64_install_cursor    _ULia64_install_cursor
31 #else
32 # include "Gcursor_i.h"
33 # define ia64_install_cursor    _Uia64_install_cursor
34 #endif
36 #define SYS_sigreturn   1181
38 #ifndef UNW_REMOTE_ONLY
40 /*  ia64_install_cursor (const cursor *c, long pri_unat, long *extra,
41                          long bspstore, long dirty_size, long *dirty_partition,
42                          long dirty_rnat)
44   Restores the machine-state represented by C and thereby resumes execution
45   in that frame.  If the frame or one of its descendants was interrupted
46   by a signal, all registers are restored (including the signal mask).
47   Otherwise, only the preserved registers, the global-pointer (r1), and
48   the exception-arguments (r15-r18) are restored.  */
50 #define pRet    p6
51 #define pSig    p7
53         .align 32
54         .hidden ia64_install_cursor
55         .global ia64_install_cursor
56         .proc ia64_install_cursor
57 ia64_install_cursor:
58         alloc r3 = ar.pfs, 7, 0, 0, 0
59         invala
60         add r2 = FR_LOC_OFF, in0
61         ;;
63         ld8 r16 = [r2], LOC_SIZE        // r16 = loc[IA64_REG_FR16]
64         mov.m r10 = ar.rsc              // (ar.rsc: ~ 12 cycle latency)
65         add r3 = FR_LOC_OFF + 16, in0
66         ;;
68         ld8 r17 = [r2], 2*LOC_SIZE      // r17 = loc[IA64_REG_FR17]
69         ld8 r18 = [r3], 2*LOC_SIZE      // r18 = loc[IA64_REG_FR18]
70         and r16 = -4, r16
71         ;;
73         ld8 r19 = [r2], 2*LOC_SIZE      // r19 = loc[IA64_REG_FR19]
74         ld8 r20 = [r3], 2*LOC_SIZE      // r20 = loc[IA64_REG_FR20]
75         and r17 = -4, r17
76         ;;
78         ldf.fill f16 = [r16]            // f16 restored (don't touch no more)
79         ldf.fill f17 = [r17]            // f17 restored (don't touch no more)
80         and r18 = -4, r18
82         ld8 r21 = [r2], 2*LOC_SIZE      // r21 = loc[IA64_REG_FR21]
83         ld8 r22 = [r3], 2*LOC_SIZE      // r22 = loc[IA64_REG_FR22]
84         and r19 = -4, r19
85         ;;
87         ldf.fill f18 = [r18]            // f18 restored (don't touch no more)
88         ldf.fill f19 = [r19]            // f19 restored (don't touch no more)
89         and r20 = -4, r20
91         ld8 r23 = [r2], 2*LOC_SIZE      // r23 = loc[IA64_REG_FR23]
92         ld8 r24 = [r3], 2*LOC_SIZE      // r24 = loc[IA64_REG_FR24]
93         and r21 = -4, r21
94         ;;
96         ldf.fill f20 = [r20]            // f20 restored (don't touch no more)
97         ldf.fill f21 = [r21]            // f21 restored (don't touch no more)
98         and r22 = -4, r22
100         ld8 r25 = [r2], 2*LOC_SIZE      // r25 = loc[IA64_REG_FR25]
101         ld8 r26 = [r3], 2*LOC_SIZE      // r26 = loc[IA64_REG_FR26]
102         and r23 = -4, r23
103         ;;
105         ldf.fill f22 = [r22]            // f22 restored (don't touch no more)
106         ldf.fill f23 = [r23]            // f23 restored (don't touch no more)
107         and r24 = -4, r24
109         ld8 r27 = [r2], 2*LOC_SIZE      // r27 = loc[IA64_REG_FR27]
110         ld8 r28 = [r3], 2*LOC_SIZE      // r28 = loc[IA64_REG_FR28]
111         and r25 = -4, r25
112         ;;
114         ldf.fill f24 = [r24]            // f24 restored (don't touch no more)
115         ldf.fill f25 = [r25]            // f25 restored (don't touch no more)
116         and r26 = -4, r26
118         ld8 r29 = [r2], 2*LOC_SIZE      // r29 = loc[IA64_REG_FR29]
119         ld8 r30 = [r3], 2*LOC_SIZE      // r30 = loc[IA64_REG_FR30]
120         and r27 = -4, r27
121         ;;
123         ldf.fill f26 = [r26]            // f26 restored (don't touch no more)
124         ldf.fill f27 = [r27]            // f27 restored (don't touch no more)
125         and r28 = -4, r28
127         ld8 r31 = [r2]                  // r31 = loc[IA64_REG_FR31]
128         mov.m ar.unat = in1
129         and r29 = -4, r29
130         ;;
132         ldf.fill f28 = [r28]            // f28 restored (don't touch no more)
133         ldf.fill f29 = [r29]            // f29 restored (don't touch no more)
134         and r30 = -4, r30
136         ld8 r1 = [in2], 8               // gp restored (don't touch no more)
137         add r8 = SIGCONTEXT_ADDR_OFF, in0
138         and r31 = -4, r31
139         ;;
141         ld8 r8 = [r8]                   // r8 = sigcontext_addr
142         and r11 = 0x1c, r10             // clear all but rsc.be and rsc.pl
143         add r2 = PFS_LOC_OFF, in0
145         ldf.fill f30 = [r30]            // f30 restored (don't touch no more)
146         ldf.fill f31 = [r31]            // f31 restored (don't touch no more)
147         add r3 = 8, in2
148         ;;
150         ld8.fill r4 = [in2], 16         // r4 restored (don't touch no more)
151         ld8.fill r5 = [r3], 16          // r5 restored (don't touch no more)
152         cmp.eq pRet, pSig = r0, r8      // sigcontext_addr == NULL?
153         ;;
154         ld8.fill r6 = [in2], 16         // r6 restored (don't touch no more)
155         ld8.fill r7 = [r3]              // r7 restored (don't touch no more)
156         add r3 = IP_OFF, in0
157         ;;
159         ld8 r14 = [r2], (B1_LOC_OFF - PFS_LOC_OFF)      // r14 = pfs_loc
160         ld8 r15 = [r3]                  // r15 = ip
161         add r3 = (B2_LOC_OFF - IP_OFF), r3
162         ;;
164         ld8 r16 = [r2], (B3_LOC_OFF - B1_LOC_OFF)       // r16 = b1_loc
165         ld8 r17= [r3], (B4_LOC_OFF - B2_LOC_OFF)        // r17 = b2_loc
166         and r14 = -4, r14
167         ;;
169         ld8 r18 = [r2], (B5_LOC_OFF - B3_LOC_OFF)       // r18 = b3_loc
170         ld8 r19 = [r3], (F2_LOC_OFF - B4_LOC_OFF)       // r19 = b4_loc
171         and r16 = -4, r16
172         ;;
174         ld8 r20 = [r2], (F3_LOC_OFF - B5_LOC_OFF)       // r20 = b5_loc
175         ld8 r21 = [r3], (F4_LOC_OFF - F2_LOC_OFF)       // r21 = f2_loc
176         and r17 = -4, r17
177         ;;
179         ld8 r16 = [r16]                 // r16 = *b1_loc
180         ld8 r17 = [r17]                 // r17 = *b2_loc
181         and r18 = -4, r18
183         ld8 r22 = [r2], (F5_LOC_OFF - F3_LOC_OFF)       // r21 = f3_loc
184         ld8 r23 = [r3], (UNAT_LOC_OFF - F4_LOC_OFF)     // r22 = f4_loc
185         and r19 = -4, r19
186         ;;
188         ld8 r18 = [r18]                 // r18 = *b3_loc
189         ld8 r19 = [r19]                 // r19 = *b4_loc
190         and r20 = -4, r20
192         ld8 r24 = [r2], (LC_LOC_OFF - F5_LOC_OFF)       // r24 = f5_loc
193         ld8 r25 = [r3], (FPSR_LOC_OFF - UNAT_LOC_OFF)   // r25 = unat_loc
194         and r21 = -4, r21
195         ;;
197         and r22 = -4, r22
198         and r23 = -4, r23
199         and r24 = -4, r24
201         ld8 r20 = [r20]                 // r20 = *b5_loc
202         ldf.fill f2 = [r21]             // f2 restored (don't touch no more)
203         mov b1 = r16                    // b1 restored (don't touch no more)
204         ;;
206         ldf.fill f3 = [r22]             // f3 restored (don't touch no more)
207         ldf.fill f4 = [r23]             // f4 restored (don't touch no more)
208         mov b2 = r17                    // b2 restored (don't touch no more)
210         ld8 r26 = [r2], (RNAT_LOC_OFF - LC_LOC_OFF)     // r26 = lc_loc
211         ld8 r27 = [r3]                  // r27 = fpsr_loc
212         and r25 = -4, r25
214         add r3 = (PSP_OFF - FPSR_LOC_OFF), r3
215         nop 0
216         nop 0
217         ;;
219         ldf.fill f5 = [r24]             // f5 restored (don't touch no more)
220 (pRet)  ld8 r25 = [r25]                 // r25 = *unat_loc
221         mov b3 = r18                    // b3 restored (don't touch no more)
223         ld8 r28 = [r2], (BSP_OFF - RNAT_LOC_OFF)        // r28 = rnat_loc
224         ld8 r29 = [r3], (PR_OFF - PSP_OFF)              // r29 = sp
225         mov b4 = r19                    // b4 restored (don't touch no more)
227         and r26 = -4, r26
228         and r27 = -4, r27
229         mov b5 = r20                    // b5 restored (don't touch no more)
230         ;;
232         ld8 r26 = [r26]                 // r26 = *lc_loc
233         ld8 r27 = [r27]                 // r27 = *fpsr_loc
234         and r28 = -4, r28
236         mov r30 = in3                   // make backup-copy of new bsp
237         ld8 r31 = [r3]                  // r31 = pr
238         mov rp = r15
239         ;;
241         ld8 r28 = [r28]                 // r28 = rnat
242         mov.m ar.rsc = r11              // put RSE into enforced lazy mode
243         mov.i ar.lc = r26               // lc restored (don't touch no more)
244         ;;
246         loadrs                          // drop dirty partition
247         mov r9 = in2                    // make backup-copy of &extra[r16]
248         cmp.eq p8, p0 = in4, r0         // dirty-size == 0?
249 (p8)    br.cond.dpnt.many .skip_load_dirty
251         mov r2 = in4                    // make backup-copy of dirty_size
252         mov r15 = in5                   // make backup-copy of dirty_partition
253         mov r16 = in6                   // make backup-copy of dirty_rnat
254         ;;
256         alloc r3 = ar.pfs, 0, 0, 0, 0   // drop register frame
257         dep r11 = r2, r11, 16, 16
258         ;;
259         mov.m ar.bspstore = r15
260         ;;
261         mov.m ar.rnat = r16
262         mov.m ar.rsc = r11              // 14 cycles latency to loadrs
263         ;;
264         loadrs                          // loadup new dirty partition
265         ;;
267 .skip_load_dirty:
268         mov.m ar.bspstore = r30         // restore register backing-store
269         add r3 = 8, r9                  // r3 = &extra[r16]
270         ;;
272 (pRet)  mov.m ar.fpsr = r27             // fpsr restored (don't touch no more)
273         mov.m ar.rnat = r28
274 (pSig)  br.cond.dpnt.many .next
276 /****** Return via br.ret: */
278         ld8 r14 = [r14]                 // r14 = *pfs_loc
279         ld8 r15 = [r9], 16              // r15 restored (don't touch no more)
280         mov pr = r31, -1                // pr restored (don't touch no more)
281         ;;
283         ld8 r16 = [r3], 16              // r16 restored (don't touch no more)
284         ld8 r17 = [r9]                  // r17 restored (don't touch no more)
285         nop.i 0
286         ;;
288         ld8 r18 = [r3]                  // r18 restored (don't touch no more)
289         mov.m ar.rsc = r10              // restore original ar.rsc
290         mov sp = r29
292         mov.m ar.unat = r25             // unat restored (don't touch no more)
293         mov.i ar.pfs = r14
294         br.ret.sptk.many rp
295         ;;
297 /****** Return via sigreturn(): */
299 .next:  mov.m ar.rsc = r10              // restore original ar.rsc
300         add r2 = (SC_FR + 6*16), r8
301         add r3 = (SC_FR + 7*16), r8
302         ;;
304         ldf.fill f6 = [r2], 32
305         ldf.fill f7 = [r3], 32
306         nop 0
307         ;;
309         ldf.fill f8 = [r2], 32
310         ldf.fill f9 = [r3], 32
311         nop 0
312         ;;
314         ldf.fill f10 = [r2], 32
315         ldf.fill f11 = [r3], 32
316         nop 0
317         ;;
319         ldf.fill f12 = [r2], 32
320         ldf.fill f13 = [r3], 32
321         nop 0
322         ;;
324         ldf.fill f14 = [r2], 32
325         ldf.fill f15 = [r3], 32
326         mov sp = r29
327         ;;
329 #if NEW_SYSCALL
330         add r2 = 8, tp;;
331         ld8 r2 = [r2]
332         mov r15 = SYS_sigreturn
333         mov b7 = r2
334         br.call.sptk.many b6 = b7
335         ;;
336 #else
337         mov r15 = SYS_sigreturn
338         break 0x100000
339 #endif
340         break 0                         // bug out if sigreturn() returns
342         .endp ia64_install_cursor
344 #endif /* !UNW_REMOTE_ONLY */
345 #ifdef __linux__
346         /* We do not need executable stack.  */
347         .section        .note.GNU-stack,"",@progbits
348 #endif