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