blob: 7b6f7a3abe7986c4e970d4e3b7379ca6594c5da0 [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
sewardj9ebd6e02007-01-08 06:01:59 +000010 Copyright (C) 2000-2007 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardj9ebd6e02007-01-08 06:01:59 +000012 Copyright (C) 2006-2007 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"
sewardjf832bb92006-10-17 01:54:54 +000034
35/* We need pub_core_vkiscnums.h, but the AIX5 formulation
36 brings in a load of C declarations. Defining this macro
37 makes them invisible. Yes, a nasty hack. */
38#define VG_IN_ASSEMBLY_SOURCE
39# include "pub_core_vkiscnums.h"
40#undef VG_IN_ASSEMBLY_SOURCE
sewardjde4a1d02002-03-22 01:27:54 +000041
sewardj54cacf02002-04-12 23:24:59 +000042/* ------------------ SIMULATED CPU HELPERS ------------------ */
sewardjb9bce632005-06-21 01:41:34 +000043/*
44 Replacements for some functions to do with vsyscalls and signals.
45 This code runs on the simulated CPU.
sewardj54cacf02002-04-12 23:24:59 +000046*/
sewardja48a4932005-09-29 11:09:56 +000047
48/*---------------------- x86-linux ----------------------*/
49#if defined(VGP_x86_linux)
sewardjb9bce632005-06-21 01:41:34 +000050
sewardj45f4e7c2005-09-27 19:20:21 +000051# define UD2_16 ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
52# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
53# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
54# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
55# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
56
57 /* a leading page of unexecutable code */
58 UD2_PAGE
sewardjb9bce632005-06-21 01:41:34 +000059
60.global VG_(trampoline_stuff_start)
61VG_(trampoline_stuff_start):
62
63.global VG_(x86_linux_SUBST_FOR_sigreturn)
64VG_(x86_linux_SUBST_FOR_sigreturn):
sewardjb5f6f512005-03-10 23:59:00 +000065 /* This is a very specific sequence which GDB uses to
sewardja672ea32006-04-29 18:03:14 +000066 recognize signal handler frames. Also gcc: see
67 x86_fallback_frame_state() in
68 gcc-4.1.0/gcc/config/i386/linux-unwind.h */
sewardjb5f6f512005-03-10 23:59:00 +000069 popl %eax
sewardjcfdc5fd2007-08-24 20:37:09 +000070 movl $ __NR_sigreturn, %eax
sewardjb5f6f512005-03-10 23:59:00 +000071 int $0x80
72 ud2
73
sewardjb9bce632005-06-21 01:41:34 +000074.global VG_(x86_linux_SUBST_FOR_rt_sigreturn)
75VG_(x86_linux_SUBST_FOR_rt_sigreturn):
sewardjb5f6f512005-03-10 23:59:00 +000076 /* Likewise for rt signal frames */
sewardjcfdc5fd2007-08-24 20:37:09 +000077 movl $ __NR_rt_sigreturn, %eax
sewardjb5f6f512005-03-10 23:59:00 +000078 int $0x80
79 ud2
fitzhardinge98abfc72003-12-16 02:05:15 +000080
sewardj6a443b22005-11-20 19:37:54 +000081/* There's no particular reason that this needs to be handwritten
82 assembly, but since that's what this file contains, here's a
83 simple index implementation (written in C and compiled by gcc.)
84
85 unsigned char* REDIR_FOR_index ( const char* s, int c )
86 {
sewardjd1dea992007-08-27 10:46:39 +000087 unsigned char ch = (unsigned char)((unsigned int)c);
88 unsigned char* p = (unsigned char*)s;
sewardj6a443b22005-11-20 19:37:54 +000089 while (1) {
sewardjd1dea992007-08-27 10:46:39 +000090 if (*p == ch) return p;
91 if (*p == 0) return 0;
sewardj6a443b22005-11-20 19:37:54 +000092 p++;
93 }
94 }
95*/
96.global VG_(x86_linux_REDIR_FOR_index)
97.type VG_(x86_linux_REDIR_FOR_index), @function
98VG_(x86_linux_REDIR_FOR_index):
99 pushl %ebp
100 movl %esp, %ebp
sewardjd1dea992007-08-27 10:46:39 +0000101 movl 8(%ebp), %eax
102 movzbl 12(%ebp), %ecx
103 movzbl (%eax), %edx
104 cmpb %dl, %cl
105 jne .L9
sewardj6a443b22005-11-20 19:37:54 +0000106 jmp .L2
sewardjd1dea992007-08-27 10:46:39 +0000107.L11:
108 addl $1, %eax
109 movzbl (%eax), %edx
110 cmpb %dl, %cl
111 je .L2
112.L9:
113 testb %dl, %dl
114 jne .L11
115 xorl %eax, %eax
116.L2:
sewardj6a443b22005-11-20 19:37:54 +0000117 popl %ebp
118 ret
119.size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index)
120
sewardjb9bce632005-06-21 01:41:34 +0000121.global VG_(trampoline_stuff_end)
122VG_(trampoline_stuff_end):
njna7598f62005-06-18 03:27:58 +0000123
sewardja48a4932005-09-29 11:09:56 +0000124 /* and a trailing page of unexecutable code */
125 UD2_PAGE
126
127# undef UD2_16
128# undef UD2_64
129# undef UD2_256
130# undef UD2_1024
131# undef UD2_PAGE
sewardjb9bce632005-06-21 01:41:34 +0000132
sewardja48a4932005-09-29 11:09:56 +0000133/*---------------------- amd64-linux ----------------------*/
sewardjb9bce632005-06-21 01:41:34 +0000134#else
135#if defined(VGP_amd64_linux)
njna7598f62005-06-18 03:27:58 +0000136
sewardja48a4932005-09-29 11:09:56 +0000137# define UD2_16 ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
138# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
139# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
140# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
141# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
142
143 /* a leading page of unexecutable code */
144 UD2_PAGE
145
sewardjb9bce632005-06-21 01:41:34 +0000146.global VG_(trampoline_stuff_start)
147VG_(trampoline_stuff_start):
148
149.global VG_(amd64_linux_SUBST_FOR_rt_sigreturn)
150VG_(amd64_linux_SUBST_FOR_rt_sigreturn):
151 /* This is a very specific sequence which GDB uses to
152 recognize signal handler frames. */
njna7598f62005-06-18 03:27:58 +0000153 movq $__NR_rt_sigreturn, %rax
154 syscall
155 ud2
156
sewardjb9bce632005-06-21 01:41:34 +0000157.global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
sewardj542eada2007-02-27 18:37:21 +0000158.type VG_(amd64_linux_REDIR_FOR_vgettimeofday), @function
sewardjb9bce632005-06-21 01:41:34 +0000159VG_(amd64_linux_REDIR_FOR_vgettimeofday):
sewardj542eada2007-02-27 18:37:21 +0000160.LfnB2:
njna7598f62005-06-18 03:27:58 +0000161 movq $__NR_gettimeofday, %rax
162 syscall
163 ret
sewardj542eada2007-02-27 18:37:21 +0000164.LfnE2:
165.size VG_(amd64_linux_REDIR_FOR_vgettimeofday), .-LfnB2
166
sewardjb9bce632005-06-21 01:41:34 +0000167.global VG_(amd64_linux_REDIR_FOR_vtime)
sewardj542eada2007-02-27 18:37:21 +0000168.type VG_(amd64_linux_REDIR_FOR_vtime), @function
sewardjb9bce632005-06-21 01:41:34 +0000169VG_(amd64_linux_REDIR_FOR_vtime):
sewardj542eada2007-02-27 18:37:21 +0000170.LfnB3:
njna7598f62005-06-18 03:27:58 +0000171 movq $__NR_time, %rax
172 syscall
173 ret
sewardj542eada2007-02-27 18:37:21 +0000174.LfnE3:
175.size VG_(amd64_linux_REDIR_FOR_vtime), .-LfnB3
176
177/* A CIE for the above two functions, followed by their FDEs */
178 .section .eh_frame,"a",@progbits
179.Lframe1:
180 .long .LEcie1-.LScie1
181.LScie1:
182 .long 0x0
183 .byte 0x1
184 .string "zR"
185 .uleb128 0x1
186 .sleb128 -8
187 .byte 0x10
188 .uleb128 0x1
189 .byte 0x3
190 .byte 0xc
191 .uleb128 0x7
192 .uleb128 0x8
193 .byte 0x90
194 .uleb128 0x1
195 .align 8
196.LEcie1:
197.LSfde2:
198 .long .LEfde2-.LASfde2
199.LASfde2:
200 .long .LASfde2-.Lframe1
201 .long .LfnB2
202 .long .LfnE2-.LfnB2
203 .uleb128 0x0
204 .align 8
205.LEfde2:
206.LSfde3:
207 .long .LEfde3-.LASfde3
208.LASfde3:
209 .long .LASfde3-.Lframe1
210 .long .LfnB3
211 .long .LfnE3-.LfnB3
212 .uleb128 0x0
213 .align 8
214.LEfde3:
215 .previous
njna7598f62005-06-18 03:27:58 +0000216
sewardjb9bce632005-06-21 01:41:34 +0000217.global VG_(trampoline_stuff_end)
218VG_(trampoline_stuff_end):
njna7598f62005-06-18 03:27:58 +0000219
sewardja48a4932005-09-29 11:09:56 +0000220 /* and a trailing page of unexecutable code */
221 UD2_PAGE
222
223# undef UD2_16
224# undef UD2_64
225# undef UD2_256
226# undef UD2_1024
227# undef UD2_PAGE
sewardjb9bce632005-06-21 01:41:34 +0000228
sewardj05b5fc12005-06-21 09:56:56 +0000229/*---------------- ppc32-linux ----------------*/
sewardjb9bce632005-06-21 01:41:34 +0000230#else
231#if defined(VGP_ppc32_linux)
232
sewardja48a4932005-09-29 11:09:56 +0000233# define UD2_16 trap ; trap ; trap; trap
234# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
235# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
236# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
237# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
238
239 /* a leading page of unexecutable code */
240 UD2_PAGE
241
sewardj05b5fc12005-06-21 09:56:56 +0000242.global VG_(trampoline_stuff_start)
243VG_(trampoline_stuff_start):
cerion85665ca2005-06-20 15:51:07 +0000244
sewardja5940262007-09-10 16:28:38 +0000245.global VG_(ppc32_linux_SUBST_FOR_sigreturn)
246VG_(ppc32_linux_SUBST_FOR_sigreturn):
247 li 0,__NR_sigreturn
248 sc
249 .long 0 /*illegal insn*/
250
251.global VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
252VG_(ppc32_linux_SUBST_FOR_rt_sigreturn):
253 li 0,__NR_rt_sigreturn
254 sc
255 .long 0 /*illegal insn*/
256
sewardjad50be32005-08-18 11:54:30 +0000257/* There's no particular reason that this needs to be handwritten
258 assembly, but since that's what this file contains, here's a
259 simple strlen implementation (written in C and compiled by gcc.)
260*/
261.global VG_(ppc32_linux_REDIR_FOR_strlen)
sewardj0b6941e2005-10-12 10:00:56 +0000262.type VG_(ppc32_linux_REDIR_FOR_strlen), @function
sewardjad50be32005-08-18 11:54:30 +0000263VG_(ppc32_linux_REDIR_FOR_strlen):
264 lbz 4,0(3)
265 li 9,0
266 cmpwi 0,4,0
sewardj5e7b2302005-10-01 19:12:08 +0000267 beq- 0,.L18
268.L19:
sewardjad50be32005-08-18 11:54:30 +0000269 lbzu 5,1(3)
270 addi 9,9,1
271 cmpwi 0,5,0
sewardj5e7b2302005-10-01 19:12:08 +0000272 bne+ 0,.L19
273.L18:
sewardjad50be32005-08-18 11:54:30 +0000274 mr 3,9
275 blr
sewardj0b6941e2005-10-12 10:00:56 +0000276.size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
sewardjad50be32005-08-18 11:54:30 +0000277
sewardj5e7b2302005-10-01 19:12:08 +0000278/* Ditto strcmp */
279.global VG_(ppc32_linux_REDIR_FOR_strcmp)
sewardj0b6941e2005-10-12 10:00:56 +0000280.type VG_(ppc32_linux_REDIR_FOR_strcmp), @function
sewardj5e7b2302005-10-01 19:12:08 +0000281VG_(ppc32_linux_REDIR_FOR_strcmp):
282.L20:
283 lbz 0,0(3)
284 cmpwi 7,0,0
285 bne- 7,.L21
286 lbz 0,0(4)
287 li 11,0
288 cmpwi 7,0,0
289 beq- 7,.L22
290.L21:
291 lbz 0,0(3)
292 li 11,-1
293 cmpwi 7,0,0
294 beq- 7,.L22
295 lbz 0,0(4)
296 li 11,1
297 cmpwi 7,0,0
298 beq- 7,.L22
299 lbz 9,0(3)
300 lbz 0,0(4)
301 li 11,-1
302 cmplw 7,9,0
303 blt- 7,.L22
304 lbz 9,0(3)
305 lbz 0,0(4)
306 li 11,1
307 addi 3,3,1
308 addi 4,4,1
309 cmplw 7,9,0
310 ble+ 7,.L20
311.L22:
312 mr 3,11
313 blr
sewardj0b6941e2005-10-12 10:00:56 +0000314.size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
sewardj5e7b2302005-10-01 19:12:08 +0000315
sewardj31d83422005-10-15 02:00:41 +0000316/* Ditto index/strchr */
317.global VG_(ppc32_linux_REDIR_FOR_strchr)
318.type VG_(ppc32_linux_REDIR_FOR_strchr), @function
319VG_(ppc32_linux_REDIR_FOR_strchr):
320 lbz 0,0(3)
sewardj23c97b62007-08-27 11:50:39 +0000321 rlwinm 4,4,0,0xff
sewardj31d83422005-10-15 02:00:41 +0000322 cmpw 7,4,0
323 beqlr 7
324 cmpwi 7,0,0
sewardj23c97b62007-08-27 11:50:39 +0000325 bne 7,.L308
326 b .L304
327.L309:
328 beq 6,.L304
329.L308:
sewardj31d83422005-10-15 02:00:41 +0000330 lbzu 0,1(3)
sewardj23c97b62007-08-27 11:50:39 +0000331 cmpw 7,4,0
sewardj31d83422005-10-15 02:00:41 +0000332 cmpwi 6,0,0
sewardj23c97b62007-08-27 11:50:39 +0000333 bne 7,.L309
sewardj31d83422005-10-15 02:00:41 +0000334 blr
sewardj23c97b62007-08-27 11:50:39 +0000335.L304:
336 li 3,0
sewardj31d83422005-10-15 02:00:41 +0000337 blr
338.size VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
339
sewardj05b5fc12005-06-21 09:56:56 +0000340.global VG_(trampoline_stuff_end)
341VG_(trampoline_stuff_end):
342
sewardjf0915fc2006-01-05 14:07:04 +0000343 /* and a trailing page of unexecutable code */
344 UD2_PAGE
345
sewardja48a4932005-09-29 11:09:56 +0000346# undef UD2_16
347# undef UD2_64
348# undef UD2_256
349# undef UD2_1024
350# undef UD2_PAGE
sewardj05b5fc12005-06-21 09:56:56 +0000351
sewardj2c48c7b2005-11-29 13:05:56 +0000352/*---------------- ppc64-linux ----------------*/
353#else
354#if defined(VGP_ppc64_linux)
355
356# define UD2_16 trap ; trap ; trap; trap
357# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
358# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
359# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
360# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
361
362 /* a leading page of unexecutable code */
363 UD2_PAGE
364
365.global VG_(trampoline_stuff_start)
366VG_(trampoline_stuff_start):
sewardjf0915fc2006-01-05 14:07:04 +0000367
sewardj53092c62007-09-10 16:52:09 +0000368.global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn)
369VG_(ppc64_linux_SUBST_FOR_rt_sigreturn):
370 li 0,__NR_rt_sigreturn
371 sc
372 .long 0 /*illegal insn*/
373
sewardj658f05a2006-01-17 02:21:09 +0000374 /* See comment in pub_core_trampoline.h for what this is for */
sewardjf832bb92006-10-17 01:54:54 +0000375.global VG_(ppctoc_magic_redirect_return_stub)
376VG_(ppctoc_magic_redirect_return_stub):
sewardj658f05a2006-01-17 02:21:09 +0000377 trap
378
sewardj1a85f4f2006-01-12 21:15:35 +0000379 /* this function is written using the "dotless" ABI convention */
380 .align 2
381 .globl VG_(ppc64_linux_REDIR_FOR_strlen)
382 .section ".opd","aw"
383 .align 3
sewardjf0915fc2006-01-05 14:07:04 +0000384VG_(ppc64_linux_REDIR_FOR_strlen):
sewardj1a85f4f2006-01-12 21:15:35 +0000385 .quad .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
386 .previous
387 .size VG_(ppc64_linux_REDIR_FOR_strlen), \
388 .L0end-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
389 .type VG_(ppc64_linux_REDIR_FOR_strlen), @function
390
sewardjf0915fc2006-01-05 14:07:04 +0000391.L.VG_(ppc64_linux_REDIR_FOR_strlen):
392 mr 9,3
393 lbz 0,0(3)
394 li 3,0
395 cmpwi 7,0,0
396 beqlr 7
397 li 3,0
sewardj1a85f4f2006-01-12 21:15:35 +0000398.L01:
sewardjf0915fc2006-01-05 14:07:04 +0000399 addi 0,3,1
400 extsw 3,0
401 lbzx 0,9,3
402 cmpwi 7,0,0
sewardj1a85f4f2006-01-12 21:15:35 +0000403 bne 7,.L01
sewardjf0915fc2006-01-05 14:07:04 +0000404 blr
405 .long 0
406 .byte 0,0,0,0,0,0,0,0
sewardj1a85f4f2006-01-12 21:15:35 +0000407.L0end:
cerion297c88f2005-12-22 15:53:12 +0000408
sewardj1a85f4f2006-01-12 21:15:35 +0000409 /* this function is written using the "dotless" ABI convention */
410 .align 2
411 .globl VG_(ppc64_linux_REDIR_FOR_strchr)
412 .section ".opd","aw"
413 .align 3
414VG_(ppc64_linux_REDIR_FOR_strchr):
415 .quad .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
416 .previous
417 .size VG_(ppc64_linux_REDIR_FOR_strchr), \
418 .L1end-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
419 .type VG_(ppc64_linux_REDIR_FOR_strchr),@function
420
421.L.VG_(ppc64_linux_REDIR_FOR_strchr):
sewardj23c97b62007-08-27 11:50:39 +0000422 lbz 0,0(3)
sewardj1a85f4f2006-01-12 21:15:35 +0000423 rldicl 4,4,0,56
sewardj23c97b62007-08-27 11:50:39 +0000424 cmpw 7,4,0
425 beqlr 7
426 cmpdi 7,0,0
427 bne 7,.L18
428 b .L14
429.L19:
430 beq 6,.L14
431.L18:
432 lbzu 0,1(3)
433 cmpw 7,4,0
434 cmpdi 6,0,0
435 bne 7,.L19
436 blr
437.L14:
438 li 3,0
sewardj1a85f4f2006-01-12 21:15:35 +0000439 blr
440 .long 0
441 .byte 0,0,0,0,0,0,0,0
442.L1end:
443
444
sewardj2c48c7b2005-11-29 13:05:56 +0000445.global VG_(trampoline_stuff_end)
446VG_(trampoline_stuff_end):
447
sewardjf0915fc2006-01-05 14:07:04 +0000448 /* and a trailing page of unexecutable code */
449 UD2_PAGE
450
sewardj2c48c7b2005-11-29 13:05:56 +0000451# undef UD2_16
452# undef UD2_64
453# undef UD2_256
454# undef UD2_1024
455# undef UD2_PAGE
456
sewardjf832bb92006-10-17 01:54:54 +0000457/*---------------- ppc32-aix5 ----------------*/
458#else
459#if defined(VGP_ppc32_aix5)
460
461# define UD2_16 trap ; trap ; trap; trap
462# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
463# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
464# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
465# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
466
467 .csect .text[PR]
468
469 /* a leading page of unexecutable code */
470 UD2_PAGE
471
472.globl VG_(trampoline_stuff_start)
473VG_(trampoline_stuff_start):
474
475/* See pub_core_trampoline.h for an explaination of this. Also
476 see pub_core_initimg.h, struct AIX5PreloadPage. On entry, r3
477 points to an AIX5PreloadPage structure. Note we can only
478 use r2-r10 as scratch registers here since those are the
479 only ones restored from the preload page when finally
480 starting the client. */
481.globl VG_(ppc32_aix5_do_preloads_then_start_client)
482VG_(ppc32_aix5_do_preloads_then_start_client):
483 stwu 1,-1024(1)
484 stw 3,512(1) /* stash r3 512 bytes up stack */
485
486 /* Try to load .../vgpreload_core.so */
487 lwz 2,0(3) /* r2 = __NR___loadx */
488 lwz 5,20(3) /* r5 = off_preloadcorename */
489 add 6,3,5 /* r6 = preloadcorename */
sewardj13552642006-11-10 22:47:27 +0000490 addis 1,1,-4
sewardjf832bb92006-10-17 01:54:54 +0000491 bl do___loadx
sewardj13552642006-11-10 22:47:27 +0000492 addis 1,1,4
sewardjf832bb92006-10-17 01:54:54 +0000493 cmpwi 0,3,0
494 beq .Lfailed
495
496 /* Try to load .../vgpreload_tool.so, if it exists */
497 lwz 3,512(1) /* restore r3 */
498 lwz 2,0(3) /* r2 = __NR___loadx */
499 lwz 5,24(3) /* r5 = off_preloadtoolname */
500 cmpwi 0,5,0 /* skip tool preload if */
501 beq .Ltry_preload /* name not present */
502 add 6,3,5 /* r6 = preloadtoolname */
sewardj13552642006-11-10 22:47:27 +0000503 addis 1,1,-4
sewardjf832bb92006-10-17 01:54:54 +0000504 bl do___loadx
sewardj13552642006-11-10 22:47:27 +0000505 addis 1,1,4
sewardjf832bb92006-10-17 01:54:54 +0000506 cmpwi 0,3,0
507 beq .Lfailed
508
509.Ltry_preload:
510 /* Try to load the LD_PRELOAD= file, if it exists */
511 lwz 3,512(1) /* restore r3 */
512 lwz 2,0(3) /* r2 = __NR___loadx */
513 lwz 5,28(3) /* r5 = off_ld_preloadname */
514 cmpwi 0,5,0 /* skip ld_preload if */
515 beq .Lstart_client /* name not present */
516 add 6,3,5 /* r6 = ld_preloadname */
sewardj13552642006-11-10 22:47:27 +0000517 addis 1,1,-4
sewardjf832bb92006-10-17 01:54:54 +0000518 bl do___loadx
sewardj13552642006-11-10 22:47:27 +0000519 addis 1,1,4
sewardjf832bb92006-10-17 01:54:54 +0000520 cmpwi 0,3,0
521 beq .Lfailed
522
523.Lstart_client:
524 /* Success. Restore r2-r10 from preloadpage-> and start
525 the client. */
526 lwz 3,512(1) /* restore r3 */
527 addi 1,1,1024
528 lwz 2,32+4(3) /* preloadpage->client_start */
529 mtctr 2
530 lwz 2,40+4(3) /* preloadpage->r2 */
531 lwz 4,56+4(3) /* preloadpage->r4 */
532 lwz 5,64+4(3) /* preloadpage->r5 */
533 lwz 6,72+4(3) /* preloadpage->r6 */
534 lwz 7,80+4(3) /* preloadpage->r7 */
535 lwz 8,88+4(3) /* preloadpage->r8 */
536 lwz 9,96+4(3) /* preloadpage->r9 */
537 lwz 10,104+4(3) /* preloadpage->r10 */
538 lwz 3,48+4(3) /* preloadpage->r3 */
539 bctr
540 /*NOTREACHED*/
541 trap
542
543.Lfailed:
544 /* __loadx barfed for some reason. Print the error
545 message and get out. */
546 /* First the error msg */
547 lwz 3,512(1) /* restore r3 */
548 lwz 2,4(3) /* r2 = __NR_kwrite */
549 lwz 4,12(3) /* r4 = offset of err msg */
550 add 4,4,3 /* r4 = err msg */
551 lwz 5,16(3) /* r5 = length err msg */
552 li 3,2 /* r3 = stderr */
553 bl do_syscall
554 /* now call the diagnosis fn */
555 lwz 3,512(1) /* restore r3 */
556 lwz 4,112(3) /* preloadpage->p_diagnose_load_failure */
557 lwz 2,4(4) /* get its TOC ptr */
558 lwz 4,0(4) /* get its entry point */
559 mtlr 4
560 blrl
561 /* Now do _exit(1) */
562 lwz 3,512(1) /* restore r3 */
563 lwz 2,8(3) /* r2 = __NR_exit */
564 li 3,1 /* doing _exit(1) */
565 addi 1,1,1024 /* fix stack pointer */
566 bl do_syscall
567 /*NOTREACHED*/
568 trap
569
570do___loadx:
571 /* On entry: r2 = __NR___loadx, r6 = name of module */
572 li 3,1
573 slwi 3,3,24 /* r3 = 0x1000000 = VKI_DL_LOAD */
sewardj13552642006-11-10 22:47:27 +0000574 mr 4,1
575 lis 5,3
sewardjf832bb92006-10-17 01:54:54 +0000576 li 7,0
577 li 8,0
578 li 9,0
579 li 10,0
580do_syscall:
sewardj13552642006-11-10 22:47:27 +0000581 crorc 6,6,6
sewardjf832bb92006-10-17 01:54:54 +0000582 sc
sewardj13552642006-11-10 22:47:27 +0000583 trap
sewardjf832bb92006-10-17 01:54:54 +0000584 /* sc continues at 'lr', hence this
585 constitutes an automatic return */
586
587
588 /* See comment in pub_core_trampoline.h for what this is for */
589.globl VG_(ppctoc_magic_redirect_return_stub)
590VG_(ppctoc_magic_redirect_return_stub):
591 trap
592
593.globl VG_(trampoline_stuff_end)
594VG_(trampoline_stuff_end):
595
596 /* and a trailing page of unexecutable code */
597 UD2_PAGE
598
599# undef UD2_16
600# undef UD2_64
601# undef UD2_256
602# undef UD2_1024
603# undef UD2_PAGE
604
605/*---------------- ppc64-aix5 ----------------*/
606#else
607#if defined(VGP_ppc64_aix5)
608
609# define UD2_16 trap ; trap ; trap; trap
610# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
611# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
612# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
613# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
614
615.globl VG_(trampoline_stuff_start)
616VG_(trampoline_stuff_start):
617/* See pub_core_trampoline.h for an explaination of this. Also
618 see pub_core_initimg.h, struct AIX5PreloadPage. On entry, r3
619 points to an AIX5PreloadPage structure. Note we can only
620 use r2-r10 as scratch registers here since those are the
621 only ones restored from the preload page when finally
622 starting the client. */
623.globl VG_(ppc64_aix5_do_preloads_then_start_client)
624VG_(ppc64_aix5_do_preloads_then_start_client):
625 stdu 1,-1024(1)
626 std 3,512(1) /* stash r3 512 bytes up stack */
627
628 /* Try to load .../vgpreload_core.so */
629 lwz 2,0(3) /* r2 = __NR_kload */
630 lwz 5,20(3) /* r5 = off_preloadcorename */
631 add 3,3,5 /* r6 = preloadcorename */
632 bl do_kload
633 cmpdi 0,3,0
634 beq .Lfailed
635
636 /* Try to load .../vgpreload_tool.so, if it exists */
637 ld 3,512(1) /* restore r3 */
638 lwz 2,0(3) /* r2 = __NR_kload */
639 lwz 5,24(3) /* r5 = off_preloadtoolname */
640 cmpwi 0,5,0 /* skip tool preload if */
641 beq .Ltry_preload /* name not present */
642 add 3,3,5 /* r6 = preloadtoolname */
643 bl do_kload
644 cmpdi 0,3,0
645 beq .Lfailed
646
647.Ltry_preload:
648 /* Try to load the LD_PRELOAD= file, if it exists */
649 ld 3,512(1) /* restore r3 */
650 lwz 2,0(3) /* r2 = __NR_kload */
651 lwz 5,28(3) /* r5 = off_ld_preloadname */
652 cmpwi 0,5,0 /* skip ld_preload if */
653 beq .Lstart_client /* name not present */
654 add 3,3,5 /* r6 = ld_preloadname */
655 bl do_kload
656 cmpdi 0,3,0
657 beq .Lfailed
658
659.Lstart_client:
660 /* Success. Restore r2-r10 from preloadpage-> and start
661 the client. */
662 ld 3,512(1) /* restore r3 */
663 addi 1,1,1024
664 ld 2,32+0(3) /* preloadpage->client_start */
665 mtctr 2
666 ld 2,40+0(3) /* preloadpage->r2 */
667 ld 4,56+0(3) /* preloadpage->r4 */
668 ld 5,64+0(3) /* preloadpage->r5 */
669 ld 6,72+0(3) /* preloadpage->r6 */
670 ld 7,80+0(3) /* preloadpage->r7 */
671 ld 8,88+0(3) /* preloadpage->r8 */
672 ld 9,96+0(3) /* preloadpage->r9 */
673 ld 10,104+0(3) /* preloadpage->r10 */
674 ld 3,48+0(3) /* preloadpage->r3 */
675 bctr
676 /*NOTREACHED*/
677 trap
678
679.Lfailed:
680 /* __loadx barfed for some reason. Print the error
681 message and get out. */
682 /* First the error msg */
683 ld 3,512(1) /* restore r3 */
684 lwz 2,4(3) /* r2 = __NR_kwrite */
685 lwz 4,12(3) /* r4 = offset of err msg */
686 add 4,4,3 /* r4 = err msg */
687 lwz 5,16(3) /* r5 = length err msg */
688 li 3,2 /* r3 = stderr */
689 bl do_syscall
690 /* now call the diagnosis fn */
691 ld 3,512(1) /* restore r3 */
692 ld 4,112(3) /* preloadpage->p_diagnose_load_failure */
693 ld 11,16(4)
694 ld 2,8(4) /* get its TOC ptr */
695 ld 4,0(4) /* get its entry point */
696 mtlr 4
697 blrl
698 /* Now do _exit(1) */
699 lwz 3,512(1) /* restore r3 */
700 lwz 2,8(3) /* r2 = __NR_exit */
701 li 3,1 /* doing _exit(1) */
702 addi 1,1,1024 /* fix stack pointer */
703 bl do_syscall
704 /*NOTREACHED*/
705 trap
706
707do_kload:
708 /* On entry: r2 = __NR_kload, r3 = name of module */
709 li 4,0
710 li 5,0
711 li 6,0
712 li 7,0
713 li 8,0
714 li 9,0
715 li 10,0
716do_syscall:
sewardj13552642006-11-10 22:47:27 +0000717 crorc 6,6,6
sewardjf832bb92006-10-17 01:54:54 +0000718 sc
719 /* sc continues at 'lr', hence this
720 constitutes an automatic return */
721
722 /* See comment in pub_core_trampoline.h for what this is for */
723.globl VG_(ppctoc_magic_redirect_return_stub)
724VG_(ppctoc_magic_redirect_return_stub):
725 trap
726
727.globl VG_(trampoline_stuff_end)
728VG_(trampoline_stuff_end):
729
730 /* and a trailing page of unexecutable code */
731 UD2_PAGE
732
733# undef UD2_16
734# undef UD2_64
735# undef UD2_256
736# undef UD2_1024
737# undef UD2_PAGE
738
sewardj05b5fc12005-06-21 09:56:56 +0000739/*---------------- unknown ----------------*/
njna7598f62005-06-18 03:27:58 +0000740#else
sewardjb9bce632005-06-21 01:41:34 +0000741# error Unknown platform
742
njna7598f62005-06-18 03:27:58 +0000743#endif
sewardjb9bce632005-06-21 01:41:34 +0000744#endif
745#endif
sewardj2c48c7b2005-11-29 13:05:56 +0000746#endif
sewardjf832bb92006-10-17 01:54:54 +0000747#endif
748#endif
sewardjb9bce632005-06-21 01:41:34 +0000749
sewardjf832bb92006-10-17 01:54:54 +0000750#if defined(VGO_linux)
thughes4ad52d02004-06-27 17:37:21 +0000751/* Let the linker know we don't need an executable stack */
752.section .note.GNU-stack,"",@progbits
sewardjf832bb92006-10-17 01:54:54 +0000753#endif
754
sewardjb9bce632005-06-21 01:41:34 +0000755/*--------------------------------------------------------------------*/
756/*--- end ---*/
757/*--------------------------------------------------------------------*/