blob: e4930f9702364cae0a0c2028d2031ac049cffe7b [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
njn53612422005-03-12 16:22:54 +000010 Copyright (C) 2000-2005 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
sewardj45f4e7c2005-09-27 19:20:21 +000031#include "pub_core_basics_asm.h"
sewardjb5f6f512005-03-10 23:59:00 +000032#include "vki_unistd.h"
sewardjde4a1d02002-03-22 01:27:54 +000033
sewardj54cacf02002-04-12 23:24:59 +000034/* ------------------ SIMULATED CPU HELPERS ------------------ */
sewardjb9bce632005-06-21 01:41:34 +000035/*
36 Replacements for some functions to do with vsyscalls and signals.
37 This code runs on the simulated CPU.
sewardj54cacf02002-04-12 23:24:59 +000038*/
sewardja48a4932005-09-29 11:09:56 +000039
40/*---------------------- x86-linux ----------------------*/
41#if defined(VGP_x86_linux)
sewardjb9bce632005-06-21 01:41:34 +000042
sewardj45f4e7c2005-09-27 19:20:21 +000043# define UD2_16 ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
44# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
45# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
46# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
47# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
48
49 /* a leading page of unexecutable code */
50 UD2_PAGE
sewardjb9bce632005-06-21 01:41:34 +000051
52.global VG_(trampoline_stuff_start)
53VG_(trampoline_stuff_start):
54
55.global VG_(x86_linux_SUBST_FOR_sigreturn)
56VG_(x86_linux_SUBST_FOR_sigreturn):
sewardjb5f6f512005-03-10 23:59:00 +000057 /* This is a very specific sequence which GDB uses to
58 recognize signal handler frames. */
59 popl %eax
60 movl $__NR_sigreturn, %eax
61 int $0x80
62 ud2
63
sewardjb9bce632005-06-21 01:41:34 +000064.global VG_(x86_linux_SUBST_FOR_rt_sigreturn)
65VG_(x86_linux_SUBST_FOR_rt_sigreturn):
sewardjb5f6f512005-03-10 23:59:00 +000066 /* Likewise for rt signal frames */
67 movl $__NR_rt_sigreturn, %eax
68 int $0x80
69 ud2
fitzhardinge98abfc72003-12-16 02:05:15 +000070
sewardjb9bce632005-06-21 01:41:34 +000071.global VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80)
72VG_(x86_linux_REDIR_FOR__dl_sysinfo_int80):
73 /* We can point our sysinfo stuff here */
fitzhardinge92360792003-12-24 10:11:11 +000074 int $0x80
75 ret
sewardj6a443b22005-11-20 19:37:54 +000076
77/* There's no particular reason that this needs to be handwritten
78 assembly, but since that's what this file contains, here's a
79 simple index implementation (written in C and compiled by gcc.)
80
81 unsigned char* REDIR_FOR_index ( const char* s, int c )
82 {
83 unsigned char ch = (unsigned char)((unsigned int)c);
84 unsigned char* p = (unsigned char*)s;
85 unsigned char* last = 0;
86 while (1) {
87 if (*p == ch) last = p;
88 if (*p == 0) return last;
89 p++;
90 }
91 }
92*/
93.global VG_(x86_linux_REDIR_FOR_index)
94.type VG_(x86_linux_REDIR_FOR_index), @function
95VG_(x86_linux_REDIR_FOR_index):
96 pushl %ebp
97 movl %esp, %ebp
98 pushl %ebx
99 movb 12(%ebp), %al
100 movl 8(%ebp), %ecx
101 movl $0, %ebx
102.L2:
103 movb (%ecx), %dl
104 cmpb %dl, %al
105 jne .L3
106 movl %ecx, %ebx
107.L3:
108 testb %dl, %dl
109 je .L8
110 addl $1, %ecx
111 jmp .L2
112.L8:
113 movl %ebx, %eax
114 popl %ebx
115 popl %ebp
116 ret
117.size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index)
118
sewardjb9bce632005-06-21 01:41:34 +0000119.global VG_(trampoline_stuff_end)
120VG_(trampoline_stuff_end):
njna7598f62005-06-18 03:27:58 +0000121
sewardja48a4932005-09-29 11:09:56 +0000122 /* and a trailing page of unexecutable code */
123 UD2_PAGE
124
125# undef UD2_16
126# undef UD2_64
127# undef UD2_256
128# undef UD2_1024
129# undef UD2_PAGE
sewardjb9bce632005-06-21 01:41:34 +0000130
sewardja48a4932005-09-29 11:09:56 +0000131/*---------------------- amd64-linux ----------------------*/
sewardjb9bce632005-06-21 01:41:34 +0000132#else
133#if defined(VGP_amd64_linux)
njna7598f62005-06-18 03:27:58 +0000134
sewardja48a4932005-09-29 11:09:56 +0000135# define UD2_16 ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
136# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
137# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
138# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
139# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
140
141 /* a leading page of unexecutable code */
142 UD2_PAGE
143
sewardjb9bce632005-06-21 01:41:34 +0000144.global VG_(trampoline_stuff_start)
145VG_(trampoline_stuff_start):
146
147.global VG_(amd64_linux_SUBST_FOR_rt_sigreturn)
148VG_(amd64_linux_SUBST_FOR_rt_sigreturn):
149 /* This is a very specific sequence which GDB uses to
150 recognize signal handler frames. */
njna7598f62005-06-18 03:27:58 +0000151 movq $__NR_rt_sigreturn, %rax
152 syscall
153 ud2
154
sewardjb9bce632005-06-21 01:41:34 +0000155.global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
156VG_(amd64_linux_REDIR_FOR_vgettimeofday):
njna7598f62005-06-18 03:27:58 +0000157 movq $__NR_gettimeofday, %rax
158 syscall
159 ret
160
sewardjb9bce632005-06-21 01:41:34 +0000161.global VG_(amd64_linux_REDIR_FOR_vtime)
162VG_(amd64_linux_REDIR_FOR_vtime):
njna7598f62005-06-18 03:27:58 +0000163 movq $__NR_time, %rax
164 syscall
165 ret
166
sewardjb9bce632005-06-21 01:41:34 +0000167.global VG_(trampoline_stuff_end)
168VG_(trampoline_stuff_end):
njna7598f62005-06-18 03:27:58 +0000169
sewardja48a4932005-09-29 11:09:56 +0000170 /* and a trailing page of unexecutable code */
171 UD2_PAGE
172
173# undef UD2_16
174# undef UD2_64
175# undef UD2_256
176# undef UD2_1024
177# undef UD2_PAGE
sewardjb9bce632005-06-21 01:41:34 +0000178
sewardj05b5fc12005-06-21 09:56:56 +0000179/*---------------- ppc32-linux ----------------*/
sewardjb9bce632005-06-21 01:41:34 +0000180#else
181#if defined(VGP_ppc32_linux)
182
sewardja48a4932005-09-29 11:09:56 +0000183# define UD2_16 trap ; trap ; trap; trap
184# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
185# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
186# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
187# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
188
189 /* a leading page of unexecutable code */
190 UD2_PAGE
191
sewardj05b5fc12005-06-21 09:56:56 +0000192.global VG_(trampoline_stuff_start)
193VG_(trampoline_stuff_start):
cerion85665ca2005-06-20 15:51:07 +0000194
sewardjad50be32005-08-18 11:54:30 +0000195/* There's no particular reason that this needs to be handwritten
196 assembly, but since that's what this file contains, here's a
197 simple strlen implementation (written in C and compiled by gcc.)
198*/
199.global VG_(ppc32_linux_REDIR_FOR_strlen)
sewardj0b6941e2005-10-12 10:00:56 +0000200.type VG_(ppc32_linux_REDIR_FOR_strlen), @function
sewardjad50be32005-08-18 11:54:30 +0000201VG_(ppc32_linux_REDIR_FOR_strlen):
202 lbz 4,0(3)
203 li 9,0
204 cmpwi 0,4,0
sewardj5e7b2302005-10-01 19:12:08 +0000205 beq- 0,.L18
206.L19:
sewardjad50be32005-08-18 11:54:30 +0000207 lbzu 5,1(3)
208 addi 9,9,1
209 cmpwi 0,5,0
sewardj5e7b2302005-10-01 19:12:08 +0000210 bne+ 0,.L19
211.L18:
sewardjad50be32005-08-18 11:54:30 +0000212 mr 3,9
213 blr
sewardj0b6941e2005-10-12 10:00:56 +0000214.size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
sewardjad50be32005-08-18 11:54:30 +0000215
sewardj5e7b2302005-10-01 19:12:08 +0000216/* Ditto strcmp */
217.global VG_(ppc32_linux_REDIR_FOR_strcmp)
sewardj0b6941e2005-10-12 10:00:56 +0000218.type VG_(ppc32_linux_REDIR_FOR_strcmp), @function
sewardj5e7b2302005-10-01 19:12:08 +0000219VG_(ppc32_linux_REDIR_FOR_strcmp):
220.L20:
221 lbz 0,0(3)
222 cmpwi 7,0,0
223 bne- 7,.L21
224 lbz 0,0(4)
225 li 11,0
226 cmpwi 7,0,0
227 beq- 7,.L22
228.L21:
229 lbz 0,0(3)
230 li 11,-1
231 cmpwi 7,0,0
232 beq- 7,.L22
233 lbz 0,0(4)
234 li 11,1
235 cmpwi 7,0,0
236 beq- 7,.L22
237 lbz 9,0(3)
238 lbz 0,0(4)
239 li 11,-1
240 cmplw 7,9,0
241 blt- 7,.L22
242 lbz 9,0(3)
243 lbz 0,0(4)
244 li 11,1
245 addi 3,3,1
246 addi 4,4,1
247 cmplw 7,9,0
248 ble+ 7,.L20
249.L22:
250 mr 3,11
251 blr
sewardj0b6941e2005-10-12 10:00:56 +0000252.size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
sewardj5e7b2302005-10-01 19:12:08 +0000253
sewardj31d83422005-10-15 02:00:41 +0000254/* Ditto index/strchr */
255.global VG_(ppc32_linux_REDIR_FOR_strchr)
256.type VG_(ppc32_linux_REDIR_FOR_strchr), @function
257VG_(ppc32_linux_REDIR_FOR_strchr):
258 lbz 0,0(3)
259 cmpw 7,4,0
260 beqlr 7
261 cmpwi 7,0,0
262 beq 7,.L307
263 .p2align 4,,15
264.L310:
265 lbzu 0,1(3)
266 cmpw 7,0,4
267 cmpwi 6,0,0
268 beq 7,.L313
269 bne 6,.L310
270.L307:
271 li 3,0
272 blr
273.L313:
274 blr
275.size VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
276
sewardj05b5fc12005-06-21 09:56:56 +0000277.global VG_(trampoline_stuff_end)
278VG_(trampoline_stuff_end):
279
sewardja48a4932005-09-29 11:09:56 +0000280# undef UD2_16
281# undef UD2_64
282# undef UD2_256
283# undef UD2_1024
284# undef UD2_PAGE
sewardj05b5fc12005-06-21 09:56:56 +0000285
sewardj05b5fc12005-06-21 09:56:56 +0000286/*---------------- unknown ----------------*/
njna7598f62005-06-18 03:27:58 +0000287#else
sewardjb9bce632005-06-21 01:41:34 +0000288# error Unknown platform
289
njna7598f62005-06-18 03:27:58 +0000290#endif
sewardjb9bce632005-06-21 01:41:34 +0000291#endif
292#endif
293
sewardjde4a1d02002-03-22 01:27:54 +0000294
thughes4ad52d02004-06-27 17:37:21 +0000295/* Let the linker know we don't need an executable stack */
296.section .note.GNU-stack,"",@progbits
297
sewardjb9bce632005-06-21 01:41:34 +0000298/*--------------------------------------------------------------------*/
299/*--- end ---*/
300/*--------------------------------------------------------------------*/