Add vbit-test-sec.vgtest and vbit-test-sec.stderr.exp to EXTRA_DIST.
[valgrind.git] / coregrind / m_trampoline.S
blob0488b54bdf2b10ee48add024ad315dd7edb65668
2 /*--------------------------------------------------------------------*/
3 /*--- Trampoline code page stuff.                   m_trampoline.S ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
10   Copyright (C) 2000-2017 Julian Seward 
11      jseward@acm.org
12   Copyright (C) 2006-2017 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.
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.
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.
30   The GNU General Public License is contained in the file COPYING.
33 #include "pub_core_basics_asm.h"
34 #include "pub_core_vkiscnums_asm.h"
36 /* ------------------ SIMULATED CPU HELPERS ------------------ */
37 /* 
38    Replacements for some functions to do with vsyscalls and signals.
39    This code runs on the simulated CPU.
41         
42 /*---------------------- x86-linux ----------------------*/
43 #if defined(VGP_x86_linux)
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  
51         /* a leading page of unexecutable code */
52         UD2_PAGE
54 .global VG_(trampoline_stuff_start)
55 VG_(trampoline_stuff_start):
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
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
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.)
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    }
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)
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.)
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)
136 .global VG_(trampoline_stuff_end)
137 VG_(trampoline_stuff_end):
139         /* and a trailing page of unexecutable code */
140         UD2_PAGE
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)
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  
158         /* a leading page of unexecutable code */
159         UD2_PAGE
161 .global VG_(trampoline_stuff_start)
162 VG_(trampoline_stuff_start):
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
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
192 .global VG_(amd64_linux_REDIR_FOR_vgetcpu)
193 .type   VG_(amd64_linux_REDIR_FOR_vgetcpu), @function
194 VG_(amd64_linux_REDIR_FOR_vgetcpu):
195 .LfnB4:
196         movq    $__NR_getcpu, %rax
197         syscall
198         ret
199 .LfnE4:
200 .size VG_(amd64_linux_REDIR_FOR_vgetcpu), .-.LfnB4
202 /* There's no particular reason that this needs to be handwritten
203    assembly, but since that's what this file contains, here's a
204    simple strlen implementation (written in C and compiled by gcc.)
206 .global VG_(amd64_linux_REDIR_FOR_strlen)
207 .type   VG_(amd64_linux_REDIR_FOR_strlen), @function
208 VG_(amd64_linux_REDIR_FOR_strlen):
209 .LfnB5:
210         xorl    %eax, %eax
211         cmpb    $0, (%rdi)
212         movq    %rdi, %rdx
213         je      .L41
214 .L40:   addq    $1, %rdx
215         cmpb    $0, (%rdx)
216         jne     .L40
217         movq    %rdx, %rax
218         subq    %rdi, %rax
219 .L41:   ret
220 .LfnE5:
221 .size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
223 .global VG_(amd64_linux_REDIR_FOR_index)
224 .type   VG_(amd64_linux_REDIR_FOR_index), @function
225 VG_(amd64_linux_REDIR_FOR_index):
226         movzbl  (%rdi), %eax
227         movl    %esi, %edx
228         cmpb    %sil, %al
229         jne     .L4
230         jmp     .L5
231 .L10:
232         addq    $1, %rdi
233         movzbl  (%rdi), %eax
234         cmpb    %dl, %al
235         je      .L5
236 .L4:
237         testb   %al, %al
238         jne     .L10
239         xorl    %eax, %eax
240         ret
241 .L5:
242         movq    %rdi, %rax
243         ret
244 .size VG_(amd64_linux_REDIR_FOR_index), .-VG_(amd64_linux_REDIR_FOR_index)
248 /* A CIE for the above four functions, followed by their FDEs */
249         .section .eh_frame,"a",@progbits
250 .Lframe1:
251         .long   .LEcie1-.LScie1
252 .LScie1:
253         .long   0x0
254         .byte   0x1
255         .string "zR"
256         .uleb128 0x1
257         .sleb128 -8
258         .byte   0x10
259         .uleb128 0x1
260         .byte   0x3
261         .byte   0xc
262         .uleb128 0x7
263         .uleb128 0x8
264         .byte   0x90
265         .uleb128 0x1
266         .align 8
267 .LEcie1:
268 .LSfde2:
269         .long   .LEfde2-.LASfde2
270 .LASfde2:
271         .long   .LASfde2-.Lframe1
272         .long   .LfnB2
273         .long   .LfnE2-.LfnB2
274         .uleb128 0x0
275         .align 8
276 .LEfde2:
277 .LSfde3:
278         .long   .LEfde3-.LASfde3
279 .LASfde3:
280         .long   .LASfde3-.Lframe1
281         .long   .LfnB3
282         .long   .LfnE3-.LfnB3
283         .uleb128 0x0
284         .align 8
285 .LEfde3:
286 .LSfde4:
287         .long   .LEfde4-.LASfde4
288 .LASfde4:
289         .long   .LASfde4-.Lframe1
290         .long   .LfnB4
291         .long   .LfnE4-.LfnB4
292         .uleb128 0x0
293         .align 8
294 .LEfde4:
295 .LSfde5:
296         .long   .LEfde5-.LASfde5
297 .LASfde5:
298         .long   .LASfde5-.Lframe1
299         .long   .LfnB5
300         .long   .LfnE5-.LfnB5
301         .uleb128 0x0
302         .align 8
303 .LEfde5:
304         .previous
306 .global VG_(trampoline_stuff_end)
307 VG_(trampoline_stuff_end):
309         /* and a trailing page of unexecutable code */
310         UD2_PAGE
312 #       undef UD2_16
313 #       undef UD2_64
314 #       undef UD2_256
315 #       undef UD2_1024
316 #       undef UD2_PAGE
318 /*---------------- ppc32-linux ----------------*/
319 #else
320 #if defined(VGP_ppc32_linux)
322 #       define UD2_16     trap ; trap ; trap; trap
323 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
324 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
325 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
326 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
328         /* a leading page of unexecutable code */
329         UD2_PAGE
331 .global VG_(trampoline_stuff_start)
332 VG_(trampoline_stuff_start):
334 .global VG_(ppc32_linux_SUBST_FOR_sigreturn)
335 VG_(ppc32_linux_SUBST_FOR_sigreturn):
336         li 0,__NR_sigreturn
337         sc
338         .long 0 /*illegal insn*/
340 .global VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
341 VG_(ppc32_linux_SUBST_FOR_rt_sigreturn):
342         li 0,__NR_rt_sigreturn
343         sc
344         .long 0 /*illegal insn*/
345         
346 /* There's no particular reason that this needs to be handwritten
347    assembly, but since that's what this file contains, here's a
348    simple strlen implementation (written in C and compiled by gcc.)
350 .global VG_(ppc32_linux_REDIR_FOR_strlen)
351 .type   VG_(ppc32_linux_REDIR_FOR_strlen), @function
352 VG_(ppc32_linux_REDIR_FOR_strlen):
353         lbz 4,0(3)
354         li 9,0
355         cmpwi 0,4,0
356         beq- 0,.L18
357 .L19:
358         lbzu 5,1(3)
359         addi 9,9,1
360         cmpwi 0,5,0
361         bne+ 0,.L19
362 .L18:
363         mr 3,9
364         blr
365 .size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
367 /* Ditto strcmp */
368 .global VG_(ppc32_linux_REDIR_FOR_strcmp)
369 .type   VG_(ppc32_linux_REDIR_FOR_strcmp), @function
370 VG_(ppc32_linux_REDIR_FOR_strcmp):
371 .L20:
372         lbz 0,0(3)
373         cmpwi 7,0,0
374         bne- 7,.L21
375         lbz 0,0(4)
376         li 11,0
377         cmpwi 7,0,0
378         beq- 7,.L22
379 .L21:
380         lbz 0,0(3)
381         li 11,-1
382         cmpwi 7,0,0
383         beq- 7,.L22
384         lbz 0,0(4)
385         li 11,1
386         cmpwi 7,0,0
387         beq- 7,.L22
388         lbz 9,0(3)
389         lbz 0,0(4)
390         li 11,-1
391         cmplw 7,9,0
392         blt- 7,.L22
393         lbz 9,0(3)
394         lbz 0,0(4)
395         li 11,1
396         addi 3,3,1
397         addi 4,4,1
398         cmplw 7,9,0
399         ble+ 7,.L20
400 .L22:
401         mr 3,11
402         blr
403 .size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
405 /* Ditto index/strchr */
406 .global VG_(ppc32_linux_REDIR_FOR_strchr)
407 .type   VG_(ppc32_linux_REDIR_FOR_strchr), @function
408 VG_(ppc32_linux_REDIR_FOR_strchr):
409         lbz 0,0(3)
410         rlwinm 4,4,0,0xff
411         cmpw 7,4,0
412         beqlr 7
413         cmpwi 7,0,0
414         bne 7,.L308
415         b .L304
416 .L309:  
417         beq 6,.L304
418 .L308:  
419         lbzu 0,1(3)
420         cmpw 7,4,0
421         cmpwi 6,0,0
422         bne 7,.L309
423         blr
424 .L304:  
425         li 3,0
426         blr
427 .size   VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
428         
429 .global VG_(trampoline_stuff_end)
430 VG_(trampoline_stuff_end):
432         /* and a trailing page of unexecutable code */
433         UD2_PAGE
435 #       undef UD2_16
436 #       undef UD2_64
437 #       undef UD2_256
438 #       undef UD2_1024
439 #       undef UD2_PAGE
441 /*---------------- ppc64-linux ----------------*/
442 #else
443 #if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
445 #       define UD2_16     trap ; trap ; trap; trap
446 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
447 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
448 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
449 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
451         /* a leading page of unexecutable code */
452         UD2_PAGE
454 .global VG_(trampoline_stuff_start)
455 VG_(trampoline_stuff_start):
457 .global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn)
458 VG_(ppc64_linux_SUBST_FOR_rt_sigreturn):
459         li 0,__NR_rt_sigreturn
460         sc
461         .long 0 /*illegal insn*/
463         /* See comment in pub_core_trampoline.h for what this is for */
464 .global VG_(ppctoc_magic_redirect_return_stub)
465 VG_(ppctoc_magic_redirect_return_stub):
466         trap
468         /* this function is written using the "dotless" ABI convention */
469         .align 2
470         .globl VG_(ppc64_linux_REDIR_FOR_strlen)
471 #if !defined VGP_ppc64be_linux || _CALL_ELF == 2
472         /* Little Endian uses ELF version 2 */
473         .type VG_(ppc64_linux_REDIR_FOR_strlen),@function
474 VG_(ppc64_linux_REDIR_FOR_strlen):
475 #else
476         /* Big Endian uses ELF version 1 */
477         .section        ".opd","aw"
478         .align 3
479 VG_(ppc64_linux_REDIR_FOR_strlen):
480         .quad   .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
481         .previous
482         .size   VG_(ppc64_linux_REDIR_FOR_strlen), \
483                         .L0end-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
484         .type   VG_(ppc64_linux_REDIR_FOR_strlen), @function
486 .L.VG_(ppc64_linux_REDIR_FOR_strlen):
487 #endif
488 #if _CALL_ELF == 2
489 0:      addis        2,12,.TOC.-0b@ha
490         addi         2,2,.TOC.-0b@l
491         .localentry  VG_(ppc64_linux_REDIR_FOR_strlen), .-VG_(ppc64_linux_REDIR_FOR_strlen)
492 #endif
493         mr 9,3
494         lbz 0,0(3)
495         li 3,0
496         cmpwi 7,0,0
497         beqlr 7
498         li 3,0
499 .L01:
500         addi 0,3,1
501         extsw 3,0
502         lbzx 0,9,3
503         cmpwi 7,0,0
504         bne 7,.L01
505         blr
507 #if !defined VGP_ppc64be_linux || _CALL_ELF == 2
508         .size VG_(ppc64_linux_REDIR_FOR_strlen),.-VG_(ppc64_linux_REDIR_FOR_strlen)
509 #else
510         .size VG_(ppc64_linux_REDIR_FOR_strlen),.-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
511 #endif
512         .long 0
513         .byte 0,0,0,0,0,0,0,0
514 .L0end:
516         /* this function is written using the "dotless" ABI convention */
517         .align 2
518         .globl VG_(ppc64_linux_REDIR_FOR_strchr)
519 #if !defined VGP_ppc64be_linux || _CALL_ELF == 2
520         .type   VG_(ppc64_linux_REDIR_FOR_strchr),@function
521 VG_(ppc64_linux_REDIR_FOR_strchr):
522 #else
523         .section        ".opd","aw"
524         .align 3
525 VG_(ppc64_linux_REDIR_FOR_strchr):
526         .quad   .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
527         .previous
528         .size   VG_(ppc64_linux_REDIR_FOR_strchr), \
529                         .L1end-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
530         .type   VG_(ppc64_linux_REDIR_FOR_strchr),@function
532 .L.VG_(ppc64_linux_REDIR_FOR_strchr):
533 #endif
534 #if  _CALL_ELF == 2
535 0:      addis         2,12,.TOC.-0b@ha
536         addi         2,2,.TOC.-0b@l
537         .localentry VG_(ppc64_linux_REDIR_FOR_strchr), .-VG_(ppc64_linux_REDIR_FOR_strchr)
538 #endif
539         lbz 0,0(3)
540         rldicl 4,4,0,56
541         cmpw 7,4,0
542         beqlr 7
543         cmpdi 7,0,0
544         bne 7,.L18
545         b .L14
546 #if !defined VGP_ppc64be_linux || _CALL_ELF == 2
547         .size VG_(ppc64_linux_REDIR_FOR_strchr),.-VG_(ppc64_linux_REDIR_FOR_strchr)
548 #else
549         .size VG_(ppc64_linux_REDIR_FOR_strchr),.-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
550 #endif
551 .L19:   
552         beq 6,.L14
553 .L18:   
554         lbzu 0,1(3)
555         cmpw 7,4,0
556         cmpdi 6,0,0
557         bne 7,.L19
558         blr
559 .L14:   
560         li 3,0
561         blr
562         .long 0
563         .byte 0,0,0,0,0,0,0,0
564 .L1end:
566         
567 .global VG_(trampoline_stuff_end)
568 VG_(trampoline_stuff_end):
570         /* and a trailing page of unexecutable code */
571         UD2_PAGE
573 #       undef UD2_16
574 #       undef UD2_64
575 #       undef UD2_256
576 #       undef UD2_1024
577 #       undef UD2_PAGE
579 /*---------------- arm-linux ----------------*/
580 #else
581 #if defined(VGP_arm_linux)
583 #       define UD2_4      .word 0xFFFFFFFF
584 #       define UD2_16     UD2_4    ; UD2_4    ; UD2_4    ; UD2_4
585 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
586 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
587 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
588 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
590         /* a leading page of unexecutable code */
591         UD2_PAGE
593 .global VG_(trampoline_stuff_start)
594 VG_(trampoline_stuff_start):
596 .global VG_(arm_linux_SUBST_FOR_sigreturn)
597 .type   VG_(arm_linux_SUBST_FOR_sigreturn),#function
598 VG_(arm_linux_SUBST_FOR_sigreturn):
599         mov r7, # __NR_sigreturn
600         svc #0
601         .long 0xFFFFFFFF /*illegal insn*/
602 .size VG_(arm_linux_SUBST_FOR_sigreturn), .-VG_(arm_linux_SUBST_FOR_sigreturn)
604 .global VG_(arm_linux_SUBST_FOR_rt_sigreturn)
605 .type   VG_(arm_linux_SUBST_FOR_rt_sigreturn),#function
606 VG_(arm_linux_SUBST_FOR_rt_sigreturn):
607         mov r7, # __NR_rt_sigreturn
608         svc #0
609         .long 0xFFFFFFFF /*illegal insn*/
610 .size VG_(arm_linux_SUBST_FOR_rt_sigreturn), .-VG_(arm_linux_SUBST_FOR_rt_sigreturn)
611         
612 .global VG_(arm_linux_REDIR_FOR_strlen)
613 VG_(arm_linux_REDIR_FOR_strlen):
614         mov     r2, r0
615         ldrb    r0, [r0, #0]    @ zero_extendqisi2
616         @ lr needed for prologue
617         cmp     r0, #0
618         bxeq    lr
619         mov     r0, #0
620 .L5:
621         add     r0, r0, #1
622         ldrb    r3, [r0, r2]    @ zero_extendqisi2
623         cmp     r3, #0
624         bne     .L5
625         bx      lr
626         UD2_4
628 .global VG_(arm_linux_REDIR_FOR_index)
629 VG_(arm_linux_REDIR_FOR_index):
630         ldrb    r3, [r0, #0]    @ zero_extendqisi2
631         and     r1, r1, #255
632         cmp     r3, r1
633         @ lr needed for prologue
634         bne     .L9
635         bx      lr
636 .L12:
637         ldrb    r3, [r0, #1]!   @ zero_extendqisi2
638         cmp     r3, r1
639         beq     .L11
640 .L9:
641         cmp     r3, #0
642         bne     .L12
643         mov     r0, #0
644         bx      lr
645 .L11:
646         bx      lr
647         UD2_4
649 .global VG_(arm_linux_REDIR_FOR_memcpy)
650 VG_(arm_linux_REDIR_FOR_memcpy):
651         stmfd   sp!, {r4, r5, lr}
652         subs    lr, r2, #0
653         mov     r5, r0
654         beq     .L2
655         cmp     r0, r1
656         bls     .L4
657         add     r3, r0, lr
658         add     r1, lr, r1
659         cmp     lr, #3
660         sub     r4, r3, #1
661         sub     r0, r1, #1
662         ble     .L28
663         sub     ip, r3, #5
664         sub     r1, r1, #5
665 .L8:
666         ldrb    r3, [r1, #4]    @ zero_extendqisi2
667         sub     lr, lr, #4
668         strb    r3, [ip, #4]
669         ldrb    r2, [r1, #3]    @ zero_extendqisi2
670         cmp     lr, #3
671         strb    r2, [ip, #3]
672         ldrb    r3, [r1, #2]    @ zero_extendqisi2
673         mov     r4, ip
674         strb    r3, [ip, #2]
675         ldrb    r2, [r1, #1]    @ zero_extendqisi2
676         mov     r0, r1
677         strb    r2, [ip, #1]
678         sub     r1, r1, #4
679         sub     ip, ip, #4
680         bgt     .L8
681         cmp     lr, #0
682         beq     .L2
683 .L28:
684         sub     r2, lr, #1
685 .L21:
686         sub     r2, r2, #1
687         ldrb    r3, [r0], #-1   @ zero_extendqisi2
688         cmn     r2, #1
689         strb    r3, [r4], #-1
690         bne     .L21
691 .L2:
692         mov     r0, r5
693         ldmfd   sp!, {r4, r5, pc}
694 .L4:
695         bcs     .L2
696         cmp     lr, #3
697         mov     ip, r0
698         ble     .L29
699 .L19:
700         ldrb    r3, [r1, #0]    @ zero_extendqisi2
701         sub     lr, lr, #4
702         strb    r3, [ip, #0]
703         ldrb    r2, [r1, #1]    @ zero_extendqisi2
704         cmp     lr, #3
705         strb    r2, [ip, #1]
706         ldrb    r3, [r1, #2]    @ zero_extendqisi2
707         strb    r3, [ip, #2]
708         ldrb    r2, [r1, #3]    @ zero_extendqisi2
709         add     r1, r1, #4
710         strb    r2, [ip, #3]
711         add     ip, ip, #4
712         bgt     .L19
713         cmp     lr, #0
714         beq     .L2
715 .L29:
716         sub     r2, lr, #1
717 .L20:
718         sub     r2, r2, #1
719         ldrb    r3, [r1], #1    @ zero_extendqisi2
720         cmn     r2, #1
721         strb    r3, [ip], #1
722         bne     .L20
723         mov     r0, r5
724         ldmfd   sp!, {r4, r5, pc}
725         UD2_4
727 .global VG_(arm_linux_REDIR_FOR_strcmp)
728 VG_(arm_linux_REDIR_FOR_strcmp):
729 .L64:
730         ldrb    r3, [r0], #1    @ zero_extendqisi2
731         ldrb    r2, [r1], #1    @ zero_extendqisi2
732         cmp     r3, #0
733         beq     .L67
734         cmp     r3, r2
735         beq     .L64
736         rsb     r0, r2, r3
737         bx      lr
738 .L67:
739         rsb     r0, r2, #0
740         bx      lr
741         UD2_4
743 .global VG_(trampoline_stuff_end)
744 VG_(trampoline_stuff_end):
746         /* and a trailing page of unexecutable code */
747         UD2_PAGE
749 #       undef UD2_4
750 #       undef UD2_16
751 #       undef UD2_64
752 #       undef UD2_256
753 #       undef UD2_1024
754 #       undef UD2_PAGE
755         
756 /*---------------- arm64-linux ----------------*/
757 #else
758 #if defined(VGP_arm64_linux)
760 #       define UD2_4      .word 0xFFFFFFFF
761 #       define UD2_16     UD2_4    ; UD2_4    ; UD2_4    ; UD2_4
762 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
763 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
764 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
765 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
767         /* a leading page of unexecutable code */
768         UD2_PAGE
770 .global VG_(trampoline_stuff_start)
771 VG_(trampoline_stuff_start):
773 .global VG_(arm64_linux_SUBST_FOR_rt_sigreturn)
774 .type   VG_(arm64_linux_SUBST_FOR_rt_sigreturn),#function
775 VG_(arm64_linux_SUBST_FOR_rt_sigreturn):
776         mov x8, # __NR_rt_sigreturn
777         svc #0
778         .long 0xFFFFFFFF /*illegal insn*/
779 .size VG_(arm64_linux_SUBST_FOR_rt_sigreturn), \
780         .-VG_(arm64_linux_SUBST_FOR_rt_sigreturn)
782 .global VG_(arm64_linux_REDIR_FOR_strlen)
783 .type   VG_(arm64_linux_REDIR_FOR_strlen),#function
784 VG_(arm64_linux_REDIR_FOR_strlen):
785         mov     x2, x0
786         ldrb    w0, [x0]
787         cbz     w0, .L5
788         mov     x0, 0
789 .L4:
790         add     x0, x0, 1
791         ldrb    w1, [x2,x0]
792         cbnz    w1, .L4
793         ret
794 .L5:
795         mov     x0, 0
796         ret
797 .size VG_(arm64_linux_REDIR_FOR_strlen), .-VG_(arm64_linux_REDIR_FOR_strlen)
799 .global VG_(arm64_linux_REDIR_FOR_index)
800 .type   VG_(arm64_linux_REDIR_FOR_index),#function
801 VG_(arm64_linux_REDIR_FOR_index):
802         ldrb    w2, [x0]
803         uxtb    w1, w1
804         cmp     w2, w1
805         beq     .L11
806 .L13:
807         cbz     w2, .L16
808         ldrb    w2, [x0,1]!
809         cmp     w2, w1
810         bne     .L13
811 .L11:
812         ret
813 .L16:
814         mov     x0, 0
815         ret
816 .size VG_(arm64_linux_REDIR_FOR_index), .-VG_(arm64_linux_REDIR_FOR_index)
818 .global VG_(arm64_linux_REDIR_FOR_strcmp)
819 .type   VG_(arm64_linux_REDIR_FOR_strcmp),#function
820 VG_(arm64_linux_REDIR_FOR_strcmp):
821         ldrb    w2, [x0]
822         ldrb    w3, [x1]
823         cmp     w2, w3
824         bcc     .L22
825 .L21:
826         bhi     .L25
827         cbz     w2, .L26
828         ldrb    w2, [x0,1]!
829         ldrb    w3, [x1,1]!
830         cmp     w2, w3
831         bcs     .L21
832 .L22:
833         mov     x0, -1
834         ret
835 .L25:
836         mov     x0, 1
837         ret
838 .L26:
839         mov     x0, 0
840         ret
841 .size VG_(arm64_linux_REDIR_FOR_strcmp), .-VG_(arm64_linux_REDIR_FOR_strcmp)
843 .global VG_(trampoline_stuff_end)
844 VG_(trampoline_stuff_end):
846         /* and a trailing page of unexecutable code */
847         UD2_PAGE
849 #       undef UD2_4
850 #       undef UD2_16
851 #       undef UD2_64
852 #       undef UD2_256
853 #       undef UD2_1024
854 #       undef UD2_PAGE
855         
856 /*---------------- x86-darwin ----------------*/
857 #else
858 #if defined(VGP_x86_darwin)
860         /* a leading page of unexecutable code */
861 .fill 2048, 2, 0x0b0f /* `ud2` */
863 .globl VG_(trampoline_stuff_start)
864 VG_(trampoline_stuff_start):
866 .globl VG_(x86_darwin_SUBST_FOR_sigreturn)
867 VG_(x86_darwin_SUBST_FOR_sigreturn):
868         /* XXX does this need to have any special form? (cf x86-linux
869         version) */
870         movl    $ __NR_DARWIN_FAKE_SIGRETURN, %eax
871         int     $0x80
872         ud2
874 .globl VG_(x86_darwin_REDIR_FOR_strlen)
875 VG_(x86_darwin_REDIR_FOR_strlen):
876         movl    4(%esp), %edx
877         movl    %edx, %eax
878         jmp     1f
880         incl    %eax
882         cmpb    $0, (%eax)
883         jne     0b
884         subl    %edx, %eax
885         ret
887 .globl VG_(x86_darwin_REDIR_FOR_strcat)
888 VG_(x86_darwin_REDIR_FOR_strcat):
889         pushl   %esi
890         movl    8(%esp), %esi
891         movl    12(%esp), %ecx
892         movl    %esi, %edx
893         jmp     1f
895         incl    %edx
897         cmpb    $0, (%edx)
898         jne     0b
900         movzbl  (%ecx), %eax
901         incl    %ecx
902         movb    %al, (%edx)
903         incl    %edx
904         testb   %al, %al
905         jne     2b
906         movl    %esi, %eax
907         popl    %esi
908         ret
911 .globl VG_(x86_darwin_REDIR_FOR_strcmp)
912 VG_(x86_darwin_REDIR_FOR_strcmp):
913         movl    4(%esp), %edx
914         movl    8(%esp), %ecx
915         jmp     1f
917         incl    %edx
918         incl    %ecx
920         movzbl  (%edx), %eax
921         testb   %al, %al
922         je      2f
923         cmpb    (%ecx), %al
924         je      0b
926         movzbl  (%ecx),%edx
927         movzbl  %al,%eax
928         subl    %edx, %eax
929         ret
932 .globl VG_(x86_darwin_REDIR_FOR_strcpy)
933 VG_(x86_darwin_REDIR_FOR_strcpy):
934         pushl   %ebp
935         movl    %esp, %ebp
936         pushl   %esi
937         movl    8(%ebp), %esi
938         movl    12(%ebp), %ecx
939         movl    %esi, %edx
940         jmp     1f
942         incl    %ecx
943         incl    %edx
945         movzbl  (%ecx), %eax
946         testb   %al, %al
947         movb    %al, (%edx)
948         jne     0b
949         movl    %esi, %eax
950         popl    %esi
951         leave
952         ret
954 .globl VG_(x86_darwin_REDIR_FOR_strlcat)
955 VG_(x86_darwin_REDIR_FOR_strlcat):
956         pushl   %ebp
957         movl    %esp, %ebp
958         pushl   %edi
959         pushl   %esi
960         subl    $16, %esp
961         movl    8(%ebp), %esi
962         movl    16(%ebp), %ecx
963         movl    %esi, %edx
964         leal    (%ecx,%esi), %eax
965         jmp     1f
967         incl    %edx
969         cmpl    %edx, %eax
970         je      2f
971         cmpb    $0, (%edx)
972         jne     0b
974         movl    %edx, %edi
975         subl    %esi, %edi
976         movl    %ecx, %esi
977         subl    %edi, %esi
978         je      3f
979         movl    12(%ebp), %eax
980         jmp     6f
982         movl    12(%ebp), %eax
983         movl    %eax, (%esp)
984         call    VG_(x86_darwin_REDIR_FOR_strlen)
985         jmp     7f
987         cmpl    $1, %esi
988         je      5f
989         movb    %cl, (%edx)
990         decl    %esi
991         incl    %edx
993         incl    %eax
995         movzbl  (%eax), %ecx
996         testb   %cl, %cl
997         jne     4b
998         movb    $0, (%edx)
999         subl    12(%ebp), %eax
1001         addl    $16, %esp
1002         leal    (%edi,%eax), %eax
1003         popl    %esi
1004         popl    %edi
1005         leave
1006         ret
1007         
1008         
1009 .globl VG_(trampoline_stuff_end)
1010 VG_(trampoline_stuff_end):
1012         /* a trailing page of unexecutable code */
1013 .fill 2048, 2, 0x0b0f /* `ud2` */
1016 /*---------------- amd64-darwin ----------------*/
1017 #else
1018 #if defined(VGP_amd64_darwin)
1020         /* a leading page of unexecutable code */
1021 .fill 2048, 2, 0x0b0f /* `ud2` */
1023 .globl VG_(trampoline_stuff_start)
1024 VG_(trampoline_stuff_start):
1026 .globl VG_(amd64_darwin_SUBST_FOR_sigreturn)
1027 VG_(amd64_darwin_SUBST_FOR_sigreturn):
1028         /* XXX does this need to have any special form? (cf x86-linux
1029         version) */
1030         movq    $ __NR_DARWIN_FAKE_SIGRETURN, %rax
1031         syscall
1032         ud2
1034 .globl VG_(amd64_darwin_REDIR_FOR_strlen)
1035 VG_(amd64_darwin_REDIR_FOR_strlen):
1036         movq    %rdi, %rax
1037         jmp     1f
1039         incq    %rax
1041         cmpb    $0, (%rax)
1042         jne     0b
1043         subq    %rdi, %rax
1044         ret
1046 .globl VG_(amd64_darwin_REDIR_FOR_strcat)
1047 VG_(amd64_darwin_REDIR_FOR_strcat):
1048         movq    %rdi, %rdx
1049         jmp     1f
1051         incq    %rdx
1053         cmpb    $0, (%rdx)
1054         jne     0b
1056         movzbl  (%rsi), %eax
1057         incq    %rsi
1058         movb    %al, (%rdx)
1059         incq    %rdx
1060         testb   %al, %al
1061         jne     2b
1062         movq    %rdi, %rax
1063         ret
1066 .globl VG_(amd64_darwin_REDIR_FOR_strcmp)
1067 VG_(amd64_darwin_REDIR_FOR_strcmp):
1068         jmp     1f
1070         incq    %rdi
1071         incq    %rsi
1073         movzbl  (%rdi), %eax
1074         testb   %al, %al
1075         je      2f
1076         cmpb    (%rsi), %al
1077         je      0b
1079         movzbl  (%rsi), %edx
1080         movzbl  %al, %eax
1081         subl    %edx, %eax
1082         ret
1084 .globl VG_(amd64_darwin_REDIR_FOR_strcpy)
1085 VG_(amd64_darwin_REDIR_FOR_strcpy):
1086         pushq   %rbp
1087         movq    %rdi, %rdx
1088         movq    %rsp, %rbp
1089         jmp     1f
1091         incq    %rsi
1092         incq    %rdx
1094         movzbl  (%rsi), %eax
1095         testb   %al, %al
1096         movb    %al, (%rdx)
1097         jne     0b
1098         leave
1099         movq    %rdi, %rax
1100         ret
1101         
1102 .globl VG_(amd64_darwin_REDIR_FOR_strlcat)
1103 VG_(amd64_darwin_REDIR_FOR_strlcat):
1104         pushq   %rbp
1105         leaq    (%rdx,%rdi), %rax
1106         movq    %rdi, %rcx
1107         movq    %rsp, %rbp
1108         pushq   %rbx
1109         subq    $8, %rsp
1110         jmp     1f
1112         incq    %rcx
1114         cmpq    %rcx, %rax
1115         je      2f
1116         cmpb    $0, (%rcx)
1117         jne     0b
1119         movq    %rcx, %rbx
1120         subq    %rdi, %rbx
1121         movq    %rdx, %rdi
1122         subq    %rbx, %rdi
1123         je      3f
1124         movq    %rsi, %rax
1125         jmp     6f
1127         movq    %rsi, %rdi
1128         call    VG_(amd64_darwin_REDIR_FOR_strlen)
1129         jmp     7f
1131         cmpq    $1, %rdi
1132         je      5f
1133         movb    %dl, (%rcx)
1134         decq    %rdi
1135         incq    %rcx
1137         incq    %rax
1139         movzbl  (%rax), %edx
1140         testb   %dl, %dl
1141         jne     4b
1142         movb    $0, (%rcx)
1143         subq    %rsi, %rax
1145         leaq    (%rbx,%rax), %rax
1146         addq    $8, %rsp
1147         popq    %rbx
1148         leave
1149         ret
1151 .globl VG_(amd64_darwin_REDIR_FOR_arc4random)
1152 VG_(amd64_darwin_REDIR_FOR_arc4random):
1153         /* not very random, hope dyld won't mind */
1154         movq    $0x76616c6772696e64, %rax
1155         ret
1157 .globl VG_(amd64_darwin_REDIR_FOR_strchr)
1158 VG_(amd64_darwin_REDIR_FOR_strchr):
1159         pushq   %rbp
1160         movq    %rsp, %rbp
1161         movb    (%rdi), %cl
1162         cmpb    %sil, %cl
1163         jne     1f
1164         movq    %rdi, %rax
1165         popq    %rbp
1166         ret
1168         testb   %cl, %cl
1169         movl    $0, %eax
1170         je      2f
1171         movb    1(%rdi), %cl
1172         incq    %rdi
1173         cmpb    %sil, %cl
1174         movq    %rdi, %rax
1175         jne     1b
1177         popq    %rbp
1178         ret
1179         
1180 .globl VG_(trampoline_stuff_end)
1181 VG_(trampoline_stuff_end):
1183         /* a trailing page of unexecutable code */
1184 .fill 2048, 2, 0x0b0f /* `ud2` */
1187 /*---------------- s390x-linux ----------------*/
1188 #else
1189 #if defined(VGP_s390x_linux)
1191         /* a leading page of unexecutable code */
1192         .fill 2048, 2, 0x0000
1194 .global VG_(trampoline_stuff_start)
1195 VG_(trampoline_stuff_start):
1197 .global VG_(s390x_linux_SUBST_FOR_sigreturn)
1198 VG_(s390x_linux_SUBST_FOR_sigreturn):
1199         svc __NR_sigreturn
1200         .short 0
1202 .global VG_(s390x_linux_SUBST_FOR_rt_sigreturn)
1203 VG_(s390x_linux_SUBST_FOR_rt_sigreturn):
1204         /* Old gcc unwinding code checks for a sig(_rt)_return svc and then
1205            for ra = cfa to decide if it is a sig_rt_frame or not. Since we
1206            set ra to this trampoline, but the cfa is still in the stack,
1207            the unwinder thinks, that this is a non-rt frame  and causes a
1208            crash in the gcc unwinder - which is used by the thread library
1209            and others. Therefore we add a lr 1,1 nop, to let the gcc
1210            unwinder bail out gracefully. This might also affect unwinding
1211            across the signal frame - tough luck. fixs390 */
1212         lr 1,1
1213         svc __NR_rt_sigreturn
1214         .short 0
1216 .global VG_(s390x_linux_REDIR_FOR_index)
1217 .type   VG_(s390x_linux_REDIR_FOR_index),@function
1218 VG_(s390x_linux_REDIR_FOR_index):
1220 #   %r2 = address of string
1221 #   %r3 = character to find
1223         lghi    %r0,255
1224         ngr     %r0,%r3        # r0 = (unsigned char)r3
1225         lghi    %r4,0
1226 .L1:
1227         llgc    %r1,0(%r2)     # r1 = byte from string
1228         cr      %r1,%r0        # compare
1229         ber     %r14           # return if found
1230         cr      %r1,%r4        # end of string ?
1231         je      .L2
1232         aghi    %r2,1          # increment r2
1233         j       .L1
1234 .L2:    lghi    %r2,0          # return value 0
1235         br      %r14
1236 .size VG_(s390x_linux_REDIR_FOR_index), .-VG_(s390x_linux_REDIR_FOR_index)
1238 .globl VG_(trampoline_stuff_end)
1239 VG_(trampoline_stuff_end):
1240         .fill 2048, 2, 0x0000
1242 /*---------------------- mips32-linux ----------------------*/
1243 #else
1244 #if defined(VGP_mips32_linux)
1246 #       define UD2_16     trap ; trap ; trap; trap
1247 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
1248 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
1249 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
1250 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
1253 .global VG_(trampoline_stuff_start)
1254 VG_(trampoline_stuff_start):
1256 .global VG_(mips32_linux_SUBST_FOR_sigreturn)
1257 VG_(mips32_linux_SUBST_FOR_sigreturn):
1258         li $v0,__NR_sigreturn
1259         syscall
1260         nop
1261         .long 0 /*illegal insn*/
1263 .global VG_(mips32_linux_SUBST_FOR_rt_sigreturn)
1264 VG_(mips32_linux_SUBST_FOR_rt_sigreturn):
1265         li $v0,__NR_rt_sigreturn
1266         syscall
1267         nop
1268         .long 0 /*illegal insn*/
1269         
1270 /* There's no particular reason that this needs to be handwritten
1271    assembly, but since that's what this file contains, here's a
1272    simple index() and strlen() implementations.
1275 .set push
1276 .set noreorder
1278 .global VG_(mips32_linux_REDIR_FOR_index)
1279 .type   VG_(mips32_linux_REDIR_FOR_index), @function
1280 VG_(mips32_linux_REDIR_FOR_index):
1281       move $v0, $a0
1282    index_loop:
1283       lbu $t0, 0($v0)
1284       beq $t0, $a1, index_end
1285       nop
1286       bne $t0, $zero, index_loop
1287       addiu $v0, $v0, 1
1288       move $v0, $zero
1289    index_end:
1290       jr $ra
1291       nop
1292 .size VG_(mips32_linux_REDIR_FOR_index), .-VG_(mips32_linux_REDIR_FOR_index)
1294 .global VG_(mips32_linux_REDIR_FOR_strlen)
1295 .type   VG_(mips32_linux_REDIR_FOR_strlen), @function
1296 VG_(mips32_linux_REDIR_FOR_strlen):
1297       move $v0, $a0
1298    strlen_loop:
1299       lbu $t0, 0($a0)
1300       bne $t0, $zero, strlen_loop
1301       addiu $a0, $a0, 1
1302       subu $v0, $a0, $v0
1303       jr $ra
1304       addiu $v0, $v0, -1
1305 .size VG_(mips32_linux_REDIR_FOR_strlen), .-VG_(mips32_linux_REDIR_FOR_strlen)
1307 .set pop
1309 .global VG_(trampoline_stuff_end)
1310 VG_(trampoline_stuff_end):
1313 #       undef UD2_16
1314 #       undef UD2_64
1315 #       undef UD2_256
1316 #       undef UD2_1024
1317 #       undef UD2_PAGE
1319 /*---------------------- mips64-linux ----------------------*/
1320 #else
1321 #if defined(VGP_mips64_linux)
1323 #       define UD2_16     trap ; trap ; trap; trap
1324 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
1325 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
1326 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
1327 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024  
1329 .global VG_(trampoline_stuff_start)
1330 VG_(trampoline_stuff_start):
1332 .global VG_(mips64_linux_SUBST_FOR_rt_sigreturn)
1333 VG_(mips64_linux_SUBST_FOR_rt_sigreturn):
1334         li $2,__NR_rt_sigreturn
1335         syscall
1336         nop
1337         .long 0 /*illegal insn*/
1339 /* There's no particular reason that this needs to be handwritten
1340    assembly, but since that's what this file contains, here's a
1341    simple index() and strlen() implementations.
1344 .set push
1345 .set noreorder
1347 .global VG_(mips64_linux_REDIR_FOR_index)
1348 .type   VG_(mips64_linux_REDIR_FOR_index), @function
1349 VG_(mips64_linux_REDIR_FOR_index):
1350       move $v0, $a0
1351    index_loop:
1352       lbu $t0, 0($v0)
1353       beq $t0, $a1, index_end
1354       nop
1355       bne $t0, $zero, index_loop
1356       daddiu $v0, $v0, 1
1357       move $v0, $zero
1358    index_end:
1359       jr $ra
1360       nop
1361 .size VG_(mips64_linux_REDIR_FOR_index), .-VG_(mips64_linux_REDIR_FOR_index)
1363 .global VG_(mips64_linux_REDIR_FOR_strlen)
1364 .type   VG_(mips64_linux_REDIR_FOR_strlen), @function
1365 VG_(mips64_linux_REDIR_FOR_strlen):
1366       move $v0, $a0
1367    strlen_loop:
1368       lbu $t0, 0($a0)
1369       bne $t0, $zero, strlen_loop
1370       daddiu $a0, $a0, 1
1371       dsubu $v0, $a0, $v0
1372       jr $ra
1373       daddiu $v0, $v0, -1
1374 .size VG_(mips64_linux_REDIR_FOR_strlen), .-VG_(mips64_linux_REDIR_FOR_strlen)
1376 .set pop
1378 .global VG_(trampoline_stuff_end)
1379 VG_(trampoline_stuff_end):
1382 #       undef UD2_16
1383 #       undef UD2_64
1384 #       undef UD2_256
1385 #       undef UD2_1024
1386 #       undef UD2_PAGE
1388 /*---------------- x86-solaris ----------------*/
1389 #else
1390 #if defined(VGP_x86_solaris)
1392 .global VG_(trampoline_stuff_start)
1393 VG_(trampoline_stuff_start):
1395 /* int strcmp(const char *s1, const char *s2); */
1396 .global VG_(x86_solaris_REDIR_FOR_strcmp)
1397 .type   VG_(x86_solaris_REDIR_FOR_strcmp), @function
1398 VG_(x86_solaris_REDIR_FOR_strcmp):
1399         pushl   %ebp                    /* establish a stack frame */
1400         movl    %esp, %ebp
1401         movl    8(%ebp), %edx           /* get s1 */
1402         movl    12(%esp), %ecx          /* get s2 */
1403         jmp     2f                      /* go compare the first characters */
1405         incl    %edx                    /* skip to the next s1 character */
1406         incl    %ecx                    /* skip to the next s2 character */
1408         movzbl  (%edx), %eax            /* load a character from s1 */
1409         testb   %al, %al                /* is it null? */
1410         jz      3f                      /* yes, exit */
1411         cmpb    (%ecx), %al             /* are the characters equal? */
1412         je      1b                      /* yes, proceed with next characters */
1414         movzbl  (%ecx), %edx            /* load a character from s2 */
1415         subl    %edx, %eax              /* calculate the return value */
1416         popl    %ebp                    /* destroy the stack frame */
1417         ret                             /* return to the caller */
1418 .size VG_(x86_solaris_REDIR_FOR_strcmp), .-VG_(x86_solaris_REDIR_FOR_strcmp)
1420 /* size_t strlen(const char *s); */
1421 .global VG_(x86_solaris_REDIR_FOR_strlen)
1422 .type   VG_(x86_solaris_REDIR_FOR_strlen), @function
1423 VG_(x86_solaris_REDIR_FOR_strlen):
1424         pushl   %ebp                    /* establish a stack frame */
1425         movl    %esp, %ebp
1426         movl    8(%ebp), %edx           /* get s */
1427         movl    %edx, %eax              /* copy s */
1428         jmp     2f                      /* go handle the first character */
1430         incl    %eax                    /* skip to the next s character */
1432         cmpb    $0, (%eax)              /* is the s character null? */
1433         jne     1b                      /* no, go process the next character */
1434         subl    %edx, %eax              /* calculate the return value */
1435         popl    %ebp                    /* destroy the stack frame */
1436         ret                             /* return to the caller */
1437 .size VG_(x86_solaris_REDIR_FOR_strlen), .-VG_(x86_solaris_REDIR_FOR_strlen)
1439 .global VG_(trampoline_stuff_end)
1440 VG_(trampoline_stuff_end):
1442 /*---------------- amd64-solaris ----------------*/
1443 #else
1444 #if defined(VGP_amd64_solaris)
1446 .global VG_(trampoline_stuff_start)
1447 VG_(trampoline_stuff_start):
1449 /* char *strcpy(char *restrict s1, const char *restrict s2); */
1450 .global VG_(amd64_solaris_REDIR_FOR_strcpy)
1451 .type   VG_(amd64_solaris_REDIR_FOR_strcpy), @function
1452 VG_(amd64_solaris_REDIR_FOR_strcpy):
1453         pushq   %rbp                    /* establish a stack frame */
1454         movq    %rsp, %rbp
1455         movq    %rdi, %rdx              /* copy s1 */
1457         movzbl  (%rsi), %eax            /* load one input character */
1458         movb    %al, (%rdx)             /* copy to output/s1 */
1459         incq    %rsi                    /* skip to the next output character */
1460         incq    %rdx                    /* skip to the next input character */
1461         testb   %al, %al                /* is the copied character null? */
1462         jnz     1b                      /* no, copy the next character */
1463         leave                           /* destroy the stack frame */
1464         movq    %rdi, %rax              /* set s1 as the return value */
1465         ret                             /* return to the caller */
1466 .size VG_(amd64_solaris_REDIR_FOR_strcpy), .-VG_(amd64_solaris_REDIR_FOR_strcpy)
1468 /* char *strncpy(char *restrict s1, const char *restrict s2, size_t n); */
1469 .global VG_(amd64_solaris_REDIR_FOR_strncpy)
1470 .type   VG_(amd64_solaris_REDIR_FOR_strncpy), @function
1471 VG_(amd64_solaris_REDIR_FOR_strncpy):
1472         pushq   %rbp                    /* establish a stack frame */
1473         movq    %rsp, %rbp
1474         movq    %rdi, %rcx              /* copy s1 */
1476         testq   %rdx, %rdx              /* is the remaining size zero? */
1477         jz      3f                      /* yes, all done */
1478         movzbl  (%rsi), %eax            /* load one input character */
1479         movb    %al, (%rcx)             /* copy to output/s1 */
1480         decq    %rdx                    /* decrement the remaining size */
1481         incq    %rsi                    /* skip to the next output character */
1482         incq    %rcx                    /* skip to the next input character */
1483         testb   %al, %al                /* is the copied character null? */
1484         jnz     1b                      /* no, copy the next character */
1486         testq   %rdx, %rdx              /* is the remaining size zero? */
1487         jz      3f                      /* yes, all done */
1488         movb    $0, (%rdx)              /* copy null to output/s2 */
1489         decq    %rdx                    /* decrement the remaining size */
1490         incq    %rsi                    /* skip to next output character */
1491         jmp     2b                      /* proceed with the next character */
1493         leave                           /* destroy the stack frame */
1494         movq    %rdi, %rax              /* set s1 as the return value */
1495         ret                             /* return to the caller */
1496 .size VG_(amd64_solaris_REDIR_FOR_strncpy), .-VG_(amd64_solaris_REDIR_FOR_strncpy)
1498 /* int strcmp(const char *s1, const char *s2); */
1499 .global VG_(amd64_solaris_REDIR_FOR_strcmp)
1500 .type   VG_(amd64_solaris_REDIR_FOR_strcmp), @function
1501 VG_(amd64_solaris_REDIR_FOR_strcmp):
1502         pushq   %rbp                    /* establish a stack frame */
1503         movq    %rsp, %rbp
1504         jmp     2f                      /* go compare the first characters */
1506         incq    %rdi                    /* skip to the next s1 character */
1507         incq    %rsi                    /* skip to the next s2 character */
1509         movzbl  (%rdi), %eax            /* load a character from s1 */
1510         testb   %al, %al                /* is it null? */
1511         jz      3f                      /* yes, exit */
1512         cmpb    (%rsi), %al             /* are the characters equal? */
1513         je      1b                      /* yes, proceed with next characters */
1515         movzbl  (%rsi), %edx            /* load a character from s2 */
1516         subl    %edx, %eax              /* calculate the return value */
1517         leave                           /* destroy the stack frame */
1518         ret                             /* return to the caller */
1519 .size VG_(amd64_solaris_REDIR_FOR_strcmp), .-VG_(amd64_solaris_REDIR_FOR_strcmp)
1521 /* char *strcat(char *restrict s1, const char *restrict s2); */
1522 .global VG_(amd64_solaris_REDIR_FOR_strcat)
1523 .type   VG_(amd64_solaris_REDIR_FOR_strcat), @function
1524 VG_(amd64_solaris_REDIR_FOR_strcat):
1525         pushq   %rbp                    /* establish a stack frame */
1526         movq    %rsp, %rbp
1527         movq    %rdi, %rdx              /* copy s1 */
1528         jmp     2f                      /* go handle the first character */
1530         incq    %rdx                    /* skip to the next s1 character */
1532         cmpb    $0, (%rdx)              /* is the s1 character null? */
1533         jne     1b                      /* no, go check the next character */
1535         movzbl  (%rsi), %eax            /* load a character from s2 */
1536         movb    %al, (%rdx)             /* copy the s2 character to s1 */
1537         incq    %rdx                    /* skip to the next s1 character */
1538         incq    %rsi                    /* skip to the next s2 character */
1539         testb   %al, %al                /* was the character null? */
1540         jnz     3b                      /* no, go copy the next character */
1541         movq    %rdi, %rax              /* set s1 as the return value */
1542         leave                           /* destroy the stack frame */
1543         ret                             /* return to the caller */
1544 .size VG_(amd64_solaris_REDIR_FOR_strcat), .-VG_(amd64_solaris_REDIR_FOR_strcat)
1546 /* size_t strlen(const char *s); */
1547 .global VG_(amd64_solaris_REDIR_FOR_strlen)
1548 .type   VG_(amd64_solaris_REDIR_FOR_strlen), @function
1549 VG_(amd64_solaris_REDIR_FOR_strlen):
1550         pushq   %rbp                    /* establish a stack frame */
1551         movq    %rsp, %rbp
1552         movq    %rdi, %rax              /* copy s */
1553         jmp     2f                      /* go handle the first character */
1555         incq    %rax                    /* skip to the next s character */
1557         cmpb    $0, (%rax)              /* is the s character null? */
1558         jne     1b                      /* no, go process the next character */
1559         subq    %rdi, %rax              /* calculate the return value */
1560         leave                           /* destroy the stack frame */
1561         ret                             /* return to the caller */
1562 .size VG_(amd64_solaris_REDIR_FOR_strlen), .-VG_(amd64_solaris_REDIR_FOR_strlen)
1564 .global VG_(trampoline_stuff_end)
1565 VG_(trampoline_stuff_end):
1567 /*---------------- unknown ----------------*/
1568 #else
1569 #  error Unknown platform
1571 #endif
1572 #endif
1573 #endif
1574 #endif
1575 #endif
1576 #endif
1577 #endif
1578 #endif
1579 #endif
1580 #endif
1581 #endif
1582 #endif
1583 #endif
1585 /* Let the linker know we don't need an executable stack */
1586 MARK_STACK_NO_EXEC
1588 /*--------------------------------------------------------------------*/
1589 /*--- end                                                          ---*/
1590 /*--------------------------------------------------------------------*/