]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/coregrind/m_trampoline.S
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / coregrind / m_trampoline.S
1
2 /*--------------------------------------------------------------------*/
3 /*--- Trampoline code page stuff.                   m_trampoline.S ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2010 Julian Seward 
11      jseward@acm.org
12   Copyright (C) 2006-2010 OpenWorks LLP
13      info@open-works.co.uk
14         
15   This program is free software; you can redistribute it and/or
16   modify it under the terms of the GNU General Public License as
17   published by the Free Software Foundation; either version 2 of the
18   License, or (at your option) any later version.
19
20   This program is distributed in the hope that it will be useful, but
21   WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   General Public License for more details.
24
25   You should have received a copy of the GNU General Public License
26   along with this program; if not, write to the Free Software
27   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28   02111-1307, USA.
29
30   The GNU General Public License is contained in the file COPYING.
31 */
32
33 #include "pub_core_basics_asm.h"
34 #include "pub_core_vkiscnums_asm.h"
35
36 /* ------------------ SIMULATED CPU HELPERS ------------------ */
37 /* 
38    Replacements for some functions to do with vsyscalls and signals.
39    This code runs on the simulated CPU.
40 */
41         
42 /*---------------------- x86-linux ----------------------*/
43 #if defined(VGP_x86_linux)
44
45 #       define UD2_16     ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
46 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
47 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
48 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
49 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
50
51         /* a leading page of unexecutable code */
52         UD2_PAGE
53
54 .global VG_(trampoline_stuff_start)
55 VG_(trampoline_stuff_start):
56
57 .global VG_(x86_linux_SUBST_FOR_sigreturn)
58 VG_(x86_linux_SUBST_FOR_sigreturn):
59         /* This is a very specific sequence which GDB uses to
60            recognize signal handler frames.  Also gcc: see
61            x86_fallback_frame_state() in
62            gcc-4.1.0/gcc/config/i386/linux-unwind.h */
63         popl    %eax
64         movl    $ __NR_sigreturn, %eax
65         int     $0x80
66         ud2
67
68 .global VG_(x86_linux_SUBST_FOR_rt_sigreturn)
69 VG_(x86_linux_SUBST_FOR_rt_sigreturn):
70         /* Likewise for rt signal frames */
71         movl    $ __NR_rt_sigreturn, %eax
72         int     $0x80
73         ud2
74
75 /* There's no particular reason that this needs to be handwritten
76    assembly, but since that's what this file contains, here's a
77    simple index implementation (written in C and compiled by gcc.)
78
79    unsigned char* REDIR_FOR_index ( const char* s, int c ) 
80    { 
81       unsigned char  ch = (unsigned char)((unsigned int)c); 
82       unsigned char* p  = (unsigned char*)s; 
83       while (1) { 
84          if (*p == ch) return p;
85          if (*p == 0)  return 0; 
86          p++; 
87       } 
88    }
89 */
90 .global VG_(x86_linux_REDIR_FOR_index)
91 .type   VG_(x86_linux_REDIR_FOR_index), @function
92 VG_(x86_linux_REDIR_FOR_index):
93         pushl   %ebp
94         movl    %esp, %ebp
95         movl    8(%ebp), %eax
96         movzbl  12(%ebp), %ecx
97         movzbl  (%eax), %edx
98         cmpb    %dl, %cl
99         jne     .L9
100         jmp     .L2
101 .L11:
102         addl    $1, %eax
103         movzbl  (%eax), %edx
104         cmpb    %dl, %cl
105         je      .L2
106 .L9:
107         testb   %dl, %dl
108         jne     .L11
109         xorl    %eax, %eax
110 .L2:
111         popl    %ebp
112         ret
113 .size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index)
114
115 /* There's no particular reason that this needs to be handwritten
116    assembly, but since that's what this file contains, here's a
117    simple strlen implementation (written in C and compiled by gcc.)
118 */
119 .global VG_(x86_linux_REDIR_FOR_strlen)
120 .type   VG_(x86_linux_REDIR_FOR_strlen), @function
121 VG_(x86_linux_REDIR_FOR_strlen):
122         pushl   %ebp
123         movl    %esp, %ebp
124         movl    8(%ebp), %edx
125         movl    %edx, %eax
126         jmp     2f
127 1:      incl    %eax
128 2:      cmpb    $0, (%eax)
129         jne     1b
130         subl    %edx, %eax
131         popl    %ebp
132         ret
133 .size VG_(x86_linux_REDIR_FOR_strlen), .-VG_(x86_linux_REDIR_FOR_strlen)
134
135
136 .global VG_(trampoline_stuff_end)
137 VG_(trampoline_stuff_end):
138
139         /* and a trailing page of unexecutable code */
140         UD2_PAGE
141
142 #       undef UD2_16
143 #       undef UD2_64
144 #       undef UD2_256
145 #       undef UD2_1024
146 #       undef UD2_PAGE
147         
148 /*---------------------- amd64-linux ----------------------*/
149 #else
150 #if defined(VGP_amd64_linux)
151
152 #       define UD2_16     ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
153 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
154 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
155 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
156 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
157
158         /* a leading page of unexecutable code */
159         UD2_PAGE
160
161 .global VG_(trampoline_stuff_start)
162 VG_(trampoline_stuff_start):
163
164 .global VG_(amd64_linux_SUBST_FOR_rt_sigreturn)
165 VG_(amd64_linux_SUBST_FOR_rt_sigreturn):
166         /* This is a very specific sequence which GDB uses to
167            recognize signal handler frames. */
168         movq    $__NR_rt_sigreturn, %rax
169         syscall
170         ud2
171
172 .global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
173 .type   VG_(amd64_linux_REDIR_FOR_vgettimeofday), @function
174 VG_(amd64_linux_REDIR_FOR_vgettimeofday):
175 .LfnB2:
176         movq    $__NR_gettimeofday, %rax
177         syscall
178         ret
179 .LfnE2:
180 .size VG_(amd64_linux_REDIR_FOR_vgettimeofday), .-.LfnB2
181         
182 .global VG_(amd64_linux_REDIR_FOR_vtime)
183 .type   VG_(amd64_linux_REDIR_FOR_vtime), @function
184 VG_(amd64_linux_REDIR_FOR_vtime):
185 .LfnB3: 
186         movq    $__NR_time, %rax
187         syscall
188         ret
189 .LfnE3:
190 .size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
191
192 /* There's no particular reason that this needs to be handwritten
193    assembly, but since that's what this file contains, here's a
194    simple strlen implementation (written in C and compiled by gcc.)
195 */
196 .global VG_(amd64_linux_REDIR_FOR_strlen)
197 .type   VG_(amd64_linux_REDIR_FOR_strlen), @function
198 VG_(amd64_linux_REDIR_FOR_strlen):
199 .LfnB4:
200         xorl    %eax, %eax
201         cmpb    $0, (%rdi)
202         movq    %rdi, %rdx
203         je      .L41
204 .L40:   addq    $1, %rdx
205         cmpb    $0, (%rdx)
206         jne     .L40
207         movq    %rdx, %rax
208         subq    %rdi, %rax
209 .L41:   ret
210 .LfnE4:
211 .size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
212
213
214 /* A CIE for the above three functions, followed by their FDEs */
215         .section .eh_frame,"a",@progbits
216 .Lframe1:
217         .long   .LEcie1-.LScie1
218 .LScie1:
219         .long   0x0
220         .byte   0x1
221         .string "zR"
222         .uleb128 0x1
223         .sleb128 -8
224         .byte   0x10
225         .uleb128 0x1
226         .byte   0x3
227         .byte   0xc
228         .uleb128 0x7
229         .uleb128 0x8
230         .byte   0x90
231         .uleb128 0x1
232         .align 8
233 .LEcie1:
234 .LSfde2:
235         .long   .LEfde2-.LASfde2
236 .LASfde2:
237         .long   .LASfde2-.Lframe1
238         .long   .LfnB2
239         .long   .LfnE2-.LfnB2
240         .uleb128 0x0
241         .align 8
242 .LEfde2:
243 .LSfde3:
244         .long   .LEfde3-.LASfde3
245 .LASfde3:
246         .long   .LASfde3-.Lframe1
247         .long   .LfnB3
248         .long   .LfnE3-.LfnB3
249         .uleb128 0x0
250         .align 8
251 .LEfde3:
252 .LSfde4:
253         .long   .LEfde4-.LASfde4
254 .LASfde4:
255         .long   .LASfde4-.Lframe1
256         .long   .LfnB4
257         .long   .LfnE4-.LfnB4
258         .uleb128 0x0
259         .align 8
260 .LEfde4:
261         .previous
262
263 .global VG_(trampoline_stuff_end)
264 VG_(trampoline_stuff_end):
265
266         /* and a trailing page of unexecutable code */
267         UD2_PAGE
268
269 #       undef UD2_16
270 #       undef UD2_64
271 #       undef UD2_256
272 #       undef UD2_1024
273 #       undef UD2_PAGE
274
275 /*---------------- ppc32-linux ----------------*/
276 #else
277 #if defined(VGP_ppc32_linux)
278
279 #       define UD2_16     trap ; trap ; trap; trap
280 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
281 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
282 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
283 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
284
285         /* a leading page of unexecutable code */
286         UD2_PAGE
287
288 .global VG_(trampoline_stuff_start)
289 VG_(trampoline_stuff_start):
290
291 .global VG_(ppc32_linux_SUBST_FOR_sigreturn)
292 VG_(ppc32_linux_SUBST_FOR_sigreturn):
293         li 0,__NR_sigreturn
294         sc
295         .long 0 /*illegal insn*/
296
297 .global VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
298 VG_(ppc32_linux_SUBST_FOR_rt_sigreturn):
299         li 0,__NR_rt_sigreturn
300         sc
301         .long 0 /*illegal insn*/
302         
303 /* There's no particular reason that this needs to be handwritten
304    assembly, but since that's what this file contains, here's a
305    simple strlen implementation (written in C and compiled by gcc.)
306 */
307 .global VG_(ppc32_linux_REDIR_FOR_strlen)
308 .type   VG_(ppc32_linux_REDIR_FOR_strlen), @function
309 VG_(ppc32_linux_REDIR_FOR_strlen):
310         lbz 4,0(3)
311         li 9,0
312         cmpwi 0,4,0
313         beq- 0,.L18
314 .L19:
315         lbzu 5,1(3)
316         addi 9,9,1
317         cmpwi 0,5,0
318         bne+ 0,.L19
319 .L18:
320         mr 3,9
321         blr
322 .size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
323
324 /* Ditto strcmp */
325 .global VG_(ppc32_linux_REDIR_FOR_strcmp)
326 .type   VG_(ppc32_linux_REDIR_FOR_strcmp), @function
327 VG_(ppc32_linux_REDIR_FOR_strcmp):
328 .L20:
329         lbz 0,0(3)
330         cmpwi 7,0,0
331         bne- 7,.L21
332         lbz 0,0(4)
333         li 11,0
334         cmpwi 7,0,0
335         beq- 7,.L22
336 .L21:
337         lbz 0,0(3)
338         li 11,-1
339         cmpwi 7,0,0
340         beq- 7,.L22
341         lbz 0,0(4)
342         li 11,1
343         cmpwi 7,0,0
344         beq- 7,.L22
345         lbz 9,0(3)
346         lbz 0,0(4)
347         li 11,-1
348         cmplw 7,9,0
349         blt- 7,.L22
350         lbz 9,0(3)
351         lbz 0,0(4)
352         li 11,1
353         addi 3,3,1
354         addi 4,4,1
355         cmplw 7,9,0
356         ble+ 7,.L20
357 .L22:
358         mr 3,11
359         blr
360 .size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
361
362 /* Ditto index/strchr */
363 .global VG_(ppc32_linux_REDIR_FOR_strchr)
364 .type   VG_(ppc32_linux_REDIR_FOR_strchr), @function
365 VG_(ppc32_linux_REDIR_FOR_strchr):
366         lbz 0,0(3)
367         rlwinm 4,4,0,0xff
368         cmpw 7,4,0
369         beqlr 7
370         cmpwi 7,0,0
371         bne 7,.L308
372         b .L304
373 .L309:  
374         beq 6,.L304
375 .L308:  
376         lbzu 0,1(3)
377         cmpw 7,4,0
378         cmpwi 6,0,0
379         bne 7,.L309
380         blr
381 .L304:  
382         li 3,0
383         blr
384 .size   VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
385         
386 .global VG_(trampoline_stuff_end)
387 VG_(trampoline_stuff_end):
388
389         /* and a trailing page of unexecutable code */
390         UD2_PAGE
391
392 #       undef UD2_16
393 #       undef UD2_64
394 #       undef UD2_256
395 #       undef UD2_1024
396 #       undef UD2_PAGE
397
398 /*---------------- ppc64-linux ----------------*/
399 #else
400 #if defined(VGP_ppc64_linux)
401
402 #       define UD2_16     trap ; trap ; trap; trap
403 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
404 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
405 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
406 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
407
408         /* a leading page of unexecutable code */
409         UD2_PAGE
410
411 .global VG_(trampoline_stuff_start)
412 VG_(trampoline_stuff_start):
413
414 .global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn)
415 VG_(ppc64_linux_SUBST_FOR_rt_sigreturn):
416         li 0,__NR_rt_sigreturn
417         sc
418         .long 0 /*illegal insn*/
419
420         /* See comment in pub_core_trampoline.h for what this is for */
421 .global VG_(ppctoc_magic_redirect_return_stub)
422 VG_(ppctoc_magic_redirect_return_stub):
423         trap
424
425         /* this function is written using the "dotless" ABI convention */
426         .align 2
427         .globl VG_(ppc64_linux_REDIR_FOR_strlen)
428         .section        ".opd","aw"
429         .align 3
430 VG_(ppc64_linux_REDIR_FOR_strlen):
431         .quad   .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
432         .previous
433         .size   VG_(ppc64_linux_REDIR_FOR_strlen), \
434                         .L0end-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
435         .type   VG_(ppc64_linux_REDIR_FOR_strlen), @function
436
437 .L.VG_(ppc64_linux_REDIR_FOR_strlen):
438         mr 9,3
439         lbz 0,0(3)
440         li 3,0
441         cmpwi 7,0,0
442         beqlr 7
443         li 3,0
444 .L01:
445         addi 0,3,1
446         extsw 3,0
447         lbzx 0,9,3
448         cmpwi 7,0,0
449         bne 7,.L01
450         blr
451         .long 0
452         .byte 0,0,0,0,0,0,0,0
453 .L0end:
454
455         /* this function is written using the "dotless" ABI convention */
456         .align 2
457         .globl VG_(ppc64_linux_REDIR_FOR_strchr)
458         .section        ".opd","aw"
459         .align 3
460 VG_(ppc64_linux_REDIR_FOR_strchr):
461         .quad   .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
462         .previous
463         .size   VG_(ppc64_linux_REDIR_FOR_strchr), \
464                         .L1end-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
465         .type   VG_(ppc64_linux_REDIR_FOR_strchr),@function
466         
467 .L.VG_(ppc64_linux_REDIR_FOR_strchr):
468         lbz 0,0(3)
469         rldicl 4,4,0,56
470         cmpw 7,4,0
471         beqlr 7
472         cmpdi 7,0,0
473         bne 7,.L18
474         b .L14
475 .L19:   
476         beq 6,.L14
477 .L18:   
478         lbzu 0,1(3)
479         cmpw 7,4,0
480         cmpdi 6,0,0
481         bne 7,.L19
482         blr
483 .L14:   
484         li 3,0
485         blr
486         .long 0
487         .byte 0,0,0,0,0,0,0,0
488 .L1end:
489
490         
491 .global VG_(trampoline_stuff_end)
492 VG_(trampoline_stuff_end):
493
494         /* and a trailing page of unexecutable code */
495         UD2_PAGE
496
497 #       undef UD2_16
498 #       undef UD2_64
499 #       undef UD2_256
500 #       undef UD2_1024
501 #       undef UD2_PAGE
502
503 /*---------------- ppc32-linux ----------------*/
504
505 #elif defined(VGP_arm_linux)
506
507 #       define UD2_4      .word 0xFFFFFFFF
508 #       define UD2_16     UD2_4    ; UD2_4    ; UD2_4    ; UD2_4
509 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
510 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
511 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
512 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
513
514         /* a leading page of unexecutable code */
515         UD2_PAGE
516
517 .global VG_(trampoline_stuff_start)
518 VG_(trampoline_stuff_start):
519
520 .global VG_(arm_linux_REDIR_FOR_strlen)
521 VG_(arm_linux_REDIR_FOR_strlen):
522         mov     r2, r0
523         ldrb    r0, [r0, #0]    @ zero_extendqisi2
524         @ lr needed for prologue
525         cmp     r0, #0
526         bxeq    lr
527         mov     r0, #0
528 .L5:
529         add     r0, r0, #1
530         ldrb    r3, [r0, r2]    @ zero_extendqisi2
531         cmp     r3, #0
532         bne     .L5
533         bx      lr
534         UD2_4
535
536 //.global VG_(arm_linux_REDIR_FOR_index)
537 //VG_(arm_linux_REDIR_FOR_index):
538 //      ldrb    r3, [r0, #0]    @ zero_extendqisi2
539 //      and     r1, r1, #255
540 //      cmp     r3, r1
541 //      @ lr needed for prologue
542 //      bne     .L9
543 //      bx      lr
544 //.L12:
545 //      ldrb    r3, [r0, #1]!   @ zero_extendqisi2
546 //      cmp     r3, r1
547 //      beq     .L11
548 //.L9:
549 //      cmp     r3, #0
550 //      bne     .L12
551 //      mov     r0, #0
552 //      bx      lr
553 //.L11:
554 //      bx      lr
555 //      UD2_4
556
557 .global VG_(arm_linux_REDIR_FOR_memcpy)
558 VG_(arm_linux_REDIR_FOR_memcpy):
559         stmfd   sp!, {r4, r5, lr}
560         subs    lr, r2, #0
561         mov     r5, r0
562         beq     .L2
563         cmp     r0, r1
564         bls     .L4
565         add     r3, r0, lr
566         add     r1, lr, r1
567         cmp     lr, #3
568         sub     r4, r3, #1
569         sub     r0, r1, #1
570         ble     .L28
571         sub     ip, r3, #5
572         sub     r1, r1, #5
573 .L8:
574         ldrb    r3, [r1, #4]    @ zero_extendqisi2
575         sub     lr, lr, #4
576         strb    r3, [ip, #4]
577         ldrb    r2, [r1, #3]    @ zero_extendqisi2
578         cmp     lr, #3
579         strb    r2, [ip, #3]
580         ldrb    r3, [r1, #2]    @ zero_extendqisi2
581         mov     r4, ip
582         strb    r3, [ip, #2]
583         ldrb    r2, [r1, #1]    @ zero_extendqisi2
584         mov     r0, r1
585         strb    r2, [ip, #1]
586         sub     r1, r1, #4
587         sub     ip, ip, #4
588         bgt     .L8
589         cmp     lr, #0
590         beq     .L2
591 .L28:
592         sub     r2, lr, #1
593 .L21:
594         sub     r2, r2, #1
595         ldrb    r3, [r0], #-1   @ zero_extendqisi2
596         cmn     r2, #1
597         strb    r3, [r4], #-1
598         bne     .L21
599 .L2:
600         mov     r0, r5
601         ldmfd   sp!, {r4, r5, pc}
602 .L4:
603         bcs     .L2
604         cmp     lr, #3
605         mov     ip, r0
606         ble     .L29
607 .L19:
608         ldrb    r3, [r1, #0]    @ zero_extendqisi2
609         sub     lr, lr, #4
610         strb    r3, [ip, #0]
611         ldrb    r2, [r1, #1]    @ zero_extendqisi2
612         cmp     lr, #3
613         strb    r2, [ip, #1]
614         ldrb    r3, [r1, #2]    @ zero_extendqisi2
615         strb    r3, [ip, #2]
616         ldrb    r2, [r1, #3]    @ zero_extendqisi2
617         add     r1, r1, #4
618         strb    r2, [ip, #3]
619         add     ip, ip, #4
620         bgt     .L19
621         cmp     lr, #0
622         beq     .L2
623 .L29:
624         sub     r2, lr, #1
625 .L20:
626         sub     r2, r2, #1
627         ldrb    r3, [r1], #1    @ zero_extendqisi2
628         cmn     r2, #1
629         strb    r3, [ip], #1
630         bne     .L20
631         mov     r0, r5
632         ldmfd   sp!, {r4, r5, pc}
633         UD2_4
634
635 .global VG_(trampoline_stuff_end)
636 VG_(trampoline_stuff_end):
637
638         /* and a trailing page of unexecutable code */
639         UD2_PAGE
640
641 #       undef UD2_4
642 #       undef UD2_16
643 #       undef UD2_64
644 #       undef UD2_256
645 #       undef UD2_1024
646 #       undef UD2_PAGE
647         
648 /*---------------- ppc32-aix5 ----------------*/
649 #else
650 #if defined(VGP_ppc32_aix5)
651
652 #       define UD2_16     trap ; trap ; trap; trap
653 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
654 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
655 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
656 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
657
658         .csect .text[PR]
659
660         /* a leading page of unexecutable code */
661         UD2_PAGE
662
663 .globl VG_(trampoline_stuff_start)
664 VG_(trampoline_stuff_start):
665
666 /* See pub_core_trampoline.h for an explaination of this.  Also
667    see pub_core_initimg.h, struct AIX5PreloadPage.  On entry, r3
668    points to an AIX5PreloadPage structure.  Note we can only 
669    use r2-r10 as scratch registers here since those are the
670    only ones restored from the preload page when finally
671    starting the client. */
672 .globl VG_(ppc32_aix5_do_preloads_then_start_client)
673 VG_(ppc32_aix5_do_preloads_then_start_client):
674         stwu    1,-1024(1)
675         stw     3,512(1)        /* stash r3 512 bytes up stack */
676
677         /* Try to load .../vgpreload_core.so */
678         lwz     2,0(3)          /* r2 = __NR___loadx */
679         lwz     5,20(3)         /* r5 = off_preloadcorename */
680         add     6,3,5           /* r6 = preloadcorename */
681         addis   1,1,-4
682         bl      do___loadx
683         addis   1,1,4
684         cmpwi   0,3,0
685         beq     .Lfailed
686
687         /* Try to load .../vgpreload_tool.so, if it exists */
688         lwz     3,512(1)        /* restore r3 */
689         lwz     2,0(3)          /* r2 = __NR___loadx */
690         lwz     5,24(3)         /* r5 = off_preloadtoolname */
691         cmpwi   0,5,0           /* skip tool preload if */
692         beq     .Ltry_preload   /* name not present */
693         add     6,3,5           /* r6 = preloadtoolname */
694         addis   1,1,-4
695         bl      do___loadx
696         addis   1,1,4
697         cmpwi   0,3,0
698         beq     .Lfailed
699
700 .Ltry_preload:
701         /* Try to load the LD_PRELOAD= file, if it exists */
702         lwz     3,512(1)        /* restore r3 */
703         lwz     2,0(3)          /* r2 = __NR___loadx */
704         lwz     5,28(3)         /* r5 = off_ld_preloadname */
705         cmpwi   0,5,0           /* skip ld_preload if */
706         beq     .Lstart_client  /* name not present */
707         add     6,3,5           /* r6 = ld_preloadname */
708         addis   1,1,-4
709         bl      do___loadx
710         addis   1,1,4
711         cmpwi   0,3,0
712         beq     .Lfailed
713         
714 .Lstart_client:
715         /* Success.  Restore r2-r10 from preloadpage-> and start
716         the client. */
717         lwz     3,512(1)        /* restore r3 */
718         addi    1,1,1024
719         lwz     2,32+4(3)       /* preloadpage->client_start */
720         mtctr   2
721         lwz     2,40+4(3)       /* preloadpage->r2 */
722         lwz     4,56+4(3)       /* preloadpage->r4 */
723         lwz     5,64+4(3)       /* preloadpage->r5 */
724         lwz     6,72+4(3)       /* preloadpage->r6 */
725         lwz     7,80+4(3)       /* preloadpage->r7 */
726         lwz     8,88+4(3)       /* preloadpage->r8 */
727         lwz     9,96+4(3)       /* preloadpage->r9 */
728         lwz     10,104+4(3)     /* preloadpage->r10 */
729         lwz     3,48+4(3)       /* preloadpage->r3 */
730         bctr
731         /*NOTREACHED*/
732         trap
733
734 .Lfailed:
735         /* __loadx barfed for some reason.  Print the error
736         message and get out. */
737         /* First the error msg */
738         lwz     3,512(1)        /* restore r3 */
739         lwz     2,4(3)          /* r2 = __NR_kwrite */
740         lwz     4,12(3)         /* r4 = offset of err msg */
741         add     4,4,3           /* r4 = err msg */
742         lwz     5,16(3)         /* r5 = length err msg */
743         li      3,2             /* r3 = stderr */
744         bl      do_syscall
745         /* now call the diagnosis fn */
746         lwz     3,512(1)        /* restore r3 */
747         lwz     4,112(3)        /* preloadpage->p_diagnose_load_failure */
748         lwz     2,4(4)          /* get its TOC ptr */
749         lwz     4,0(4)          /* get its entry point */
750         mtlr    4
751         blrl
752         /* Now do _exit(1) */
753         lwz     3,512(1)        /* restore r3 */
754         lwz     2,8(3)          /* r2 = __NR_exit */
755         li      3,1             /* doing _exit(1) */
756         addi    1,1,1024        /* fix stack pointer */
757         bl      do_syscall
758         /*NOTREACHED*/
759         trap
760         
761 do___loadx:
762         /* On entry: r2 = __NR___loadx, r6 = name of module */
763         li      3,1
764         slwi    3,3,24  /* r3 = 0x1000000 = VKI_DL_LOAD */
765         mr      4,1
766         lis     5,3
767         li      7,0
768         li      8,0
769         li      9,0
770         li      10,0
771 do_syscall:
772         crorc   6,6,6
773         sc
774         trap
775         /* sc continues at 'lr', hence this 
776         constitutes an automatic return */
777
778
779         /* See comment in pub_core_trampoline.h for what this is for */
780 .globl VG_(ppctoc_magic_redirect_return_stub)
781 VG_(ppctoc_magic_redirect_return_stub):
782         trap
783         
784 .globl VG_(trampoline_stuff_end)
785 VG_(trampoline_stuff_end):
786
787         /* and a trailing page of unexecutable code */
788         UD2_PAGE
789
790 #       undef UD2_16
791 #       undef UD2_64
792 #       undef UD2_256
793 #       undef UD2_1024
794 #       undef UD2_PAGE
795
796 /*---------------- ppc64-aix5 ----------------*/
797 #else
798 #if defined(VGP_ppc64_aix5)
799
800 #       define UD2_16     trap ; trap ; trap; trap
801 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
802 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
803 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
804 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
805
806 .globl VG_(trampoline_stuff_start)
807 VG_(trampoline_stuff_start):
808 /* See pub_core_trampoline.h for an explaination of this.  Also
809    see pub_core_initimg.h, struct AIX5PreloadPage.  On entry, r3
810    points to an AIX5PreloadPage structure.  Note we can only 
811    use r2-r10 as scratch registers here since those are the
812    only ones restored from the preload page when finally
813    starting the client. */
814 .globl VG_(ppc64_aix5_do_preloads_then_start_client)
815 VG_(ppc64_aix5_do_preloads_then_start_client):
816         stdu    1,-1024(1)
817         std     3,512(1)        /* stash r3 512 bytes up stack */
818
819         /* Try to load .../vgpreload_core.so */
820         lwz     2,0(3)          /* r2 = __NR_kload */
821         lwz     5,20(3)         /* r5 = off_preloadcorename */
822         add     3,3,5           /* r6 = preloadcorename */
823         bl      do_kload
824         cmpdi   0,3,0
825         beq     .Lfailed
826
827         /* Try to load .../vgpreload_tool.so, if it exists */
828         ld      3,512(1)        /* restore r3 */
829         lwz     2,0(3)          /* r2 = __NR_kload */
830         lwz     5,24(3)         /* r5 = off_preloadtoolname */
831         cmpwi   0,5,0           /* skip tool preload if */
832         beq     .Ltry_preload   /* name not present */
833         add     3,3,5           /* r6 = preloadtoolname */
834         bl      do_kload
835         cmpdi   0,3,0
836         beq     .Lfailed
837
838 .Ltry_preload:
839         /* Try to load the LD_PRELOAD= file, if it exists */
840         ld      3,512(1)        /* restore r3 */
841         lwz     2,0(3)          /* r2 = __NR_kload */
842         lwz     5,28(3)         /* r5 = off_ld_preloadname */
843         cmpwi   0,5,0           /* skip ld_preload if */
844         beq     .Lstart_client  /* name not present */
845         add     3,3,5           /* r6 = ld_preloadname */
846         bl      do_kload
847         cmpdi   0,3,0
848         beq     .Lfailed
849         
850 .Lstart_client:
851         /* Success.  Restore r2-r10 from preloadpage-> and start
852         the client. */
853         ld      3,512(1)        /* restore r3 */
854         addi    1,1,1024
855         ld      2,32+0(3)       /* preloadpage->client_start */
856         mtctr   2
857         ld      2,40+0(3)       /* preloadpage->r2 */
858         ld      4,56+0(3)       /* preloadpage->r4 */
859         ld      5,64+0(3)       /* preloadpage->r5 */
860         ld      6,72+0(3)       /* preloadpage->r6 */
861         ld      7,80+0(3)       /* preloadpage->r7 */
862         ld      8,88+0(3)       /* preloadpage->r8 */
863         ld      9,96+0(3)       /* preloadpage->r9 */
864         ld      10,104+0(3)     /* preloadpage->r10 */
865         ld      3,48+0(3)       /* preloadpage->r3 */
866         bctr
867         /*NOTREACHED*/
868         trap
869
870 .Lfailed:
871         /* __loadx barfed for some reason.  Print the error
872         message and get out. */
873         /* First the error msg */
874         ld      3,512(1)        /* restore r3 */
875         lwz     2,4(3)          /* r2 = __NR_kwrite */
876         lwz     4,12(3)         /* r4 = offset of err msg */
877         add     4,4,3           /* r4 = err msg */
878         lwz     5,16(3)         /* r5 = length err msg */
879         li      3,2             /* r3 = stderr */
880         bl      do_syscall
881         /* now call the diagnosis fn */
882         ld      3,512(1)        /* restore r3 */
883         ld      4,112(3)        /* preloadpage->p_diagnose_load_failure */
884         ld      11,16(4)
885         ld      2,8(4)          /* get its TOC ptr */
886         ld      4,0(4)          /* get its entry point */
887         mtlr    4
888         blrl
889         /* Now do _exit(1) */
890         lwz     3,512(1)        /* restore r3 */
891         lwz     2,8(3)          /* r2 = __NR_exit */
892         li      3,1             /* doing _exit(1) */
893         addi    1,1,1024        /* fix stack pointer */
894         bl      do_syscall
895         /*NOTREACHED*/
896         trap
897         
898 do_kload:
899         /* On entry: r2 = __NR_kload,   r3 = name of module */
900         li      4,0
901         li      5,0
902         li      6,0
903         li      7,0
904         li      8,0
905         li      9,0
906         li      10,0
907 do_syscall:
908         crorc   6,6,6
909         sc
910         /* sc continues at 'lr', hence this 
911         constitutes an automatic return */
912
913         /* See comment in pub_core_trampoline.h for what this is for */
914 .globl VG_(ppctoc_magic_redirect_return_stub)
915 VG_(ppctoc_magic_redirect_return_stub):
916         trap
917         
918 .globl VG_(trampoline_stuff_end)
919 VG_(trampoline_stuff_end):
920
921         /* and a trailing page of unexecutable code */
922         UD2_PAGE
923
924 #       undef UD2_16
925 #       undef UD2_64
926 #       undef UD2_256
927 #       undef UD2_1024
928 #       undef UD2_PAGE
929
930 /*---------------- x86-darwin ----------------*/
931 #else
932 #if defined(VGP_x86_darwin)
933
934         /* a leading page of unexecutable code */
935 .fill 2048, 2, 0x0b0f /* `ud2` */
936
937 .globl VG_(trampoline_stuff_start)
938 VG_(trampoline_stuff_start):
939
940 .globl VG_(x86_darwin_SUBST_FOR_sigreturn)
941 VG_(x86_darwin_SUBST_FOR_sigreturn):
942         /* XXX does this need to have any special form? (cf x86-linux
943         version) */
944         movl    $ __NR_DARWIN_FAKE_SIGRETURN, %eax
945         int     $0x80
946         ud2
947
948 .globl VG_(x86_darwin_REDIR_FOR_strlen)
949 VG_(x86_darwin_REDIR_FOR_strlen):
950         movl    4(%esp), %edx
951         movl    %edx, %eax
952         jmp     1f
953 0:
954         incl    %eax
955 1:
956         cmpb    $0, (%eax)
957         jne     0b
958         subl    %edx, %eax
959         ret
960
961 .globl VG_(x86_darwin_REDIR_FOR_strcat)
962 VG_(x86_darwin_REDIR_FOR_strcat):
963         pushl   %esi
964         movl    8(%esp), %esi
965         movl    12(%esp), %ecx
966         movl    %esi, %edx
967         jmp     1f
968 0:
969         incl    %edx
970 1:
971         cmpb    $0, (%edx)
972         jne     0b
973 2:
974         movzbl  (%ecx), %eax
975         incl    %ecx
976         movb    %al, (%edx)
977         incl    %edx
978         testb   %al, %al
979         jne     2b
980         movl    %esi, %eax
981         popl    %esi
982         ret
983
984
985 .globl VG_(x86_darwin_REDIR_FOR_strcmp)
986 VG_(x86_darwin_REDIR_FOR_strcmp):
987         movl    4(%esp), %edx
988         movl    8(%esp), %ecx
989         jmp     1f
990 0:
991         incl    %edx
992         incl    %ecx
993 1:
994         movzbl  (%edx), %eax
995         testb   %al, %al
996         je      2f
997         cmpb    (%ecx), %al
998         je      0b
999 2:
1000         movzbl  (%ecx),%edx
1001         movzbl  %al,%eax
1002         subl    %edx, %eax
1003         ret
1004
1005
1006 .globl VG_(x86_darwin_REDIR_FOR_strcpy)
1007 VG_(x86_darwin_REDIR_FOR_strcpy):
1008         pushl   %ebp
1009         movl    %esp, %ebp
1010         pushl   %esi
1011         movl    8(%ebp), %esi
1012         movl    12(%ebp), %ecx
1013         movl    %esi, %edx
1014         jmp     1f
1015 0:
1016         incl    %ecx
1017         incl    %edx
1018 1:
1019         movzbl  (%ecx), %eax
1020         testb   %al, %al
1021         movb    %al, (%edx)
1022         jne     0b
1023         movl    %esi, %eax
1024         popl    %esi
1025         leave
1026         ret
1027
1028 .globl VG_(x86_darwin_REDIR_FOR_strlcat)
1029 VG_(x86_darwin_REDIR_FOR_strlcat):
1030         pushl   %ebp
1031         movl    %esp, %ebp
1032         pushl   %edi
1033         pushl   %esi
1034         subl    $16, %esp
1035         movl    8(%ebp), %esi
1036         movl    16(%ebp), %ecx
1037         movl    %esi, %edx
1038         leal    (%ecx,%esi), %eax
1039         jmp     1f
1040 0:
1041         incl    %edx
1042 1:
1043         cmpl    %edx, %eax
1044         je      2f
1045         cmpb    $0, (%edx)
1046         jne     0b
1047 2:
1048         movl    %edx, %edi
1049         subl    %esi, %edi
1050         movl    %ecx, %esi
1051         subl    %edi, %esi
1052         je      3f
1053         movl    12(%ebp), %eax
1054         jmp     6f
1055 3:
1056         movl    12(%ebp), %eax
1057         movl    %eax, (%esp)
1058         call    VG_(x86_darwin_REDIR_FOR_strlen)
1059         jmp     7f
1060 4:
1061         cmpl    $1, %esi
1062         je      5f
1063         movb    %cl, (%edx)
1064         decl    %esi
1065         incl    %edx
1066 5:
1067         incl    %eax
1068 6:
1069         movzbl  (%eax), %ecx
1070         testb   %cl, %cl
1071         jne     4b
1072         movb    $0, (%edx)
1073         subl    12(%ebp), %eax
1074 7:
1075         addl    $16, %esp
1076         leal    (%edi,%eax), %eax
1077         popl    %esi
1078         popl    %edi
1079         leave
1080         ret
1081         
1082         
1083 .globl VG_(trampoline_stuff_end)
1084 VG_(trampoline_stuff_end):
1085
1086         /* a trailing page of unexecutable code */
1087 .fill 2048, 2, 0x0b0f /* `ud2` */
1088
1089
1090 /*---------------- amd64-darwin ----------------*/
1091 #else
1092 #if defined(VGP_amd64_darwin)
1093
1094         /* a leading page of unexecutable code */
1095 .fill 2048, 2, 0x0b0f /* `ud2` */
1096
1097 .globl VG_(trampoline_stuff_start)
1098 VG_(trampoline_stuff_start):
1099
1100 .globl VG_(amd64_darwin_SUBST_FOR_sigreturn)
1101 VG_(amd64_darwin_SUBST_FOR_sigreturn):
1102         /* XXX does this need to have any special form? (cf x86-linux
1103         version) */
1104         movq    $ __NR_DARWIN_FAKE_SIGRETURN, %rax
1105         syscall
1106         ud2
1107
1108 .globl VG_(amd64_darwin_REDIR_FOR_strlen)
1109 VG_(amd64_darwin_REDIR_FOR_strlen):
1110         movq    %rdi, %rax
1111         jmp     1f
1112 0:
1113         incq    %rax
1114 1:
1115         cmpb    $0, (%rax)
1116         jne     0b
1117         subq    %rdi, %rax
1118         ret
1119
1120 .globl VG_(amd64_darwin_REDIR_FOR_strcat)
1121 VG_(amd64_darwin_REDIR_FOR_strcat):
1122         movq    %rdi, %rdx
1123         jmp     1f
1124 0:
1125         incq    %rdx
1126 1:
1127         cmpb    $0, (%rdx)
1128         jne     0b
1129 2:
1130         movzbl  (%rsi), %eax
1131         incq    %rsi
1132         movb    %al, (%rdx)
1133         incq    %rdx
1134         testb   %al, %al
1135         jne     2b
1136         movq    %rdi, %rax
1137         ret
1138
1139
1140 .globl VG_(amd64_darwin_REDIR_FOR_strcmp)
1141 VG_(amd64_darwin_REDIR_FOR_strcmp):
1142         jmp     1f
1143 0:
1144         incq    %rdi
1145         incq    %rsi
1146 1:
1147         movzbl  (%rdi), %eax
1148         testb   %al, %al
1149         je      2f
1150         cmpb    (%rsi), %al
1151         je      0b
1152 2:
1153         movzbl  (%rsi), %edx
1154         movzbl  %al, %eax
1155         subl    %edx, %eax
1156         ret
1157
1158 .globl VG_(amd64_darwin_REDIR_FOR_strcpy)
1159 VG_(amd64_darwin_REDIR_FOR_strcpy):
1160         pushq   %rbp
1161         movq    %rdi, %rdx
1162         movq    %rsp, %rbp
1163         jmp     1f
1164 0:
1165         incq    %rsi
1166         incq    %rdx
1167 1:
1168         movzbl  (%rsi), %eax
1169         testb   %al, %al
1170         movb    %al, (%rdx)
1171         jne     0b
1172         leave
1173         movq    %rdi, %rax
1174         ret
1175         
1176 .globl VG_(amd64_darwin_REDIR_FOR_strlcat)
1177 VG_(amd64_darwin_REDIR_FOR_strlcat):
1178         pushq   %rbp
1179         leaq    (%rdx,%rdi), %rax
1180         movq    %rdi, %rcx
1181         movq    %rsp, %rbp
1182         pushq   %rbx
1183         subq    $8, %rsp
1184         jmp     1f
1185 0:
1186         incq    %rcx
1187 1:
1188         cmpq    %rcx, %rax
1189         je      2f
1190         cmpb    $0, (%rcx)
1191         jne     0b
1192 2:
1193         movq    %rcx, %rbx
1194         subq    %rdi, %rbx
1195         movq    %rdx, %rdi
1196         subq    %rbx, %rdi
1197         je      3f
1198         movq    %rsi, %rax
1199         jmp     6f
1200 3:
1201         movq    %rsi, %rdi
1202         call    VG_(amd64_darwin_REDIR_FOR_strlen)
1203         jmp     7f
1204 4:
1205         cmpq    $1, %rdi
1206         je      5f
1207         movb    %dl, (%rcx)
1208         decq    %rdi
1209         incq    %rcx
1210 5:
1211         incq    %rax
1212 6:
1213         movzbl  (%rax), %edx
1214         testb   %dl, %dl
1215         jne     4b
1216         movb    $0, (%rcx)
1217         subq    %rsi, %rax
1218 7:
1219         leaq    (%rbx,%rax), %rax
1220         addq    $8, %rsp
1221         popq    %rbx
1222         leave
1223         ret
1224
1225 .globl VG_(amd64_darwin_REDIR_FOR_arc4random)
1226 VG_(amd64_darwin_REDIR_FOR_arc4random):
1227         /* not very random, hope dyld won't mind */
1228         movq    $0x76616c6772696e64, %rax
1229         ret
1230
1231 .globl VG_(trampoline_stuff_end)
1232 VG_(trampoline_stuff_end):
1233
1234         /* a trailing page of unexecutable code */
1235 .fill 2048, 2, 0x0b0f /* `ud2` */
1236
1237 /*---------------------- x86-l4re ----------------------*/
1238 #else
1239 #if defined(VGP_x86_l4re)
1240
1241 #       define UD2_16     ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
1242 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
1243 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
1244 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
1245 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
1246
1247         /* a leading page of unexecutable code */
1248         UD2_PAGE
1249
1250 .global VG_(trampoline_stuff_start)
1251 VG_(trampoline_stuff_start):
1252
1253 .global VG_(x86_l4re_SUBST_FOR_sigreturn)
1254 VG_(x86_l4re_SUBST_FOR_sigreturn):
1255         /* This is a very specific sequence which GDB uses to
1256            recognize signal handler frames.  Also gcc: see
1257            x86_fallback_frame_state() in
1258            gcc-4.1.0/gcc/config/i386/linux-unwind.h */
1259         popl    %eax
1260         movl    $0x0815, %eax
1261 /*        movl    $ __NR_sigreturn, %eax*/
1262         int     $0x80
1263         ud2
1264
1265 .global VG_(x86_l4re_SUBST_FOR_rt_sigreturn)
1266 VG_(x86_l4re_SUBST_FOR_rt_sigreturn):
1267         /* Likewise for rt signal frames */
1268         movl    $0x0815, %eax
1269 /*        movl    $ __NR_rt_sigreturn, %eax */
1270         int     $0x80
1271         ud2
1272
1273 /* There's no particular reason that this needs to be handwritten
1274    assembly, but since that's what this file contains, here's a
1275    simple index implementation (written in C and compiled by gcc.)
1276
1277    unsigned char* REDIR_FOR_index ( const char* s, int c ) 
1278    { 
1279       unsigned char  ch = (unsigned char)((unsigned int)c); 
1280       unsigned char* p  = (unsigned char*)s; 
1281       while (1) { 
1282          if (*p == ch) return p;
1283          if (*p == 0)  return 0; 
1284          p++; 
1285       } 
1286    }
1287 */
1288 .global VG_(x86_l4re_REDIR_FOR_index)
1289 .type   VG_(x86_l4re_REDIR_FOR_index), @function
1290 VG_(x86_l4re_REDIR_FOR_index):
1291         pushl   %ebp
1292         movl    %esp, %ebp
1293         movl    8(%ebp), %eax
1294         movzbl  12(%ebp), %ecx
1295         movzbl  (%eax), %edx
1296         cmpb    %dl, %cl
1297         jne     .L9
1298         jmp     .L2
1299 .L11:
1300         addl    $1, %eax
1301         movzbl  (%eax), %edx
1302         cmpb    %dl, %cl
1303         je      .L2
1304 .L9:
1305         testb   %dl, %dl
1306         jne     .L11
1307         xorl    %eax, %eax
1308 .L2:
1309         popl    %ebp
1310         ret
1311 .size VG_(x86_l4re_REDIR_FOR_index), .-VG_(x86_l4re_REDIR_FOR_index)
1312
1313 .global VG_(trampoline_stuff_end)
1314 VG_(trampoline_stuff_end):
1315
1316         /* and a trailing page of unexecutable code */
1317         UD2_PAGE
1318
1319 #       undef UD2_16
1320 #       undef UD2_64
1321 #       undef UD2_256
1322 #       undef UD2_1024
1323 #       undef UD2_PAGE
1324
1325 /*---------------- s390x-linux ----------------*/
1326 #else
1327 #if defined(VGP_s390x_linux)
1328
1329         /* a leading page of unexecutable code */
1330         .fill 2048, 2, 0x0000
1331
1332 .global VG_(trampoline_stuff_start)
1333 VG_(trampoline_stuff_start):
1334
1335 .global VG_(s390x_linux_SUBST_FOR_sigreturn)
1336 VG_(s390x_linux_SUBST_FOR_sigreturn):
1337         svc __NR_sigreturn
1338         .short 0
1339
1340 .global VG_(s390x_linux_SUBST_FOR_rt_sigreturn)
1341 VG_(s390x_linux_SUBST_FOR_rt_sigreturn):
1342         /* Old gcc unwinding code checks for a sig(_rt)_return svc and then
1343            for ra = cfa to decide if it is a sig_rt_frame or not. Since we
1344            set ra to this trampoline, but the cfa is still in the stack,
1345            the unwinder thinks, that this is a non-rt frame  and causes a
1346            crash in the gcc unwinder - which is used by the thread library
1347            and others. Therefore we add a lr 1,1 nop, to let the gcc
1348            unwinder bail out gracefully. This might also affect unwinding
1349            across the signal frame - tough luck. fixs390 */
1350         lr 1,1
1351         svc __NR_rt_sigreturn
1352         .short 0
1353
1354 .globl VG_(trampoline_stuff_end)
1355 VG_(trampoline_stuff_end):
1356         .fill 2048, 2, 0x0000
1357
1358 /*---------------- unknown ----------------*/
1359 #else
1360 #  error Unknown platform
1361
1362 #endif
1363 #endif
1364 #endif
1365 #endif
1366 #endif
1367 #endif
1368 #endif
1369 #endif
1370 #endif
1371 #endif
1372
1373 #if defined(VGO_linux)
1374 /* Let the linker know we don't need an executable stack */
1375 #  if defined(VGP_arm_linux)
1376    .section .note.GNU-stack,"",%progbits
1377 #  else        
1378    .section .note.GNU-stack,"",@progbits
1379 #  endif
1380 #endif
1381
1382 /*--------------------------------------------------------------------*/
1383 /*--- end                                                          ---*/
1384 /*--------------------------------------------------------------------*/