2 /*--------------------------------------------------------------------*/
3 /*--- Trampoline code page stuff. m_trampoline.S ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2010 Julian Seward
12 Copyright (C) 2006-2010 OpenWorks LLP
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
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 ------------------ */
38 Replacements for some functions to do with vsyscalls and signals.
39 This code runs on the simulated CPU.
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 */
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 */
64 movl $ __NR_sigreturn, %eax
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
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 )
81 unsigned char ch = (unsigned char)((unsigned int)c);
82 unsigned char* p = (unsigned char*)s;
84 if (*p == ch) return p;
85 if (*p == 0) return 0;
90 .global VG_(x86_linux_REDIR_FOR_index)
91 .type VG_(x86_linux_REDIR_FOR_index), @function
92 VG_(x86_linux_REDIR_FOR_index):
113 .size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index)
115 .global VG_(trampoline_stuff_end)
116 VG_(trampoline_stuff_end):
118 /* and a trailing page of unexecutable code */
127 /*---------------------- amd64-linux ----------------------*/
129 #if defined(VGP_amd64_linux)
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
137 /* a leading page of unexecutable code */
140 .global VG_(trampoline_stuff_start)
141 VG_(trampoline_stuff_start):
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
151 .global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
152 .type VG_(amd64_linux_REDIR_FOR_vgettimeofday), @function
153 VG_(amd64_linux_REDIR_FOR_vgettimeofday):
155 movq $__NR_gettimeofday, %rax
159 .size VG_(amd64_linux_REDIR_FOR_vgettimeofday), .-.LfnB2
161 .global VG_(amd64_linux_REDIR_FOR_vtime)
162 .type VG_(amd64_linux_REDIR_FOR_vtime), @function
163 VG_(amd64_linux_REDIR_FOR_vtime):
165 movq $__NR_time, %rax
169 .size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
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.)
175 .global VG_(amd64_linux_REDIR_FOR_strlen)
176 .type VG_(amd64_linux_REDIR_FOR_strlen), @function
177 VG_(amd64_linux_REDIR_FOR_strlen):
190 .size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
193 /* A CIE for the above three functions, followed by their FDEs */
194 .section .eh_frame,"a",@progbits
196 .long .LEcie1-.LScie1
214 .long .LEfde2-.LASfde2
216 .long .LASfde2-.Lframe1
223 .long .LEfde3-.LASfde3
225 .long .LASfde3-.Lframe1
232 .long .LEfde4-.LASfde4
234 .long .LASfde4-.Lframe1
242 .global VG_(trampoline_stuff_end)
243 VG_(trampoline_stuff_end):
245 /* and a trailing page of unexecutable code */
254 /*---------------- ppc32-linux ----------------*/
256 #if defined(VGP_ppc32_linux)
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
264 /* a leading page of unexecutable code */
267 .global VG_(trampoline_stuff_start)
268 VG_(trampoline_stuff_start):
270 .global VG_(ppc32_linux_SUBST_FOR_sigreturn)
271 VG_(ppc32_linux_SUBST_FOR_sigreturn):
274 .long 0 /*illegal insn*/
276 .global VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
277 VG_(ppc32_linux_SUBST_FOR_rt_sigreturn):
278 li 0,__NR_rt_sigreturn
280 .long 0 /*illegal insn*/
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.)
286 .global VG_(ppc32_linux_REDIR_FOR_strlen)
287 .type VG_(ppc32_linux_REDIR_FOR_strlen), @function
288 VG_(ppc32_linux_REDIR_FOR_strlen):
301 .size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
304 .global VG_(ppc32_linux_REDIR_FOR_strcmp)
305 .type VG_(ppc32_linux_REDIR_FOR_strcmp), @function
306 VG_(ppc32_linux_REDIR_FOR_strcmp):
339 .size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
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):
363 .size VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
365 .global VG_(trampoline_stuff_end)
366 VG_(trampoline_stuff_end):
368 /* and a trailing page of unexecutable code */
377 /*---------------- ppc64-linux ----------------*/
379 #if defined(VGP_ppc64_linux)
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
387 /* a leading page of unexecutable code */
390 .global VG_(trampoline_stuff_start)
391 VG_(trampoline_stuff_start):
393 .global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn)
394 VG_(ppc64_linux_SUBST_FOR_rt_sigreturn):
395 li 0,__NR_rt_sigreturn
397 .long 0 /*illegal insn*/
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):
404 /* this function is written using the "dotless" ABI convention */
406 .globl VG_(ppc64_linux_REDIR_FOR_strlen)
409 VG_(ppc64_linux_REDIR_FOR_strlen):
410 .quad .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
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
416 .L.VG_(ppc64_linux_REDIR_FOR_strlen):
431 .byte 0,0,0,0,0,0,0,0
434 /* this function is written using the "dotless" ABI convention */
436 .globl VG_(ppc64_linux_REDIR_FOR_strchr)
439 VG_(ppc64_linux_REDIR_FOR_strchr):
440 .quad .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
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
446 .L.VG_(ppc64_linux_REDIR_FOR_strchr):
466 .byte 0,0,0,0,0,0,0,0
470 .global VG_(trampoline_stuff_end)
471 VG_(trampoline_stuff_end):
473 /* and a trailing page of unexecutable code */
482 /*---------------- ppc32-linux ----------------*/
484 #elif defined(VGP_arm_linux)
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
493 /* a leading page of unexecutable code */
496 .global VG_(trampoline_stuff_start)
497 VG_(trampoline_stuff_start):
499 .global VG_(arm_linux_REDIR_FOR_strlen)
500 VG_(arm_linux_REDIR_FOR_strlen):
502 ldrb r0, [r0, #0] @ zero_extendqisi2
503 @ lr needed for prologue
509 ldrb r3, [r0, r2] @ zero_extendqisi2
515 //.global VG_(arm_linux_REDIR_FOR_index)
516 //VG_(arm_linux_REDIR_FOR_index):
517 // ldrb r3, [r0, #0] @ zero_extendqisi2
520 // @ lr needed for prologue
524 // ldrb r3, [r0, #1]! @ zero_extendqisi2
536 .global VG_(arm_linux_REDIR_FOR_memcpy)
537 VG_(arm_linux_REDIR_FOR_memcpy):
538 stmfd sp!, {r4, r5, lr}
553 ldrb r3, [r1, #4] @ zero_extendqisi2
556 ldrb r2, [r1, #3] @ zero_extendqisi2
559 ldrb r3, [r1, #2] @ zero_extendqisi2
562 ldrb r2, [r1, #1] @ zero_extendqisi2
574 ldrb r3, [r0], #-1 @ zero_extendqisi2
580 ldmfd sp!, {r4, r5, pc}
587 ldrb r3, [r1, #0] @ zero_extendqisi2
590 ldrb r2, [r1, #1] @ zero_extendqisi2
593 ldrb r3, [r1, #2] @ zero_extendqisi2
595 ldrb r2, [r1, #3] @ zero_extendqisi2
606 ldrb r3, [r1], #1 @ zero_extendqisi2
611 ldmfd sp!, {r4, r5, pc}
614 .global VG_(trampoline_stuff_end)
615 VG_(trampoline_stuff_end):
617 /* and a trailing page of unexecutable code */
627 /*---------------- ppc32-aix5 ----------------*/
629 #if defined(VGP_ppc32_aix5)
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
639 /* a leading page of unexecutable code */
642 .globl VG_(trampoline_stuff_start)
643 VG_(trampoline_stuff_start):
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):
654 stw 3,512(1) /* stash r3 512 bytes up stack */
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 */
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 */
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 */
694 /* Success. Restore r2-r10 from preloadpage-> and start
696 lwz 3,512(1) /* restore r3 */
698 lwz 2,32+4(3) /* preloadpage->client_start */
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 */
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 */
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 */
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 */
741 /* On entry: r2 = __NR___loadx, r6 = name of module */
743 slwi 3,3,24 /* r3 = 0x1000000 = VKI_DL_LOAD */
754 /* sc continues at 'lr', hence this
755 constitutes an automatic return */
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):
763 .globl VG_(trampoline_stuff_end)
764 VG_(trampoline_stuff_end):
766 /* and a trailing page of unexecutable code */
775 /*---------------- ppc64-aix5 ----------------*/
777 #if defined(VGP_ppc64_aix5)
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
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):
796 std 3,512(1) /* stash r3 512 bytes up stack */
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 */
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 */
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 */
830 /* Success. Restore r2-r10 from preloadpage-> and start
832 ld 3,512(1) /* restore r3 */
834 ld 2,32+0(3) /* preloadpage->client_start */
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 */
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 */
860 /* now call the diagnosis fn */
861 ld 3,512(1) /* restore r3 */
862 ld 4,112(3) /* preloadpage->p_diagnose_load_failure */
864 ld 2,8(4) /* get its TOC ptr */
865 ld 4,0(4) /* get its entry point */
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 */
878 /* On entry: r2 = __NR_kload, r3 = name of module */
889 /* sc continues at 'lr', hence this
890 constitutes an automatic return */
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):
897 .globl VG_(trampoline_stuff_end)
898 VG_(trampoline_stuff_end):
900 /* and a trailing page of unexecutable code */
909 /*---------------- x86-darwin ----------------*/
911 #if defined(VGP_x86_darwin)
913 /* a leading page of unexecutable code */
914 .fill 2048, 2, 0x0b0f /* `ud2` */
916 .globl VG_(trampoline_stuff_start)
917 VG_(trampoline_stuff_start):
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
923 movl $ __NR_DARWIN_FAKE_SIGRETURN, %eax
927 .globl VG_(darwin_REDIR_FOR_strlen)
928 VG_(darwin_REDIR_FOR_strlen):
940 .globl VG_(darwin_REDIR_FOR_strcat)
941 VG_(darwin_REDIR_FOR_strcat):
964 .globl VG_(darwin_REDIR_FOR_strcmp)
965 VG_(darwin_REDIR_FOR_strcmp):
985 .globl VG_(darwin_REDIR_FOR_strcpy)
986 VG_(darwin_REDIR_FOR_strcpy):
1007 .globl VG_(darwin_REDIR_FOR_strlcat)
1008 VG_(darwin_REDIR_FOR_strlcat):
1017 leal (%ecx,%esi), %eax
1037 call VG_(darwin_REDIR_FOR_strlen)
1055 leal (%edi,%eax), %eax
1062 .globl VG_(trampoline_stuff_end)
1063 VG_(trampoline_stuff_end):
1065 /* a trailing page of unexecutable code */
1066 .fill 2048, 2, 0x0b0f /* `ud2` */
1069 /*---------------- amd64-darwin ----------------*/
1071 #if defined(VGP_amd64_darwin)
1073 /* a leading page of unexecutable code */
1074 .fill 2048, 2, 0x0b0f /* `ud2` */
1076 .globl VG_(trampoline_stuff_start)
1077 VG_(trampoline_stuff_start):
1079 .globl VG_(darwin_REDIR_FOR_strlen)
1080 VG_(darwin_REDIR_FOR_strlen):
1091 .globl VG_(darwin_REDIR_FOR_strcat)
1092 VG_(darwin_REDIR_FOR_strcat):
1111 .globl VG_(darwin_REDIR_FOR_strcmp)
1112 VG_(darwin_REDIR_FOR_strcmp):
1129 .globl VG_(darwin_REDIR_FOR_strcpy)
1130 VG_(darwin_REDIR_FOR_strcpy):
1147 .globl VG_(darwin_REDIR_FOR_strlcat)
1148 VG_(darwin_REDIR_FOR_strlcat):
1150 leaq (%rdx,%rdi), %rax
1173 call VG_(darwin_REDIR_FOR_strlen)
1190 leaq (%rbx,%rax), %rax
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
1202 .globl VG_(trampoline_stuff_end)
1203 VG_(trampoline_stuff_end):
1205 /* a trailing page of unexecutable code */
1206 .fill 2048, 2, 0x0b0f /* `ud2` */
1208 /*---------------------- x86-l4re ----------------------*/
1210 #if defined(VGP_x86_l4re)
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
1218 /* a leading page of unexecutable code */
1221 .global VG_(trampoline_stuff_start)
1222 VG_(trampoline_stuff_start):
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 */
1232 /* movl $ __NR_sigreturn, %eax*/
1236 .global VG_(x86_l4re_SUBST_FOR_rt_sigreturn)
1237 VG_(x86_l4re_SUBST_FOR_rt_sigreturn):
1238 /* Likewise for rt signal frames */
1240 /* movl $ __NR_rt_sigreturn, %eax */
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.)
1248 unsigned char* REDIR_FOR_index ( const char* s, int c )
1250 unsigned char ch = (unsigned char)((unsigned int)c);
1251 unsigned char* p = (unsigned char*)s;
1253 if (*p == ch) return p;
1254 if (*p == 0) return 0;
1259 .global VG_(x86_l4re_REDIR_FOR_index)
1260 .type VG_(x86_l4re_REDIR_FOR_index), @function
1261 VG_(x86_l4re_REDIR_FOR_index):
1265 movzbl 12(%ebp), %ecx
1282 .size VG_(x86_l4re_REDIR_FOR_index), .-VG_(x86_l4re_REDIR_FOR_index)
1284 .global VG_(trampoline_stuff_end)
1285 VG_(trampoline_stuff_end):
1287 /* and a trailing page of unexecutable code */
1296 /*---------------- unknown ----------------*/
1298 # error Unknown platform
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
1315 .section .note.GNU-stack,"",@progbits
1319 /*--------------------------------------------------------------------*/
1321 /*--------------------------------------------------------------------*/