blob: 3d2be09ba762c61d060f836a8b53904bda487e1f [file] [log] [blame]
njna7598f62005-06-18 03:27:58 +00001
sewardjb9bce632005-06-21 01:41:34 +00002/*--------------------------------------------------------------------*/
3/*--- Trampoline code page stuff. m_trampoline.S ---*/
4/*--------------------------------------------------------------------*/
sewardjde4a1d02002-03-22 01:27:54 +00005
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardj0f157dd2013-10-18 14:27:36 +000012 Copyright (C) 2006-2013 OpenWorks LLP
sewardj13552642006-11-10 22:47:27 +000013 info@open-works.co.uk
14
sewardjde4a1d02002-03-22 01:27:54 +000015 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
njn25e49d8e72002-09-23 09:36:25 +000030 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000031*/
32
sewardj45f4e7c2005-09-27 19:20:21 +000033#include "pub_core_basics_asm.h"
njn1a1e95c2009-06-03 06:50:06 +000034#include "pub_core_vkiscnums_asm.h"
sewardjde4a1d02002-03-22 01:27:54 +000035
sewardj54cacf02002-04-12 23:24:59 +000036/* ------------------ SIMULATED CPU HELPERS ------------------ */
sewardjb9bce632005-06-21 01:41:34 +000037/*
38 Replacements for some functions to do with vsyscalls and signals.
39 This code runs on the simulated CPU.
sewardj54cacf02002-04-12 23:24:59 +000040*/
sewardja48a4932005-09-29 11:09:56 +000041
42/*---------------------- x86-linux ----------------------*/
43#if defined(VGP_x86_linux)
sewardjb9bce632005-06-21 01:41:34 +000044
sewardj45f4e7c2005-09-27 19:20:21 +000045# 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
sewardjb9bce632005-06-21 01:41:34 +000053
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):
sewardjb5f6f512005-03-10 23:59:00 +000059 /* This is a very specific sequence which GDB uses to
sewardja672ea32006-04-29 18:03:14 +000060 recognize signal handler frames. Also gcc: see
61 x86_fallback_frame_state() in
62 gcc-4.1.0/gcc/config/i386/linux-unwind.h */
sewardjb5f6f512005-03-10 23:59:00 +000063 popl %eax
sewardjcfdc5fd2007-08-24 20:37:09 +000064 movl $ __NR_sigreturn, %eax
sewardjb5f6f512005-03-10 23:59:00 +000065 int $0x80
66 ud2
67
sewardjb9bce632005-06-21 01:41:34 +000068.global VG_(x86_linux_SUBST_FOR_rt_sigreturn)
69VG_(x86_linux_SUBST_FOR_rt_sigreturn):
sewardjb5f6f512005-03-10 23:59:00 +000070 /* Likewise for rt signal frames */
sewardjcfdc5fd2007-08-24 20:37:09 +000071 movl $ __NR_rt_sigreturn, %eax
sewardjb5f6f512005-03-10 23:59:00 +000072 int $0x80
73 ud2
fitzhardinge98abfc72003-12-16 02:05:15 +000074
sewardj6a443b22005-11-20 19:37:54 +000075/* 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 {
sewardjd1dea992007-08-27 10:46:39 +000081 unsigned char ch = (unsigned char)((unsigned int)c);
82 unsigned char* p = (unsigned char*)s;
sewardj6a443b22005-11-20 19:37:54 +000083 while (1) {
sewardjd1dea992007-08-27 10:46:39 +000084 if (*p == ch) return p;
85 if (*p == 0) return 0;
sewardj6a443b22005-11-20 19:37:54 +000086 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
sewardjd1dea992007-08-27 10:46:39 +000095 movl 8(%ebp), %eax
96 movzbl 12(%ebp), %ecx
97 movzbl (%eax), %edx
98 cmpb %dl, %cl
99 jne .L9
sewardj6a443b22005-11-20 19:37:54 +0000100 jmp .L2
sewardjd1dea992007-08-27 10:46:39 +0000101.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:
sewardj6a443b22005-11-20 19:37:54 +0000111 popl %ebp
112 ret
113.size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index)
114
sewardjd28cc962011-03-28 08:22:55 +0000115/* 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
sewardjb9bce632005-06-21 01:41:34 +0000136.global VG_(trampoline_stuff_end)
137VG_(trampoline_stuff_end):
njna7598f62005-06-18 03:27:58 +0000138
sewardja48a4932005-09-29 11:09:56 +0000139 /* 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
sewardjb9bce632005-06-21 01:41:34 +0000147
sewardja48a4932005-09-29 11:09:56 +0000148/*---------------------- amd64-linux ----------------------*/
sewardjb9bce632005-06-21 01:41:34 +0000149#else
150#if defined(VGP_amd64_linux)
njna7598f62005-06-18 03:27:58 +0000151
sewardja48a4932005-09-29 11:09:56 +0000152# 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
sewardjb9bce632005-06-21 01:41:34 +0000161.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. */
njna7598f62005-06-18 03:27:58 +0000168 movq $__NR_rt_sigreturn, %rax
169 syscall
170 ud2
171
sewardjb9bce632005-06-21 01:41:34 +0000172.global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
sewardj542eada2007-02-27 18:37:21 +0000173.type VG_(amd64_linux_REDIR_FOR_vgettimeofday), @function
sewardjb9bce632005-06-21 01:41:34 +0000174VG_(amd64_linux_REDIR_FOR_vgettimeofday):
sewardj542eada2007-02-27 18:37:21 +0000175.LfnB2:
njna7598f62005-06-18 03:27:58 +0000176 movq $__NR_gettimeofday, %rax
177 syscall
178 ret
sewardj542eada2007-02-27 18:37:21 +0000179.LfnE2:
sewardj1944c912008-10-26 11:06:44 +0000180.size VG_(amd64_linux_REDIR_FOR_vgettimeofday), .-.LfnB2
sewardj542eada2007-02-27 18:37:21 +0000181
sewardjb9bce632005-06-21 01:41:34 +0000182.global VG_(amd64_linux_REDIR_FOR_vtime)
sewardj542eada2007-02-27 18:37:21 +0000183.type VG_(amd64_linux_REDIR_FOR_vtime), @function
sewardjb9bce632005-06-21 01:41:34 +0000184VG_(amd64_linux_REDIR_FOR_vtime):
sewardj542eada2007-02-27 18:37:21 +0000185.LfnB3:
njna7598f62005-06-18 03:27:58 +0000186 movq $__NR_time, %rax
187 syscall
188 ret
sewardj542eada2007-02-27 18:37:21 +0000189.LfnE3:
sewardj1944c912008-10-26 11:06:44 +0000190.size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
sewardj542eada2007-02-27 18:37:21 +0000191
tomd6ae9e62012-02-09 11:54:16 +0000192.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
sewardjb57e6932009-08-02 12:21:31 +0000202/* 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):
tomd6ae9e62012-02-09 11:54:16 +0000209.LfnB5:
sewardjb57e6932009-08-02 12:21:31 +0000210 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
tomd6ae9e62012-02-09 11:54:16 +0000220.LfnE5:
sewardjb57e6932009-08-02 12:21:31 +0000221.size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
222
223
tomd6ae9e62012-02-09 11:54:16 +0000224/* A CIE for the above four functions, followed by their FDEs */
sewardj542eada2007-02-27 18:37:21 +0000225 .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:
sewardjb57e6932009-08-02 12:21:31 +0000262.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:
tomd6ae9e62012-02-09 11:54:16 +0000271.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:
sewardj542eada2007-02-27 18:37:21 +0000280 .previous
njna7598f62005-06-18 03:27:58 +0000281
sewardjb9bce632005-06-21 01:41:34 +0000282.global VG_(trampoline_stuff_end)
283VG_(trampoline_stuff_end):
njna7598f62005-06-18 03:27:58 +0000284
sewardja48a4932005-09-29 11:09:56 +0000285 /* 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
sewardjb9bce632005-06-21 01:41:34 +0000293
sewardj05b5fc12005-06-21 09:56:56 +0000294/*---------------- ppc32-linux ----------------*/
sewardjb9bce632005-06-21 01:41:34 +0000295#else
296#if defined(VGP_ppc32_linux)
297
sewardja48a4932005-09-29 11:09:56 +0000298# 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
sewardj05b5fc12005-06-21 09:56:56 +0000307.global VG_(trampoline_stuff_start)
308VG_(trampoline_stuff_start):
cerion85665ca2005-06-20 15:51:07 +0000309
sewardja5940262007-09-10 16:28:38 +0000310.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
sewardjad50be32005-08-18 11:54:30 +0000322/* 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)
sewardj0b6941e2005-10-12 10:00:56 +0000327.type VG_(ppc32_linux_REDIR_FOR_strlen), @function
sewardjad50be32005-08-18 11:54:30 +0000328VG_(ppc32_linux_REDIR_FOR_strlen):
329 lbz 4,0(3)
330 li 9,0
331 cmpwi 0,4,0
sewardj5e7b2302005-10-01 19:12:08 +0000332 beq- 0,.L18
333.L19:
sewardjad50be32005-08-18 11:54:30 +0000334 lbzu 5,1(3)
335 addi 9,9,1
336 cmpwi 0,5,0
sewardj5e7b2302005-10-01 19:12:08 +0000337 bne+ 0,.L19
338.L18:
sewardjad50be32005-08-18 11:54:30 +0000339 mr 3,9
340 blr
sewardj0b6941e2005-10-12 10:00:56 +0000341.size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
sewardjad50be32005-08-18 11:54:30 +0000342
sewardj5e7b2302005-10-01 19:12:08 +0000343/* Ditto strcmp */
344.global VG_(ppc32_linux_REDIR_FOR_strcmp)
sewardj0b6941e2005-10-12 10:00:56 +0000345.type VG_(ppc32_linux_REDIR_FOR_strcmp), @function
sewardj5e7b2302005-10-01 19:12:08 +0000346VG_(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
sewardj0b6941e2005-10-12 10:00:56 +0000379.size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
sewardj5e7b2302005-10-01 19:12:08 +0000380
sewardj31d83422005-10-15 02:00:41 +0000381/* 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)
sewardj23c97b62007-08-27 11:50:39 +0000386 rlwinm 4,4,0,0xff
sewardj31d83422005-10-15 02:00:41 +0000387 cmpw 7,4,0
388 beqlr 7
389 cmpwi 7,0,0
sewardj23c97b62007-08-27 11:50:39 +0000390 bne 7,.L308
391 b .L304
392.L309:
393 beq 6,.L304
394.L308:
sewardj31d83422005-10-15 02:00:41 +0000395 lbzu 0,1(3)
sewardj23c97b62007-08-27 11:50:39 +0000396 cmpw 7,4,0
sewardj31d83422005-10-15 02:00:41 +0000397 cmpwi 6,0,0
sewardj23c97b62007-08-27 11:50:39 +0000398 bne 7,.L309
sewardj31d83422005-10-15 02:00:41 +0000399 blr
sewardj23c97b62007-08-27 11:50:39 +0000400.L304:
401 li 3,0
sewardj31d83422005-10-15 02:00:41 +0000402 blr
403.size VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
404
sewardj05b5fc12005-06-21 09:56:56 +0000405.global VG_(trampoline_stuff_end)
406VG_(trampoline_stuff_end):
407
sewardjf0915fc2006-01-05 14:07:04 +0000408 /* and a trailing page of unexecutable code */
409 UD2_PAGE
410
sewardja48a4932005-09-29 11:09:56 +0000411# undef UD2_16
412# undef UD2_64
413# undef UD2_256
414# undef UD2_1024
415# undef UD2_PAGE
sewardj05b5fc12005-06-21 09:56:56 +0000416
sewardj2c48c7b2005-11-29 13:05:56 +0000417/*---------------- ppc64-linux ----------------*/
418#else
carllcae0cc22014-08-07 23:17:29 +0000419#if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
sewardj2c48c7b2005-11-29 13:05:56 +0000420
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):
sewardjf0915fc2006-01-05 14:07:04 +0000432
sewardj53092c62007-09-10 16:52:09 +0000433.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
sewardj658f05a2006-01-17 02:21:09 +0000439 /* See comment in pub_core_trampoline.h for what this is for */
sewardjf832bb92006-10-17 01:54:54 +0000440.global VG_(ppctoc_magic_redirect_return_stub)
441VG_(ppctoc_magic_redirect_return_stub):
sewardj658f05a2006-01-17 02:21:09 +0000442 trap
443
sewardj1a85f4f2006-01-12 21:15:35 +0000444 /* this function is written using the "dotless" ABI convention */
445 .align 2
446 .globl VG_(ppc64_linux_REDIR_FOR_strlen)
carll582d5822014-08-07 23:35:54 +0000447#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 */
sewardj1a85f4f2006-01-12 21:15:35 +0000453 .section ".opd","aw"
454 .align 3
sewardjf0915fc2006-01-05 14:07:04 +0000455VG_(ppc64_linux_REDIR_FOR_strlen):
sewardj1a85f4f2006-01-12 21:15:35 +0000456 .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
sewardjf0915fc2006-01-05 14:07:04 +0000462.L.VG_(ppc64_linux_REDIR_FOR_strlen):
carll582d5822014-08-07 23:35:54 +0000463#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
sewardjf0915fc2006-01-05 14:07:04 +0000469 mr 9,3
470 lbz 0,0(3)
471 li 3,0
472 cmpwi 7,0,0
473 beqlr 7
474 li 3,0
sewardj1a85f4f2006-01-12 21:15:35 +0000475.L01:
sewardjf0915fc2006-01-05 14:07:04 +0000476 addi 0,3,1
477 extsw 3,0
478 lbzx 0,9,3
479 cmpwi 7,0,0
sewardj1a85f4f2006-01-12 21:15:35 +0000480 bne 7,.L01
sewardjf0915fc2006-01-05 14:07:04 +0000481 blr
carll582d5822014-08-07 23:35:54 +0000482
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
sewardjf0915fc2006-01-05 14:07:04 +0000488 .long 0
489 .byte 0,0,0,0,0,0,0,0
sewardj1a85f4f2006-01-12 21:15:35 +0000490.L0end:
cerion297c88f2005-12-22 15:53:12 +0000491
sewardj1a85f4f2006-01-12 21:15:35 +0000492 /* this function is written using the "dotless" ABI convention */
493 .align 2
494 .globl VG_(ppc64_linux_REDIR_FOR_strchr)
carll582d5822014-08-07 23:35:54 +0000495#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
sewardj1a85f4f2006-01-12 21:15:35 +0000499 .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
carll582d5822014-08-07 23:35:54 +0000507
sewardj1a85f4f2006-01-12 21:15:35 +0000508.L.VG_(ppc64_linux_REDIR_FOR_strchr):
carll582d5822014-08-07 23:35:54 +0000509#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
sewardj23c97b62007-08-27 11:50:39 +0000515 lbz 0,0(3)
sewardj1a85f4f2006-01-12 21:15:35 +0000516 rldicl 4,4,0,56
sewardj23c97b62007-08-27 11:50:39 +0000517 cmpw 7,4,0
518 beqlr 7
519 cmpdi 7,0,0
520 bne 7,.L18
521 b .L14
carll582d5822014-08-07 23:35:54 +0000522#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
sewardj23c97b62007-08-27 11:50:39 +0000527.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
sewardj1a85f4f2006-01-12 21:15:35 +0000537 blr
538 .long 0
539 .byte 0,0,0,0,0,0,0,0
540.L1end:
541
542
sewardj2c48c7b2005-11-29 13:05:56 +0000543.global VG_(trampoline_stuff_end)
544VG_(trampoline_stuff_end):
545
sewardjf0915fc2006-01-05 14:07:04 +0000546 /* and a trailing page of unexecutable code */
547 UD2_PAGE
548
sewardj2c48c7b2005-11-29 13:05:56 +0000549# undef UD2_16
550# undef UD2_64
551# undef UD2_256
552# undef UD2_1024
553# undef UD2_PAGE
554
sewardjf0c12502014-01-12 12:54:00 +0000555/*---------------- arm-linux ----------------*/
556#else
557#if defined(VGP_arm_linux)
sewardj59570ff2010-01-01 11:59:33 +0000558
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
sewardjbc33be62011-11-20 09:35:51 +0000572.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
sewardj59570ff2010-01-01 11:59:33 +0000588.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
mjw1cd23782014-08-28 14:59:04 +0000703.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
sewardj59570ff2010-01-01 11:59:33 +0000719.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
sewardjf0c12502014-01-12 12:54:00 +0000732/*---------------- 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
sewardj7aa66512014-03-09 09:44:32 +0000758.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
sewardjf0c12502014-01-12 12:54:00 +0000819.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
njnf76d27a2009-05-28 01:53:07 +0000832/*---------------- 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
njnea2d6fd2010-07-01 00:20:20 +0000850.globl VG_(x86_darwin_REDIR_FOR_strlen)
851VG_(x86_darwin_REDIR_FOR_strlen):
njnf76d27a2009-05-28 01:53:07 +0000852 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
njnea2d6fd2010-07-01 00:20:20 +0000863.globl VG_(x86_darwin_REDIR_FOR_strcat)
864VG_(x86_darwin_REDIR_FOR_strcat):
njnf76d27a2009-05-28 01:53:07 +0000865 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
njnea2d6fd2010-07-01 00:20:20 +0000887.globl VG_(x86_darwin_REDIR_FOR_strcmp)
888VG_(x86_darwin_REDIR_FOR_strcmp):
njnf76d27a2009-05-28 01:53:07 +0000889 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
njnea2d6fd2010-07-01 00:20:20 +0000908.globl VG_(x86_darwin_REDIR_FOR_strcpy)
909VG_(x86_darwin_REDIR_FOR_strcpy):
njnf76d27a2009-05-28 01:53:07 +0000910 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
njnea2d6fd2010-07-01 00:20:20 +0000930.globl VG_(x86_darwin_REDIR_FOR_strlcat)
931VG_(x86_darwin_REDIR_FOR_strlcat):
njnf76d27a2009-05-28 01:53:07 +0000932 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)
njnea2d6fd2010-07-01 00:20:20 +0000960 call VG_(x86_darwin_REDIR_FOR_strlen)
njnf76d27a2009-05-28 01:53:07 +0000961 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
sewardjf832bb92006-10-17 01:54:54 +0000983
njnf76d27a2009-05-28 01:53:07 +0000984
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
njnea2d6fd2010-07-01 00:20:20 +00001002.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):
njnf76d27a2009-05-28 01:53:07 +00001012 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
njnea2d6fd2010-07-01 00:20:20 +00001022.globl VG_(amd64_darwin_REDIR_FOR_strcat)
1023VG_(amd64_darwin_REDIR_FOR_strcat):
njnf76d27a2009-05-28 01:53:07 +00001024 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
njnea2d6fd2010-07-01 00:20:20 +00001042.globl VG_(amd64_darwin_REDIR_FOR_strcmp)
1043VG_(amd64_darwin_REDIR_FOR_strcmp):
njnf76d27a2009-05-28 01:53:07 +00001044 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
njnea2d6fd2010-07-01 00:20:20 +00001060.globl VG_(amd64_darwin_REDIR_FOR_strcpy)
1061VG_(amd64_darwin_REDIR_FOR_strcpy):
njnf76d27a2009-05-28 01:53:07 +00001062 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
njnea2d6fd2010-07-01 00:20:20 +00001078.globl VG_(amd64_darwin_REDIR_FOR_strlcat)
1079VG_(amd64_darwin_REDIR_FOR_strlcat):
njnf76d27a2009-05-28 01:53:07 +00001080 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
njnea2d6fd2010-07-01 00:20:20 +00001104 call VG_(amd64_darwin_REDIR_FOR_strlen)
njnf76d27a2009-05-28 01:53:07 +00001105 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
njnea2d6fd2010-07-01 00:20:20 +00001127.globl VG_(amd64_darwin_REDIR_FOR_arc4random)
1128VG_(amd64_darwin_REDIR_FOR_arc4random):
njnf76d27a2009-05-28 01:53:07 +00001129 /* not very random, hope dyld won't mind */
1130 movq $0x76616c6772696e64, %rax
1131 ret
1132
sewardj704bf0e2014-06-21 09:34:22 +00001133.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
njnf76d27a2009-05-28 01:53:07 +00001156.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
sewardjb5b87402011-03-07 16:05:35 +00001163/*---------------- 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
florianae6e3ac2014-09-03 16:01:10 +00001192.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
sewardjb5b87402011-03-07 16:05:35 +00001214.globl VG_(trampoline_stuff_end)
1215VG_(trampoline_stuff_end):
1216 .fill 2048, 2, 0x0000
1217
sewardj5db15402012-06-07 09:13:21 +00001218/*---------------------- 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
petarj4df0bfc2013-02-27 23:17:33 +00001276/*---------------------- 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
sewardj05b5fc12005-06-21 09:56:56 +00001332/*---------------- unknown ----------------*/
njna7598f62005-06-18 03:27:58 +00001333#else
sewardjb9bce632005-06-21 01:41:34 +00001334# error Unknown platform
1335
njna7598f62005-06-18 03:27:58 +00001336#endif
sewardjb9bce632005-06-21 01:41:34 +00001337#endif
1338#endif
sewardj2c48c7b2005-11-29 13:05:56 +00001339#endif
sewardjf832bb92006-10-17 01:54:54 +00001340#endif
1341#endif
njnf76d27a2009-05-28 01:53:07 +00001342#endif
sewardj5db15402012-06-07 09:13:21 +00001343#endif
petarj4df0bfc2013-02-27 23:17:33 +00001344#endif
sewardjf0c12502014-01-12 12:54:00 +00001345#endif
1346#endif
sewardjb9bce632005-06-21 01:41:34 +00001347
sewardjf832bb92006-10-17 01:54:54 +00001348#if defined(VGO_linux)
thughes4ad52d02004-06-27 17:37:21 +00001349/* Let the linker know we don't need an executable stack */
sewardj59570ff2010-01-01 11:59:33 +00001350# if defined(VGP_arm_linux)
1351 .section .note.GNU-stack,"",%progbits
1352# else
1353 .section .note.GNU-stack,"",@progbits
1354# endif
sewardjf832bb92006-10-17 01:54:54 +00001355#endif
1356
sewardjb9bce632005-06-21 01:41:34 +00001357/*--------------------------------------------------------------------*/
1358/*--- end ---*/
1359/*--------------------------------------------------------------------*/