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-2013 Julian Seward
11     jseward@acm.org
12  Copyright (C) 2006-2013 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)
55VG_(trampoline_stuff_start):
56
57.global VG_(x86_linux_SUBST_FOR_sigreturn)
58VG_(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)
69VG_(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
92VG_(x86_linux_REDIR_FOR_index):
93        pushl   %ebp
94        movl    %esp, %ebp
95        movl    8(%ebp), %eax
96        movzbl  12(%ebp), %ecx
97        movzbl  (%eax), %edx
98        cmpb    %dl, %cl
99        jne     .L9
100        jmp     .L2
101.L11:
102        addl    $1, %eax
103        movzbl  (%eax), %edx
104        cmpb    %dl, %cl
105        je      .L2
106.L9:
107        testb   %dl, %dl
108        jne     .L11
109        xorl    %eax, %eax
110.L2:
111        popl    %ebp
112        ret
113.size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index)
114
115/* There's no particular reason that this needs to be handwritten
116   assembly, but since that's what this file contains, here's a
117   simple strlen implementation (written in C and compiled by gcc.)
118*/
119.global VG_(x86_linux_REDIR_FOR_strlen)
120.type   VG_(x86_linux_REDIR_FOR_strlen), @function
121VG_(x86_linux_REDIR_FOR_strlen):
122        pushl   %ebp
123        movl    %esp, %ebp
124        movl    8(%ebp), %edx
125        movl    %edx, %eax
126        jmp     2f
1271:      incl    %eax
1282:      cmpb    $0, (%eax)
129        jne     1b
130        subl    %edx, %eax
131        popl    %ebp
132        ret
133.size VG_(x86_linux_REDIR_FOR_strlen), .-VG_(x86_linux_REDIR_FOR_strlen)
134
135
136.global VG_(trampoline_stuff_end)
137VG_(trampoline_stuff_end):
138
139	/* and a trailing page of unexecutable code */
140	UD2_PAGE
141
142#	undef UD2_16
143#	undef UD2_64
144#	undef UD2_256
145#	undef UD2_1024
146#	undef UD2_PAGE
147
148/*---------------------- amd64-linux ----------------------*/
149#else
150#if defined(VGP_amd64_linux)
151
152#	define UD2_16     ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
153#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
154#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
155#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
156#	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
157
158	/* a leading page of unexecutable code */
159	UD2_PAGE
160
161.global VG_(trampoline_stuff_start)
162VG_(trampoline_stuff_start):
163
164.global VG_(amd64_linux_SUBST_FOR_rt_sigreturn)
165VG_(amd64_linux_SUBST_FOR_rt_sigreturn):
166        /* This is a very specific sequence which GDB uses to
167           recognize signal handler frames. */
168        movq    $__NR_rt_sigreturn, %rax
169        syscall
170        ud2
171
172.global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
173.type   VG_(amd64_linux_REDIR_FOR_vgettimeofday), @function
174VG_(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
184VG_(amd64_linux_REDIR_FOR_vtime):
185.LfnB3:
186        movq    $__NR_time, %rax
187        syscall
188        ret
189.LfnE3:
190.size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
191
192.global VG_(amd64_linux_REDIR_FOR_vgetcpu)
193.type   VG_(amd64_linux_REDIR_FOR_vgetcpu), @function
194VG_(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
201
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.)
205*/
206.global VG_(amd64_linux_REDIR_FOR_strlen)
207.type   VG_(amd64_linux_REDIR_FOR_strlen), @function
208VG_(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)
222
223
224/* A CIE for the above four functions, followed by their FDEs */
225	.section .eh_frame,"a",@progbits
226.Lframe1:
227        .long   .LEcie1-.LScie1
228.LScie1:
229        .long   0x0
230        .byte   0x1
231        .string "zR"
232        .uleb128 0x1
233        .sleb128 -8
234        .byte   0x10
235        .uleb128 0x1
236        .byte   0x3
237        .byte   0xc
238        .uleb128 0x7
239        .uleb128 0x8
240        .byte   0x90
241        .uleb128 0x1
242        .align 8
243.LEcie1:
244.LSfde2:
245        .long   .LEfde2-.LASfde2
246.LASfde2:
247        .long   .LASfde2-.Lframe1
248        .long   .LfnB2
249        .long   .LfnE2-.LfnB2
250        .uleb128 0x0
251        .align 8
252.LEfde2:
253.LSfde3:
254        .long   .LEfde3-.LASfde3
255.LASfde3:
256        .long   .LASfde3-.Lframe1
257        .long   .LfnB3
258        .long   .LfnE3-.LfnB3
259        .uleb128 0x0
260        .align 8
261.LEfde3:
262.LSfde4:
263        .long   .LEfde4-.LASfde4
264.LASfde4:
265        .long   .LASfde4-.Lframe1
266        .long   .LfnB4
267        .long   .LfnE4-.LfnB4
268        .uleb128 0x0
269        .align 8
270.LEfde4:
271.LSfde5:
272        .long   .LEfde5-.LASfde5
273.LASfde5:
274        .long   .LASfde5-.Lframe1
275        .long   .LfnB5
276        .long   .LfnE5-.LfnB5
277        .uleb128 0x0
278        .align 8
279.LEfde5:
280	.previous
281
282.global VG_(trampoline_stuff_end)
283VG_(trampoline_stuff_end):
284
285	/* and a trailing page of unexecutable code */
286	UD2_PAGE
287
288#	undef UD2_16
289#	undef UD2_64
290#	undef UD2_256
291#	undef UD2_1024
292#	undef UD2_PAGE
293
294/*---------------- ppc32-linux ----------------*/
295#else
296#if defined(VGP_ppc32_linux)
297
298#	define UD2_16     trap ; trap ; trap; trap
299#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
300#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
301#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
302#	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
303
304	/* a leading page of unexecutable code */
305	UD2_PAGE
306
307.global VG_(trampoline_stuff_start)
308VG_(trampoline_stuff_start):
309
310.global VG_(ppc32_linux_SUBST_FOR_sigreturn)
311VG_(ppc32_linux_SUBST_FOR_sigreturn):
312	li 0,__NR_sigreturn
313        sc
314        .long 0	/*illegal insn*/
315
316.global VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
317VG_(ppc32_linux_SUBST_FOR_rt_sigreturn):
318	li 0,__NR_rt_sigreturn
319        sc
320        .long 0	/*illegal insn*/
321
322/* There's no particular reason that this needs to be handwritten
323   assembly, but since that's what this file contains, here's a
324   simple strlen implementation (written in C and compiled by gcc.)
325*/
326.global VG_(ppc32_linux_REDIR_FOR_strlen)
327.type   VG_(ppc32_linux_REDIR_FOR_strlen), @function
328VG_(ppc32_linux_REDIR_FOR_strlen):
329        lbz 4,0(3)
330        li 9,0
331        cmpwi 0,4,0
332        beq- 0,.L18
333.L19:
334        lbzu 5,1(3)
335        addi 9,9,1
336        cmpwi 0,5,0
337        bne+ 0,.L19
338.L18:
339        mr 3,9
340        blr
341.size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
342
343/* Ditto strcmp */
344.global VG_(ppc32_linux_REDIR_FOR_strcmp)
345.type   VG_(ppc32_linux_REDIR_FOR_strcmp), @function
346VG_(ppc32_linux_REDIR_FOR_strcmp):
347.L20:
348        lbz 0,0(3)
349        cmpwi 7,0,0
350        bne- 7,.L21
351        lbz 0,0(4)
352        li 11,0
353        cmpwi 7,0,0
354        beq- 7,.L22
355.L21:
356        lbz 0,0(3)
357        li 11,-1
358        cmpwi 7,0,0
359        beq- 7,.L22
360        lbz 0,0(4)
361        li 11,1
362        cmpwi 7,0,0
363        beq- 7,.L22
364        lbz 9,0(3)
365        lbz 0,0(4)
366        li 11,-1
367        cmplw 7,9,0
368        blt- 7,.L22
369        lbz 9,0(3)
370        lbz 0,0(4)
371        li 11,1
372        addi 3,3,1
373        addi 4,4,1
374        cmplw 7,9,0
375        ble+ 7,.L20
376.L22:
377        mr 3,11
378        blr
379.size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
380
381/* Ditto index/strchr */
382.global VG_(ppc32_linux_REDIR_FOR_strchr)
383.type   VG_(ppc32_linux_REDIR_FOR_strchr), @function
384VG_(ppc32_linux_REDIR_FOR_strchr):
385        lbz 0,0(3)
386        rlwinm 4,4,0,0xff
387        cmpw 7,4,0
388        beqlr 7
389        cmpwi 7,0,0
390        bne 7,.L308
391        b .L304
392.L309:
393        beq 6,.L304
394.L308:
395        lbzu 0,1(3)
396        cmpw 7,4,0
397        cmpwi 6,0,0
398        bne 7,.L309
399        blr
400.L304:
401        li 3,0
402        blr
403.size   VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
404
405.global VG_(trampoline_stuff_end)
406VG_(trampoline_stuff_end):
407
408	/* and a trailing page of unexecutable code */
409	UD2_PAGE
410
411#	undef UD2_16
412#	undef UD2_64
413#	undef UD2_256
414#	undef UD2_1024
415#	undef UD2_PAGE
416
417/*---------------- ppc64-linux ----------------*/
418#else
419#if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
420
421#	define UD2_16     trap ; trap ; trap; trap
422#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
423#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
424#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
425#	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
426
427	/* a leading page of unexecutable code */
428	UD2_PAGE
429
430.global VG_(trampoline_stuff_start)
431VG_(trampoline_stuff_start):
432
433.global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn)
434VG_(ppc64_linux_SUBST_FOR_rt_sigreturn):
435	li 0,__NR_rt_sigreturn
436        sc
437        .long 0	/*illegal insn*/
438
439	/* See comment in pub_core_trampoline.h for what this is for */
440.global VG_(ppctoc_magic_redirect_return_stub)
441VG_(ppctoc_magic_redirect_return_stub):
442	trap
443
444	/* this function is written using the "dotless" ABI convention */
445	.align 2
446	.globl VG_(ppc64_linux_REDIR_FOR_strlen)
447#if !defined VGP_ppc64be_linux || _CALL_ELF == 2
448        /* Little Endian uses ELF version 2 */
449        .type VG_(ppc64_linux_REDIR_FOR_strlen),@function
450VG_(ppc64_linux_REDIR_FOR_strlen):
451#else
452        /* Big Endian uses ELF version 1 */
453	.section        ".opd","aw"
454	.align 3
455VG_(ppc64_linux_REDIR_FOR_strlen):
456	.quad   .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
457	.previous
458	.size	VG_(ppc64_linux_REDIR_FOR_strlen), \
459			.L0end-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
460	.type	VG_(ppc64_linux_REDIR_FOR_strlen), @function
461
462.L.VG_(ppc64_linux_REDIR_FOR_strlen):
463#endif
464#if _CALL_ELF == 2
4650:      addis        2,12,.TOC.-0b@ha
466        addi         2,2,.TOC.-0b@l
467        .localentry  VG_(ppc64_linux_REDIR_FOR_strlen), .-VG_(ppc64_linux_REDIR_FOR_strlen)
468#endif
469        mr 9,3
470        lbz 0,0(3)
471        li 3,0
472        cmpwi 7,0,0
473        beqlr 7
474        li 3,0
475.L01:
476        addi 0,3,1
477        extsw 3,0
478        lbzx 0,9,3
479        cmpwi 7,0,0
480        bne 7,.L01
481        blr
482
483#if !defined VGP_ppc64be_linux || _CALL_ELF == 2
484        .size VG_(ppc64_linux_REDIR_FOR_strlen),.-VG_(ppc64_linux_REDIR_FOR_strlen)
485#else
486        .size VG_(ppc64_linux_REDIR_FOR_strlen),.-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
487#endif
488        .long 0
489        .byte 0,0,0,0,0,0,0,0
490.L0end:
491
492        /* this function is written using the "dotless" ABI convention */
493        .align 2
494        .globl VG_(ppc64_linux_REDIR_FOR_strchr)
495#if !defined VGP_ppc64be_linux || _CALL_ELF == 2
496        .type   VG_(ppc64_linux_REDIR_FOR_strchr),@function
497VG_(ppc64_linux_REDIR_FOR_strchr):
498#else
499	.section        ".opd","aw"
500	.align 3
501VG_(ppc64_linux_REDIR_FOR_strchr):
502        .quad   .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
503        .previous
504        .size   VG_(ppc64_linux_REDIR_FOR_strchr), \
505                        .L1end-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
506        .type   VG_(ppc64_linux_REDIR_FOR_strchr),@function
507
508.L.VG_(ppc64_linux_REDIR_FOR_strchr):
509#endif
510#if  _CALL_ELF == 2
5110:      addis         2,12,.TOC.-0b@ha
512        addi         2,2,.TOC.-0b@l
513        .localentry VG_(ppc64_linux_REDIR_FOR_strchr), .-VG_(ppc64_linux_REDIR_FOR_strchr)
514#endif
515        lbz 0,0(3)
516        rldicl 4,4,0,56
517        cmpw 7,4,0
518        beqlr 7
519        cmpdi 7,0,0
520        bne 7,.L18
521        b .L14
522#if !defined VGP_ppc64be_linux || _CALL_ELF == 2
523        .size VG_(ppc64_linux_REDIR_FOR_strchr),.-VG_(ppc64_linux_REDIR_FOR_strchr)
524#else
525        .size VG_(ppc64_linux_REDIR_FOR_strchr),.-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
526#endif
527.L19:
528        beq 6,.L14
529.L18:
530        lbzu 0,1(3)
531        cmpw 7,4,0
532        cmpdi 6,0,0
533        bne 7,.L19
534        blr
535.L14:
536        li 3,0
537        blr
538        .long 0
539        .byte 0,0,0,0,0,0,0,0
540.L1end:
541
542
543.global VG_(trampoline_stuff_end)
544VG_(trampoline_stuff_end):
545
546	/* and a trailing page of unexecutable code */
547	UD2_PAGE
548
549#	undef UD2_16
550#	undef UD2_64
551#	undef UD2_256
552#	undef UD2_1024
553#	undef UD2_PAGE
554
555/*---------------- arm-linux ----------------*/
556#else
557#if defined(VGP_arm_linux)
558
559#       define UD2_4      .word 0xFFFFFFFF
560#	define UD2_16     UD2_4    ; UD2_4    ; UD2_4    ; UD2_4
561#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
562#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
563#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
564#	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
565
566	/* a leading page of unexecutable code */
567	UD2_PAGE
568
569.global VG_(trampoline_stuff_start)
570VG_(trampoline_stuff_start):
571
572.global VG_(arm_linux_SUBST_FOR_sigreturn)
573.type   VG_(arm_linux_SUBST_FOR_sigreturn),#function
574VG_(arm_linux_SUBST_FOR_sigreturn):
575	mov r7, # __NR_sigreturn
576        svc #0
577        .long 0xFFFFFFFF /*illegal insn*/
578.size VG_(arm_linux_SUBST_FOR_sigreturn), .-VG_(arm_linux_SUBST_FOR_sigreturn)
579
580.global VG_(arm_linux_SUBST_FOR_rt_sigreturn)
581.type   VG_(arm_linux_SUBST_FOR_rt_sigreturn),#function
582VG_(arm_linux_SUBST_FOR_rt_sigreturn):
583	mov r7, # __NR_rt_sigreturn
584        svc #0
585        .long 0xFFFFFFFF /*illegal insn*/
586.size VG_(arm_linux_SUBST_FOR_rt_sigreturn), .-VG_(arm_linux_SUBST_FOR_rt_sigreturn)
587
588.global VG_(arm_linux_REDIR_FOR_strlen)
589VG_(arm_linux_REDIR_FOR_strlen):
590	mov	r2, r0
591	ldrb	r0, [r0, #0]	@ zero_extendqisi2
592	@ lr needed for prologue
593	cmp	r0, #0
594	bxeq	lr
595	mov	r0, #0
596.L5:
597	add	r0, r0, #1
598	ldrb	r3, [r0, r2]	@ zero_extendqisi2
599	cmp	r3, #0
600	bne	.L5
601	bx	lr
602	UD2_4
603
604//.global VG_(arm_linux_REDIR_FOR_index)
605//VG_(arm_linux_REDIR_FOR_index):
606//	ldrb	r3, [r0, #0]	@ zero_extendqisi2
607//	and	r1, r1, #255
608//	cmp	r3, r1
609//	@ lr needed for prologue
610//	bne	.L9
611//	bx	lr
612//.L12:
613//	ldrb	r3, [r0, #1]!	@ zero_extendqisi2
614//	cmp	r3, r1
615//	beq	.L11
616//.L9:
617//	cmp	r3, #0
618//	bne	.L12
619//	mov	r0, #0
620//	bx	lr
621//.L11:
622//	bx	lr
623//	UD2_4
624
625.global VG_(arm_linux_REDIR_FOR_memcpy)
626VG_(arm_linux_REDIR_FOR_memcpy):
627	stmfd	sp!, {r4, r5, lr}
628	subs	lr, r2, #0
629	mov	r5, r0
630	beq	.L2
631	cmp	r0, r1
632	bls	.L4
633	add	r3, r0, lr
634	add	r1, lr, r1
635	cmp	lr, #3
636	sub	r4, r3, #1
637	sub	r0, r1, #1
638	ble	.L28
639	sub	ip, r3, #5
640	sub	r1, r1, #5
641.L8:
642	ldrb	r3, [r1, #4]	@ zero_extendqisi2
643	sub	lr, lr, #4
644	strb	r3, [ip, #4]
645	ldrb	r2, [r1, #3]	@ zero_extendqisi2
646	cmp	lr, #3
647	strb	r2, [ip, #3]
648	ldrb	r3, [r1, #2]	@ zero_extendqisi2
649	mov	r4, ip
650	strb	r3, [ip, #2]
651	ldrb	r2, [r1, #1]	@ zero_extendqisi2
652	mov	r0, r1
653	strb	r2, [ip, #1]
654	sub	r1, r1, #4
655	sub	ip, ip, #4
656	bgt	.L8
657	cmp	lr, #0
658	beq	.L2
659.L28:
660	sub	r2, lr, #1
661.L21:
662	sub	r2, r2, #1
663	ldrb	r3, [r0], #-1	@ zero_extendqisi2
664	cmn	r2, #1
665	strb	r3, [r4], #-1
666	bne	.L21
667.L2:
668	mov	r0, r5
669	ldmfd	sp!, {r4, r5, pc}
670.L4:
671	bcs	.L2
672	cmp	lr, #3
673	mov	ip, r0
674	ble	.L29
675.L19:
676	ldrb	r3, [r1, #0]	@ zero_extendqisi2
677	sub	lr, lr, #4
678	strb	r3, [ip, #0]
679	ldrb	r2, [r1, #1]	@ zero_extendqisi2
680	cmp	lr, #3
681	strb	r2, [ip, #1]
682	ldrb	r3, [r1, #2]	@ zero_extendqisi2
683	strb	r3, [ip, #2]
684	ldrb	r2, [r1, #3]	@ zero_extendqisi2
685	add	r1, r1, #4
686	strb	r2, [ip, #3]
687	add	ip, ip, #4
688	bgt	.L19
689	cmp	lr, #0
690	beq	.L2
691.L29:
692	sub	r2, lr, #1
693.L20:
694	sub	r2, r2, #1
695	ldrb	r3, [r1], #1	@ zero_extendqisi2
696	cmn	r2, #1
697	strb	r3, [ip], #1
698	bne	.L20
699	mov	r0, r5
700	ldmfd	sp!, {r4, r5, pc}
701	UD2_4
702
703.global VG_(arm_linux_REDIR_FOR_strcmp)
704VG_(arm_linux_REDIR_FOR_strcmp):
705.L64:
706	ldrb	r3, [r0], #1	@ zero_extendqisi2
707	ldrb	r2, [r1], #1	@ zero_extendqisi2
708	cmp	r3, #0
709	beq	.L67
710	cmp	r3, r2
711	beq	.L64
712	rsb	r0, r2, r3
713	bx	lr
714.L67:
715	rsb	r0, r2, #0
716	bx	lr
717	UD2_4
718
719.global VG_(trampoline_stuff_end)
720VG_(trampoline_stuff_end):
721
722	/* and a trailing page of unexecutable code */
723	UD2_PAGE
724
725#	undef UD2_4
726#	undef UD2_16
727#	undef UD2_64
728#	undef UD2_256
729#	undef UD2_1024
730#	undef UD2_PAGE
731
732/*---------------- arm64-linux ----------------*/
733#else
734#if defined(VGP_arm64_linux)
735
736#       define UD2_4      .word 0xFFFFFFFF
737#	define UD2_16     UD2_4    ; UD2_4    ; UD2_4    ; UD2_4
738#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
739#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
740#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
741#	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
742
743	/* a leading page of unexecutable code */
744	UD2_PAGE
745
746.global VG_(trampoline_stuff_start)
747VG_(trampoline_stuff_start):
748
749.global VG_(arm64_linux_SUBST_FOR_rt_sigreturn)
750.type   VG_(arm64_linux_SUBST_FOR_rt_sigreturn),#function
751VG_(arm64_linux_SUBST_FOR_rt_sigreturn):
752	mov x8, # __NR_rt_sigreturn
753        svc #0
754        .long 0xFFFFFFFF /*illegal insn*/
755.size VG_(arm64_linux_SUBST_FOR_rt_sigreturn), \
756        .-VG_(arm64_linux_SUBST_FOR_rt_sigreturn)
757
758.global VG_(arm64_linux_REDIR_FOR_strlen)
759.type   VG_(arm64_linux_REDIR_FOR_strlen),#function
760VG_(arm64_linux_REDIR_FOR_strlen):
761	mov	x2, x0
762	ldrb	w0, [x0]
763	cbz	w0, .L5
764	mov	x0, 0
765.L4:
766	add	x0, x0, 1
767	ldrb	w1, [x2,x0]
768	cbnz	w1, .L4
769	ret
770.L5:
771	mov	x0, 0
772	ret
773.size VG_(arm64_linux_REDIR_FOR_strlen), .-VG_(arm64_linux_REDIR_FOR_strlen)
774
775.global VG_(arm64_linux_REDIR_FOR_index)
776.type   VG_(arm64_linux_REDIR_FOR_index),#function
777VG_(arm64_linux_REDIR_FOR_index):
778        ldrb    w2, [x0]
779        uxtb    w1, w1
780        cmp     w2, w1
781        beq     .L11
782.L13:
783        cbz     w2, .L16
784        ldrb    w2, [x0,1]!
785        cmp     w2, w1
786        bne     .L13
787.L11:
788        ret
789.L16:
790        mov     x0, 0
791        ret
792.size VG_(arm64_linux_REDIR_FOR_index), .-VG_(arm64_linux_REDIR_FOR_index)
793
794.global VG_(arm64_linux_REDIR_FOR_strcmp)
795.type   VG_(arm64_linux_REDIR_FOR_strcmp),#function
796VG_(arm64_linux_REDIR_FOR_strcmp):
797        ldrb    w2, [x0]
798        ldrb    w3, [x1]
799        cmp     w2, w3
800        bcc     .L22
801.L21:
802        bhi     .L25
803        cbz     w2, .L26
804        ldrb    w2, [x0,1]!
805        ldrb    w3, [x1,1]!
806        cmp     w2, w3
807        bcs     .L21
808.L22:
809        mov     x0, -1
810        ret
811.L25:
812        mov     x0, 1
813        ret
814.L26:
815        mov     x0, 0
816        ret
817.size VG_(arm64_linux_REDIR_FOR_strcmp), .-VG_(arm64_linux_REDIR_FOR_strcmp)
818
819.global VG_(trampoline_stuff_end)
820VG_(trampoline_stuff_end):
821
822	/* and a trailing page of unexecutable code */
823	UD2_PAGE
824
825#	undef UD2_4
826#	undef UD2_16
827#	undef UD2_64
828#	undef UD2_256
829#	undef UD2_1024
830#	undef UD2_PAGE
831
832/*---------------- x86-darwin ----------------*/
833#else
834#if defined(VGP_x86_darwin)
835
836        /* a leading page of unexecutable code */
837.fill 2048, 2, 0x0b0f /* `ud2` */
838
839.globl VG_(trampoline_stuff_start)
840VG_(trampoline_stuff_start):
841
842.globl VG_(x86_darwin_SUBST_FOR_sigreturn)
843VG_(x86_darwin_SUBST_FOR_sigreturn):
844        /* XXX does this need to have any special form? (cf x86-linux
845	version) */
846        movl    $ __NR_DARWIN_FAKE_SIGRETURN, %eax
847        int     $0x80
848        ud2
849
850.globl VG_(x86_darwin_REDIR_FOR_strlen)
851VG_(x86_darwin_REDIR_FOR_strlen):
852        movl    4(%esp), %edx
853        movl    %edx, %eax
854        jmp     1f
8550:
856        incl    %eax
8571:
858        cmpb    $0, (%eax)
859        jne     0b
860        subl    %edx, %eax
861        ret
862
863.globl VG_(x86_darwin_REDIR_FOR_strcat)
864VG_(x86_darwin_REDIR_FOR_strcat):
865        pushl   %esi
866        movl    8(%esp), %esi
867        movl    12(%esp), %ecx
868        movl    %esi, %edx
869        jmp     1f
8700:
871        incl    %edx
8721:
873        cmpb    $0, (%edx)
874        jne     0b
8752:
876        movzbl  (%ecx), %eax
877        incl    %ecx
878        movb    %al, (%edx)
879        incl    %edx
880        testb   %al, %al
881        jne     2b
882        movl    %esi, %eax
883        popl    %esi
884        ret
885
886
887.globl VG_(x86_darwin_REDIR_FOR_strcmp)
888VG_(x86_darwin_REDIR_FOR_strcmp):
889        movl    4(%esp), %edx
890        movl    8(%esp), %ecx
891        jmp     1f
8920:
893        incl    %edx
894        incl    %ecx
8951:
896        movzbl  (%edx), %eax
897        testb   %al, %al
898        je      2f
899        cmpb    (%ecx), %al
900        je      0b
9012:
902        movzbl  (%ecx),%edx
903        movzbl  %al,%eax
904        subl    %edx, %eax
905        ret
906
907
908.globl VG_(x86_darwin_REDIR_FOR_strcpy)
909VG_(x86_darwin_REDIR_FOR_strcpy):
910	pushl	%ebp
911	movl	%esp, %ebp
912	pushl	%esi
913	movl	8(%ebp), %esi
914	movl	12(%ebp), %ecx
915	movl	%esi, %edx
916	jmp	1f
9170:
918	incl	%ecx
919	incl	%edx
9201:
921	movzbl	(%ecx), %eax
922	testb	%al, %al
923	movb	%al, (%edx)
924	jne	0b
925	movl	%esi, %eax
926	popl	%esi
927	leave
928	ret
929
930.globl VG_(x86_darwin_REDIR_FOR_strlcat)
931VG_(x86_darwin_REDIR_FOR_strlcat):
932	pushl	%ebp
933	movl	%esp, %ebp
934	pushl	%edi
935	pushl	%esi
936	subl	$16, %esp
937	movl	8(%ebp), %esi
938	movl	16(%ebp), %ecx
939	movl	%esi, %edx
940	leal	(%ecx,%esi), %eax
941	jmp	1f
9420:
943	incl	%edx
9441:
945	cmpl	%edx, %eax
946	je	2f
947	cmpb	$0, (%edx)
948	jne	0b
9492:
950	movl	%edx, %edi
951	subl	%esi, %edi
952	movl	%ecx, %esi
953	subl	%edi, %esi
954	je	3f
955	movl	12(%ebp), %eax
956	jmp	6f
9573:
958	movl	12(%ebp), %eax
959	movl	%eax, (%esp)
960	call	VG_(x86_darwin_REDIR_FOR_strlen)
961	jmp	7f
9624:
963	cmpl	$1, %esi
964	je	5f
965	movb	%cl, (%edx)
966	decl	%esi
967	incl	%edx
9685:
969	incl	%eax
9706:
971	movzbl	(%eax), %ecx
972	testb	%cl, %cl
973	jne	4b
974	movb	$0, (%edx)
975	subl	12(%ebp), %eax
9767:
977	addl	$16, %esp
978	leal	(%edi,%eax), %eax
979	popl	%esi
980	popl	%edi
981	leave
982	ret
983
984
985.globl VG_(trampoline_stuff_end)
986VG_(trampoline_stuff_end):
987
988        /* a trailing page of unexecutable code */
989.fill 2048, 2, 0x0b0f /* `ud2` */
990
991
992/*---------------- amd64-darwin ----------------*/
993#else
994#if defined(VGP_amd64_darwin)
995
996        /* a leading page of unexecutable code */
997.fill 2048, 2, 0x0b0f /* `ud2` */
998
999.globl VG_(trampoline_stuff_start)
1000VG_(trampoline_stuff_start):
1001
1002.globl VG_(amd64_darwin_SUBST_FOR_sigreturn)
1003VG_(amd64_darwin_SUBST_FOR_sigreturn):
1004        /* XXX does this need to have any special form? (cf x86-linux
1005	version) */
1006        movq    $ __NR_DARWIN_FAKE_SIGRETURN, %rax
1007        syscall
1008        ud2
1009
1010.globl VG_(amd64_darwin_REDIR_FOR_strlen)
1011VG_(amd64_darwin_REDIR_FOR_strlen):
1012        movq    %rdi, %rax
1013        jmp     1f
10140:
1015        incq    %rax
10161:
1017        cmpb    $0, (%rax)
1018        jne     0b
1019        subq    %rdi, %rax
1020        ret
1021
1022.globl VG_(amd64_darwin_REDIR_FOR_strcat)
1023VG_(amd64_darwin_REDIR_FOR_strcat):
1024	movq	%rdi, %rdx
1025	jmp	1f
10260:
1027	incq	%rdx
10281:
1029	cmpb	$0, (%rdx)
1030	jne	0b
10312:
1032	movzbl	(%rsi), %eax
1033	incq	%rsi
1034	movb	%al, (%rdx)
1035	incq	%rdx
1036	testb	%al, %al
1037	jne	2b
1038	movq	%rdi, %rax
1039	ret
1040
1041
1042.globl VG_(amd64_darwin_REDIR_FOR_strcmp)
1043VG_(amd64_darwin_REDIR_FOR_strcmp):
1044	jmp	1f
10450:
1046	incq	%rdi
1047	incq	%rsi
10481:
1049	movzbl	(%rdi), %eax
1050	testb	%al, %al
1051	je	2f
1052	cmpb	(%rsi), %al
1053	je	0b
10542:
1055	movzbl	(%rsi), %edx
1056	movzbl	%al, %eax
1057	subl	%edx, %eax
1058	ret
1059
1060.globl VG_(amd64_darwin_REDIR_FOR_strcpy)
1061VG_(amd64_darwin_REDIR_FOR_strcpy):
1062	pushq	%rbp
1063	movq	%rdi, %rdx
1064	movq	%rsp, %rbp
1065	jmp	1f
10660:
1067	incq	%rsi
1068	incq	%rdx
10691:
1070	movzbl	(%rsi), %eax
1071	testb	%al, %al
1072	movb	%al, (%rdx)
1073	jne	0b
1074	leave
1075	movq	%rdi, %rax
1076	ret
1077
1078.globl VG_(amd64_darwin_REDIR_FOR_strlcat)
1079VG_(amd64_darwin_REDIR_FOR_strlcat):
1080	pushq	%rbp
1081	leaq	(%rdx,%rdi), %rax
1082	movq	%rdi, %rcx
1083	movq	%rsp, %rbp
1084	pushq	%rbx
1085	subq	$8, %rsp
1086	jmp	1f
10870:
1088	incq	%rcx
10891:
1090	cmpq	%rcx, %rax
1091	je	2f
1092	cmpb	$0, (%rcx)
1093	jne	0b
10942:
1095	movq	%rcx, %rbx
1096	subq	%rdi, %rbx
1097	movq	%rdx, %rdi
1098	subq	%rbx, %rdi
1099	je	3f
1100	movq	%rsi, %rax
1101	jmp	6f
11023:
1103	movq	%rsi, %rdi
1104	call	VG_(amd64_darwin_REDIR_FOR_strlen)
1105	jmp	7f
11064:
1107	cmpq	$1, %rdi
1108	je	5f
1109	movb	%dl, (%rcx)
1110	decq	%rdi
1111	incq	%rcx
11125:
1113	incq	%rax
11146:
1115	movzbl	(%rax), %edx
1116	testb	%dl, %dl
1117	jne	4b
1118	movb	$0, (%rcx)
1119	subq	%rsi, %rax
11207:
1121	leaq	(%rbx,%rax), %rax
1122	addq	$8, %rsp
1123	popq	%rbx
1124	leave
1125	ret
1126
1127.globl VG_(amd64_darwin_REDIR_FOR_arc4random)
1128VG_(amd64_darwin_REDIR_FOR_arc4random):
1129	/* not very random, hope dyld won't mind */
1130	movq	$0x76616c6772696e64, %rax
1131	ret
1132
1133.globl VG_(amd64_darwin_REDIR_FOR_strchr)
1134VG_(amd64_darwin_REDIR_FOR_strchr):
1135        pushq   %rbp
1136        movq    %rsp, %rbp
1137        movb    (%rdi), %cl
1138        cmpb    %sil, %cl
1139        jne     1f
1140        movq    %rdi, %rax
1141        popq    %rbp
1142        ret
11431:
1144        testb   %cl, %cl
1145        movl    $0, %eax
1146        je      2f
1147        movb    1(%rdi), %cl
1148        incq    %rdi
1149        cmpb    %sil, %cl
1150        movq    %rdi, %rax
1151        jne     1b
11522:
1153        popq    %rbp
1154        ret
1155
1156.globl VG_(trampoline_stuff_end)
1157VG_(trampoline_stuff_end):
1158
1159        /* a trailing page of unexecutable code */
1160.fill 2048, 2, 0x0b0f /* `ud2` */
1161
1162
1163/*---------------- s390x-linux ----------------*/
1164#else
1165#if defined(VGP_s390x_linux)
1166
1167        /* a leading page of unexecutable code */
1168	.fill 2048, 2, 0x0000
1169
1170.global VG_(trampoline_stuff_start)
1171VG_(trampoline_stuff_start):
1172
1173.global VG_(s390x_linux_SUBST_FOR_sigreturn)
1174VG_(s390x_linux_SUBST_FOR_sigreturn):
1175        svc __NR_sigreturn
1176	.short 0
1177
1178.global VG_(s390x_linux_SUBST_FOR_rt_sigreturn)
1179VG_(s390x_linux_SUBST_FOR_rt_sigreturn):
1180        /* Old gcc unwinding code checks for a sig(_rt)_return svc and then
1181           for ra = cfa to decide if it is a sig_rt_frame or not. Since we
1182           set ra to this trampoline, but the cfa is still in the stack,
1183           the unwinder thinks, that this is a non-rt frame  and causes a
1184           crash in the gcc unwinder - which is used by the thread library
1185           and others. Therefore we add a lr 1,1 nop, to let the gcc
1186           unwinder bail out gracefully. This might also affect unwinding
1187           across the signal frame - tough luck. fixs390 */
1188        lr 1,1
1189        svc __NR_rt_sigreturn
1190	.short 0
1191
1192.global VG_(s390x_linux_REDIR_FOR_index)
1193.type   VG_(s390x_linux_REDIR_FOR_index),@function
1194VG_(s390x_linux_REDIR_FOR_index):
1195#
1196#   %r2 = addess of string
1197#   %r3 = character to find
1198#
1199        lghi    %r0,255
1200        ngr     %r0,%r3        # r0 = (unsigned char)r3
1201        lghi    %r4,0
1202.L1:
1203        llgc    %r1,0(%r2)     # r1 = byte from string
1204        cr      %r1,%r0        # compare
1205        ber     %r14           # return if found
1206        cr      %r1,%r4        # end of string ?
1207        je      .L2
1208        aghi    %r2,1          # increment r2
1209        j       .L1
1210.L2:    lghi    %r2,0          # return value 0
1211        br      %r14
1212.size VG_(s390x_linux_REDIR_FOR_index), .-VG_(s390x_linux_REDIR_FOR_index)
1213
1214.globl VG_(trampoline_stuff_end)
1215VG_(trampoline_stuff_end):
1216	.fill 2048, 2, 0x0000
1217
1218/*---------------------- mips32-linux ----------------------*/
1219#else
1220#if defined(VGP_mips32_linux)
1221
1222#	define UD2_16     trap ; trap ; trap; trap
1223#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
1224#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
1225#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
1226#	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
1227
1228
1229.global VG_(trampoline_stuff_start)
1230VG_(trampoline_stuff_start):
1231
1232.global VG_(mips32_linux_SUBST_FOR_sigreturn)
1233VG_(mips32_linux_SUBST_FOR_sigreturn):
1234        li $v0,__NR_sigreturn
1235        syscall
1236        nop
1237        .long 0	/*illegal insn*/
1238
1239.global VG_(mips32_linux_SUBST_FOR_rt_sigreturn)
1240VG_(mips32_linux_SUBST_FOR_rt_sigreturn):
1241	li $v0,__NR_rt_sigreturn
1242        syscall
1243        nop
1244        .long 0	/*illegal insn*/
1245
1246/* There's no particular reason that this needs to be handwritten
1247   assembly, but since that's what this file contains, here's a
1248   simple strlen implementation (written in C and compiled by gcc.)
1249*/
1250.global VG_(mips32_linux_REDIR_FOR_strlen)
1251.type   VG_(mips32_linux_REDIR_FOR_strlen), @function
1252VG_(mips32_linux_REDIR_FOR_strlen):
1253      li $v0, 0
1254      //la $a0, string
1255      j strlen_cond
1256   strlen_loop:
1257      addi $v0, $v0, 1
1258      addi $a0, $a0, 1
1259   strlen_cond:
1260      lbu $t0, ($a0)
1261      bne $t0, $zero, strlen_loop
1262    jr $ra
1263
1264.size VG_(mips32_linux_REDIR_FOR_strlen), .-VG_(mips32_linux_REDIR_FOR_strlen)
1265
1266.global VG_(trampoline_stuff_end)
1267VG_(trampoline_stuff_end):
1268
1269
1270#	undef UD2_16
1271#	undef UD2_64
1272#	undef UD2_256
1273#	undef UD2_1024
1274#	undef UD2_PAGE
1275
1276/*---------------------- mips64-linux ----------------------*/
1277#else
1278#if defined(VGP_mips64_linux)
1279
1280#       define UD2_16     trap ; trap ; trap; trap
1281#       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
1282#       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
1283#       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
1284#       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
1285
1286.global VG_(trampoline_stuff_start)
1287VG_(trampoline_stuff_start):
1288
1289.global VG_(mips64_linux_SUBST_FOR_rt_sigreturn)
1290VG_(mips64_linux_SUBST_FOR_rt_sigreturn):
1291        li $2,__NR_rt_sigreturn
1292        syscall
1293        nop
1294        .long 0	/*illegal insn*/
1295
1296/* There's no particular reason that this needs to be handwritten
1297   assembly, but since that's what this file contains, here's a
1298   simple strlen implementation (written in C and compiled by gcc.)
1299*/
1300.global VG_(mips64_linux_REDIR_FOR_strlen)
1301.type   VG_(mips64_linux_REDIR_FOR_strlen), @function
1302VG_(mips64_linux_REDIR_FOR_strlen):
1303        lbu $12, 0($4)
1304        li  $13, 0
1305        beq $12, $0, M01
1306        nop
1307
1308M02:
1309        addiu $13, $13, 1
1310        addiu $4, $4, 1
1311        lbu $12, 0($4)
1312        bne $12, $0, M02
1313        nop
1314
1315M01:
1316        move $2, $13
1317        jr $31
1318        nop
1319
1320.size VG_(mips64_linux_REDIR_FOR_strlen), .-VG_(mips64_linux_REDIR_FOR_strlen)
1321
1322.global VG_(trampoline_stuff_end)
1323VG_(trampoline_stuff_end):
1324
1325
1326#	undef UD2_16
1327#	undef UD2_64
1328#	undef UD2_256
1329#	undef UD2_1024
1330#	undef UD2_PAGE
1331
1332#else
1333#if defined(VGP_tilegx_linux)
1334
1335#	define UD2_16     ill ; ill
1336#	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
1337#	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
1338#	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
1339#	define UD2_4K     UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
1340#	define UD2_16K    UD2_4K   ; UD2_4K   ; UD2_4K   ; UD2_4K
1341#	define UD2_PAGE   UD2_16K  ; UD2_16K  ; UD2_16K  ; UD2_16K
1342	/* a leading page of unexecutable code */
1343	UD2_PAGE
1344
1345.global VG_(trampoline_stuff_start)
1346VG_(trampoline_stuff_start):
1347
1348.global VG_(tilegx_linux_SUBST_FOR_rt_sigreturn)
1349VG_(tilegx_linux_SUBST_FOR_rt_sigreturn):
1350        /* This is a very specific sequence which GDB uses to
1351           recognize signal handler frames. */
1352        moveli  r10, __NR_rt_sigreturn
1353        swint1
1354        ill
1355
1356.global VG_(tilegx_linux_REDIR_FOR_vgettimeofday)
1357.type   VG_(tilegx_linux_REDIR_FOR_vgettimeofday), @function
1358VG_(tilegx_linux_REDIR_FOR_vgettimeofday):
1359        moveli  r10, __NR_gettimeofday
1360        swint1
1361        jrp lr
1362.size VG_(tilegx_linux_REDIR_FOR_vgettimeofday), .-VG_(tilegx_linux_REDIR_FOR_vgettimeofday)
1363
1364.global VG_(tilegx_linux_REDIR_FOR_vtime)
1365.type   VG_(tilegx_linux_REDIR_FOR_vtime), @function
1366VG_(tilegx_linux_REDIR_FOR_vtime):
1367        moveli  r10, __NR_gettimeofday
1368        swint1
1369        jrp lr
1370.size VG_(tilegx_linux_REDIR_FOR_vtime), .-VG_(tilegx_linux_REDIR_FOR_vtime)
1371
1372.global VG_(tilegx_linux_REDIR_FOR_strlen)
1373.type   VG_(tilegx_linux_REDIR_FOR_strlen), @function
1374VG_(tilegx_linux_REDIR_FOR_strlen):
1375        {
1376         movei   r1, 0
1377         beqz    r0, 2f
1378        }
13791:      {
1380         addi     r1, r1, 1
1381         ld1s_add r2, r0, 1
1382        }
1383        bnezt   r2, 1b
1384        addi    r1, r1, -1
13852:      move    r0, r1
1386        jrp     lr
1387.size VG_(tilegx_linux_REDIR_FOR_strlen), .-VG_(tilegx_linux_REDIR_FOR_strlen)
1388
1389.global VG_(trampoline_stuff_end)
1390VG_(trampoline_stuff_end):
1391
1392	/* and a trailing page of unexecutable code */
1393	UD2_PAGE
1394
1395#	undef UD2_16
1396#	undef UD2_64
1397#	undef UD2_256
1398#	undef UD2_1024
1399#	undef UD2_4K
1400#	undef UD2_16K
1401#	undef UD2_PAGE
1402/*---------------- unknown ----------------*/
1403#else
1404#  error Unknown platform
1405
1406#endif
1407#endif
1408#endif
1409#endif
1410#endif
1411#endif
1412#endif
1413#endif
1414#endif
1415#endif
1416#endif
1417#endif
1418
1419#if defined(VGO_linux)
1420/* Let the linker know we don't need an executable stack */
1421#  if defined(VGP_arm_linux)
1422   .section .note.GNU-stack,"",%progbits
1423#  else
1424   .section .note.GNU-stack,"",@progbits
1425#  endif
1426#endif
1427
1428/*--------------------------------------------------------------------*/
1429/*--- end                                                          ---*/
1430/*--------------------------------------------------------------------*/
1431