Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Trampoline code page stuff.                   m_trampoline.S ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7   This file is part of Valgrind, a dynamic binary instrumentation
      8   framework.
      9 
     10   Copyright (C) 2000-2010 Julian Seward
     11      jseward (at) acm.org
     12   Copyright (C) 2006-2010 OpenWorks LLP
     13      info (at) open-works.co.uk
     14 
     15   This program is free software; you can redistribute it and/or
     16   modify it under the terms of the GNU General Public License as
     17   published by the Free Software Foundation; either version 2 of the
     18   License, or (at your option) any later version.
     19 
     20   This program is distributed in the hope that it will be useful, but
     21   WITHOUT ANY WARRANTY; without even the implied warranty of
     22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23   General Public License for more details.
     24 
     25   You should have received a copy of the GNU General Public License
     26   along with this program; if not, write to the Free Software
     27   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     28   02111-1307, USA.
     29 
     30   The GNU General Public License is contained in the file COPYING.
     31 */
     32 
     33 #include "pub_core_basics_asm.h"
     34 #include "pub_core_vkiscnums_asm.h"
     35 
     36 /* ------------------ SIMULATED CPU HELPERS ------------------ */
     37 /*
     38    Replacements for some functions to do with vsyscalls and signals.
     39    This code runs on the simulated CPU.
     40 */
     41 
     42 /*---------------------- x86-linux ----------------------*/
     43 #if defined(VGP_x86_linux)
     44 
     45 #	define UD2_16     ud2 ; ud2 ; ud2 ; ud2 ;ud2 ; ud2 ; ud2 ; ud2
     46 #	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
     47 #	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
     48 #	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
     49 #	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
     50 
     51 	/* a leading page of unexecutable code */
     52 	UD2_PAGE
     53 
     54 .global VG_(trampoline_stuff_start)
     55 VG_(trampoline_stuff_start):
     56 
     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 */
     63         popl    %eax
     64         movl    $ __NR_sigreturn, %eax
     65         int     $0x80
     66         ud2
     67 
     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
     72         int     $0x80
     73         ud2
     74 
     75 /* There's no particular reason that this needs to be handwritten
     76    assembly, but since that's what this file contains, here's a
     77    simple index implementation (written in C and compiled by gcc.)
     78 
     79    unsigned char* REDIR_FOR_index ( const char* s, int c )
     80    {
     81       unsigned char  ch = (unsigned char)((unsigned int)c);
     82       unsigned char* p  = (unsigned char*)s;
     83       while (1) {
     84          if (*p == ch) return p;
     85          if (*p == 0)  return 0;
     86          p++;
     87       }
     88    }
     89 */
     90 .global VG_(x86_linux_REDIR_FOR_index)
     91 .type   VG_(x86_linux_REDIR_FOR_index), @function
     92 VG_(x86_linux_REDIR_FOR_index):
     93         pushl   %ebp
     94         movl    %esp, %ebp
     95         movl    8(%ebp), %eax
     96         movzbl  12(%ebp), %ecx
     97         movzbl  (%eax), %edx
     98         cmpb    %dl, %cl
     99         jne     .L9
    100         jmp     .L2
    101 .L11:
    102         addl    $1, %eax
    103         movzbl  (%eax), %edx
    104         cmpb    %dl, %cl
    105         je      .L2
    106 .L9:
    107         testb   %dl, %dl
    108         jne     .L11
    109         xorl    %eax, %eax
    110 .L2:
    111         popl    %ebp
    112         ret
    113 .size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index)
    114 
    115 .global VG_(trampoline_stuff_end)
    116 VG_(trampoline_stuff_end):
    117 
    118 	/* and a trailing page of unexecutable code */
    119 	UD2_PAGE
    120 
    121 #	undef UD2_16
    122 #	undef UD2_64
    123 #	undef UD2_256
    124 #	undef UD2_1024
    125 #	undef UD2_PAGE
    126 
    127 /*---------------------- amd64-linux ----------------------*/
    128 #else
    129 #if defined(VGP_amd64_linux)
    130 
    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
    136 
    137 	/* a leading page of unexecutable code */
    138 	UD2_PAGE
    139 
    140 .global VG_(trampoline_stuff_start)
    141 VG_(trampoline_stuff_start):
    142 
    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
    148         syscall
    149         ud2
    150 
    151 .global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
    152 .type   VG_(amd64_linux_REDIR_FOR_vgettimeofday), @function
    153 VG_(amd64_linux_REDIR_FOR_vgettimeofday):
    154 .LfnB2:
    155         movq    $__NR_gettimeofday, %rax
    156         syscall
    157         ret
    158 .LfnE2:
    159 .size VG_(amd64_linux_REDIR_FOR_vgettimeofday), .-.LfnB2
    160 
    161 .global VG_(amd64_linux_REDIR_FOR_vtime)
    162 .type   VG_(amd64_linux_REDIR_FOR_vtime), @function
    163 VG_(amd64_linux_REDIR_FOR_vtime):
    164 .LfnB3:
    165         movq    $__NR_time, %rax
    166         syscall
    167         ret
    168 .LfnE3:
    169 .size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
    170 
    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.)
    174 */
    175 .global VG_(amd64_linux_REDIR_FOR_strlen)
    176 .type   VG_(amd64_linux_REDIR_FOR_strlen), @function
    177 VG_(amd64_linux_REDIR_FOR_strlen):
    178 .LfnB4:
    179 	xorl	%eax, %eax
    180 	cmpb	$0, (%rdi)
    181 	movq	%rdi, %rdx
    182 	je	.L41
    183 .L40:	addq	$1, %rdx
    184 	cmpb	$0, (%rdx)
    185 	jne	.L40
    186 	movq	%rdx, %rax
    187 	subq	%rdi, %rax
    188 .L41:	ret
    189 .LfnE4:
    190 .size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
    191 
    192 
    193 /* A CIE for the above three functions, followed by their FDEs */
    194 	.section .eh_frame,"a",@progbits
    195 .Lframe1:
    196         .long   .LEcie1-.LScie1
    197 .LScie1:
    198         .long   0x0
    199         .byte   0x1
    200         .string "zR"
    201         .uleb128 0x1
    202         .sleb128 -8
    203         .byte   0x10
    204         .uleb128 0x1
    205         .byte   0x3
    206         .byte   0xc
    207         .uleb128 0x7
    208         .uleb128 0x8
    209         .byte   0x90
    210         .uleb128 0x1
    211         .align 8
    212 .LEcie1:
    213 .LSfde2:
    214         .long   .LEfde2-.LASfde2
    215 .LASfde2:
    216         .long   .LASfde2-.Lframe1
    217         .long   .LfnB2
    218         .long   .LfnE2-.LfnB2
    219         .uleb128 0x0
    220         .align 8
    221 .LEfde2:
    222 .LSfde3:
    223         .long   .LEfde3-.LASfde3
    224 .LASfde3:
    225         .long   .LASfde3-.Lframe1
    226         .long   .LfnB3
    227         .long   .LfnE3-.LfnB3
    228         .uleb128 0x0
    229         .align 8
    230 .LEfde3:
    231 .LSfde4:
    232         .long   .LEfde4-.LASfde4
    233 .LASfde4:
    234         .long   .LASfde4-.Lframe1
    235         .long   .LfnB4
    236         .long   .LfnE4-.LfnB4
    237         .uleb128 0x0
    238         .align 8
    239 .LEfde4:
    240 	.previous
    241 
    242 .global VG_(trampoline_stuff_end)
    243 VG_(trampoline_stuff_end):
    244 
    245 	/* and a trailing page of unexecutable code */
    246 	UD2_PAGE
    247 
    248 #	undef UD2_16
    249 #	undef UD2_64
    250 #	undef UD2_256
    251 #	undef UD2_1024
    252 #	undef UD2_PAGE
    253 
    254 /*---------------- ppc32-linux ----------------*/
    255 #else
    256 #if defined(VGP_ppc32_linux)
    257 
    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
    263 
    264 	/* a leading page of unexecutable code */
    265 	UD2_PAGE
    266 
    267 .global VG_(trampoline_stuff_start)
    268 VG_(trampoline_stuff_start):
    269 
    270 .global VG_(ppc32_linux_SUBST_FOR_sigreturn)
    271 VG_(ppc32_linux_SUBST_FOR_sigreturn):
    272 	li 0,__NR_sigreturn
    273         sc
    274         .long 0	/*illegal insn*/
    275 
    276 .global VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
    277 VG_(ppc32_linux_SUBST_FOR_rt_sigreturn):
    278 	li 0,__NR_rt_sigreturn
    279         sc
    280         .long 0	/*illegal insn*/
    281 
    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.)
    285 */
    286 .global VG_(ppc32_linux_REDIR_FOR_strlen)
    287 .type   VG_(ppc32_linux_REDIR_FOR_strlen), @function
    288 VG_(ppc32_linux_REDIR_FOR_strlen):
    289         lbz 4,0(3)
    290         li 9,0
    291         cmpwi 0,4,0
    292         beq- 0,.L18
    293 .L19:
    294         lbzu 5,1(3)
    295         addi 9,9,1
    296         cmpwi 0,5,0
    297         bne+ 0,.L19
    298 .L18:
    299         mr 3,9
    300         blr
    301 .size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
    302 
    303 /* Ditto strcmp */
    304 .global VG_(ppc32_linux_REDIR_FOR_strcmp)
    305 .type   VG_(ppc32_linux_REDIR_FOR_strcmp), @function
    306 VG_(ppc32_linux_REDIR_FOR_strcmp):
    307 .L20:
    308         lbz 0,0(3)
    309         cmpwi 7,0,0
    310         bne- 7,.L21
    311         lbz 0,0(4)
    312         li 11,0
    313         cmpwi 7,0,0
    314         beq- 7,.L22
    315 .L21:
    316         lbz 0,0(3)
    317         li 11,-1
    318         cmpwi 7,0,0
    319         beq- 7,.L22
    320         lbz 0,0(4)
    321         li 11,1
    322         cmpwi 7,0,0
    323         beq- 7,.L22
    324         lbz 9,0(3)
    325         lbz 0,0(4)
    326         li 11,-1
    327         cmplw 7,9,0
    328         blt- 7,.L22
    329         lbz 9,0(3)
    330         lbz 0,0(4)
    331         li 11,1
    332         addi 3,3,1
    333         addi 4,4,1
    334         cmplw 7,9,0
    335         ble+ 7,.L20
    336 .L22:
    337         mr 3,11
    338         blr
    339 .size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
    340 
    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):
    345         lbz 0,0(3)
    346         rlwinm 4,4,0,0xff
    347         cmpw 7,4,0
    348         beqlr 7
    349         cmpwi 7,0,0
    350         bne 7,.L308
    351         b .L304
    352 .L309:
    353         beq 6,.L304
    354 .L308:
    355         lbzu 0,1(3)
    356         cmpw 7,4,0
    357         cmpwi 6,0,0
    358         bne 7,.L309
    359         blr
    360 .L304:
    361         li 3,0
    362         blr
    363 .size   VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
    364 
    365 .global VG_(trampoline_stuff_end)
    366 VG_(trampoline_stuff_end):
    367 
    368 	/* and a trailing page of unexecutable code */
    369 	UD2_PAGE
    370 
    371 #	undef UD2_16
    372 #	undef UD2_64
    373 #	undef UD2_256
    374 #	undef UD2_1024
    375 #	undef UD2_PAGE
    376 
    377 /*---------------- ppc64-linux ----------------*/
    378 #else
    379 #if defined(VGP_ppc64_linux)
    380 
    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
    386 
    387 	/* a leading page of unexecutable code */
    388 	UD2_PAGE
    389 
    390 .global VG_(trampoline_stuff_start)
    391 VG_(trampoline_stuff_start):
    392 
    393 .global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn)
    394 VG_(ppc64_linux_SUBST_FOR_rt_sigreturn):
    395 	li 0,__NR_rt_sigreturn
    396         sc
    397         .long 0	/*illegal insn*/
    398 
    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):
    402 	trap
    403 
    404 	/* this function is written using the "dotless" ABI convention */
    405 	.align 2
    406 	.globl VG_(ppc64_linux_REDIR_FOR_strlen)
    407 	.section        ".opd","aw"
    408 	.align 3
    409 VG_(ppc64_linux_REDIR_FOR_strlen):
    410 	.quad   .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
    411 	.previous
    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
    415 
    416 .L.VG_(ppc64_linux_REDIR_FOR_strlen):
    417         mr 9,3
    418         lbz 0,0(3)
    419         li 3,0
    420         cmpwi 7,0,0
    421         beqlr 7
    422         li 3,0
    423 .L01:
    424         addi 0,3,1
    425         extsw 3,0
    426         lbzx 0,9,3
    427         cmpwi 7,0,0
    428         bne 7,.L01
    429         blr
    430         .long 0
    431         .byte 0,0,0,0,0,0,0,0
    432 .L0end:
    433 
    434         /* this function is written using the "dotless" ABI convention */
    435         .align 2
    436         .globl VG_(ppc64_linux_REDIR_FOR_strchr)
    437 	.section        ".opd","aw"
    438 	.align 3
    439 VG_(ppc64_linux_REDIR_FOR_strchr):
    440         .quad   .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
    441         .previous
    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
    445 
    446 .L.VG_(ppc64_linux_REDIR_FOR_strchr):
    447         lbz 0,0(3)
    448         rldicl 4,4,0,56
    449         cmpw 7,4,0
    450         beqlr 7
    451         cmpdi 7,0,0
    452         bne 7,.L18
    453         b .L14
    454 .L19:
    455         beq 6,.L14
    456 .L18:
    457         lbzu 0,1(3)
    458         cmpw 7,4,0
    459         cmpdi 6,0,0
    460         bne 7,.L19
    461         blr
    462 .L14:
    463         li 3,0
    464         blr
    465         .long 0
    466         .byte 0,0,0,0,0,0,0,0
    467 .L1end:
    468 
    469 
    470 .global VG_(trampoline_stuff_end)
    471 VG_(trampoline_stuff_end):
    472 
    473 	/* and a trailing page of unexecutable code */
    474 	UD2_PAGE
    475 
    476 #	undef UD2_16
    477 #	undef UD2_64
    478 #	undef UD2_256
    479 #	undef UD2_1024
    480 #	undef UD2_PAGE
    481 
    482 /*---------------- ppc32-linux ----------------*/
    483 
    484 #elif defined(VGP_arm_linux)
    485 
    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
    492 
    493 	/* a leading page of unexecutable code */
    494 	UD2_PAGE
    495 
    496 .global VG_(trampoline_stuff_start)
    497 VG_(trampoline_stuff_start):
    498 
    499 .global VG_(arm_linux_REDIR_FOR_strlen)
    500 VG_(arm_linux_REDIR_FOR_strlen):
    501 	mov	r2, r0
    502 	ldrb	r0, [r0, #0]	@ zero_extendqisi2
    503 	@ lr needed for prologue
    504 	cmp	r0, #0
    505 	bxeq	lr
    506 	mov	r0, #0
    507 .L5:
    508 	add	r0, r0, #1
    509 	ldrb	r3, [r0, r2]	@ zero_extendqisi2
    510 	cmp	r3, #0
    511 	bne	.L5
    512 	bx	lr
    513 	UD2_4
    514 
    515 //.global VG_(arm_linux_REDIR_FOR_index)
    516 //VG_(arm_linux_REDIR_FOR_index):
    517 //	ldrb	r3, [r0, #0]	@ zero_extendqisi2
    518 //	and	r1, r1, #255
    519 //	cmp	r3, r1
    520 //	@ lr needed for prologue
    521 //	bne	.L9
    522 //	bx	lr
    523 //.L12:
    524 //	ldrb	r3, [r0, #1]!	@ zero_extendqisi2
    525 //	cmp	r3, r1
    526 //	beq	.L11
    527 //.L9:
    528 //	cmp	r3, #0
    529 //	bne	.L12
    530 //	mov	r0, #0
    531 //	bx	lr
    532 //.L11:
    533 //	bx	lr
    534 //	UD2_4
    535 
    536 .global VG_(arm_linux_REDIR_FOR_memcpy)
    537 VG_(arm_linux_REDIR_FOR_memcpy):
    538 	stmfd	sp!, {r4, r5, lr}
    539 	subs	lr, r2, #0
    540 	mov	r5, r0
    541 	beq	.L2
    542 	cmp	r0, r1
    543 	bls	.L4
    544 	add	r3, r0, lr
    545 	add	r1, lr, r1
    546 	cmp	lr, #3
    547 	sub	r4, r3, #1
    548 	sub	r0, r1, #1
    549 	ble	.L28
    550 	sub	ip, r3, #5
    551 	sub	r1, r1, #5
    552 .L8:
    553 	ldrb	r3, [r1, #4]	@ zero_extendqisi2
    554 	sub	lr, lr, #4
    555 	strb	r3, [ip, #4]
    556 	ldrb	r2, [r1, #3]	@ zero_extendqisi2
    557 	cmp	lr, #3
    558 	strb	r2, [ip, #3]
    559 	ldrb	r3, [r1, #2]	@ zero_extendqisi2
    560 	mov	r4, ip
    561 	strb	r3, [ip, #2]
    562 	ldrb	r2, [r1, #1]	@ zero_extendqisi2
    563 	mov	r0, r1
    564 	strb	r2, [ip, #1]
    565 	sub	r1, r1, #4
    566 	sub	ip, ip, #4
    567 	bgt	.L8
    568 	cmp	lr, #0
    569 	beq	.L2
    570 .L28:
    571 	sub	r2, lr, #1
    572 .L21:
    573 	sub	r2, r2, #1
    574 	ldrb	r3, [r0], #-1	@ zero_extendqisi2
    575 	cmn	r2, #1
    576 	strb	r3, [r4], #-1
    577 	bne	.L21
    578 .L2:
    579 	mov	r0, r5
    580 	ldmfd	sp!, {r4, r5, pc}
    581 .L4:
    582 	bcs	.L2
    583 	cmp	lr, #3
    584 	mov	ip, r0
    585 	ble	.L29
    586 .L19:
    587 	ldrb	r3, [r1, #0]	@ zero_extendqisi2
    588 	sub	lr, lr, #4
    589 	strb	r3, [ip, #0]
    590 	ldrb	r2, [r1, #1]	@ zero_extendqisi2
    591 	cmp	lr, #3
    592 	strb	r2, [ip, #1]
    593 	ldrb	r3, [r1, #2]	@ zero_extendqisi2
    594 	strb	r3, [ip, #2]
    595 	ldrb	r2, [r1, #3]	@ zero_extendqisi2
    596 	add	r1, r1, #4
    597 	strb	r2, [ip, #3]
    598 	add	ip, ip, #4
    599 	bgt	.L19
    600 	cmp	lr, #0
    601 	beq	.L2
    602 .L29:
    603 	sub	r2, lr, #1
    604 .L20:
    605 	sub	r2, r2, #1
    606 	ldrb	r3, [r1], #1	@ zero_extendqisi2
    607 	cmn	r2, #1
    608 	strb	r3, [ip], #1
    609 	bne	.L20
    610 	mov	r0, r5
    611 	ldmfd	sp!, {r4, r5, pc}
    612 	UD2_4
    613 
    614 .global VG_(trampoline_stuff_end)
    615 VG_(trampoline_stuff_end):
    616 
    617 	/* and a trailing page of unexecutable code */
    618 	UD2_PAGE
    619 
    620 #	undef UD2_4
    621 #	undef UD2_16
    622 #	undef UD2_64
    623 #	undef UD2_256
    624 #	undef UD2_1024
    625 #	undef UD2_PAGE
    626 
    627 /*---------------- ppc32-aix5 ----------------*/
    628 #else
    629 #if defined(VGP_ppc32_aix5)
    630 
    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
    636 
    637 	.csect .text[PR]
    638 
    639 	/* a leading page of unexecutable code */
    640 	UD2_PAGE
    641 
    642 .globl VG_(trampoline_stuff_start)
    643 VG_(trampoline_stuff_start):
    644 
    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):
    653 	stwu	1,-1024(1)
    654 	stw	3,512(1)	/* stash r3 512 bytes up stack */
    655 
    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 */
    660 	addis	1,1,-4
    661 	bl	do___loadx
    662 	addis	1,1,4
    663 	cmpwi	0,3,0
    664 	beq	.Lfailed
    665 
    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 */
    673 	addis	1,1,-4
    674 	bl	do___loadx
    675 	addis	1,1,4
    676 	cmpwi	0,3,0
    677 	beq	.Lfailed
    678 
    679 .Ltry_preload:
    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 */
    687 	addis	1,1,-4
    688 	bl	do___loadx
    689 	addis	1,1,4
    690 	cmpwi	0,3,0
    691 	beq	.Lfailed
    692 
    693 .Lstart_client:
    694 	/* Success.  Restore r2-r10 from preloadpage-> and start
    695 	the client. */
    696 	lwz	3,512(1)	/* restore r3 */
    697 	addi	1,1,1024
    698 	lwz	2,32+4(3)	/* preloadpage->client_start */
    699 	mtctr	2
    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 */
    709 	bctr
    710 	/*NOTREACHED*/
    711 	trap
    712 
    713 .Lfailed:
    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 */
    723 	bl	do_syscall
    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 */
    729 	mtlr	4
    730 	blrl
    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 */
    736 	bl	do_syscall
    737 	/*NOTREACHED*/
    738 	trap
    739 
    740 do___loadx:
    741 	/* On entry: r2 = __NR___loadx,	r6 = name of module */
    742 	li	3,1
    743 	slwi	3,3,24	/* r3 = 0x1000000 = VKI_DL_LOAD */
    744 	mr	4,1
    745 	lis	5,3
    746 	li	7,0
    747 	li	8,0
    748 	li	9,0
    749 	li	10,0
    750 do_syscall:
    751 	crorc	6,6,6
    752 	sc
    753 	trap
    754 	/* sc continues at 'lr', hence this
    755 	constitutes an automatic return */
    756 
    757 
    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):
    761 	trap
    762 
    763 .globl VG_(trampoline_stuff_end)
    764 VG_(trampoline_stuff_end):
    765 
    766 	/* and a trailing page of unexecutable code */
    767 	UD2_PAGE
    768 
    769 #	undef UD2_16
    770 #	undef UD2_64
    771 #	undef UD2_256
    772 #	undef UD2_1024
    773 #	undef UD2_PAGE
    774 
    775 /*---------------- ppc64-aix5 ----------------*/
    776 #else
    777 #if defined(VGP_ppc64_aix5)
    778 
    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
    784 
    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):
    795 	stdu	1,-1024(1)
    796 	std	3,512(1)	/* stash r3 512 bytes up stack */
    797 
    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 */
    802 	bl	do_kload
    803 	cmpdi	0,3,0
    804 	beq	.Lfailed
    805 
    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 */
    813 	bl	do_kload
    814 	cmpdi	0,3,0
    815 	beq	.Lfailed
    816 
    817 .Ltry_preload:
    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 */
    825 	bl	do_kload
    826 	cmpdi	0,3,0
    827 	beq	.Lfailed
    828 
    829 .Lstart_client:
    830 	/* Success.  Restore r2-r10 from preloadpage-> and start
    831 	the client. */
    832 	ld	3,512(1)	/* restore r3 */
    833 	addi	1,1,1024
    834 	ld	2,32+0(3)	/* preloadpage->client_start */
    835 	mtctr	2
    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 */
    845 	bctr
    846 	/*NOTREACHED*/
    847 	trap
    848 
    849 .Lfailed:
    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 */
    859 	bl	do_syscall
    860 	/* now call the diagnosis fn */
    861 	ld	3,512(1)	/* restore r3 */
    862 	ld	4,112(3)	/* preloadpage->p_diagnose_load_failure */
    863 	ld	11,16(4)
    864 	ld	2,8(4)		/* get its TOC ptr */
    865 	ld	4,0(4)		/* get its entry point */
    866 	mtlr	4
    867 	blrl
    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 */
    873 	bl	do_syscall
    874 	/*NOTREACHED*/
    875 	trap
    876 
    877 do_kload:
    878 	/* On entry: r2 = __NR_kload,	r3 = name of module */
    879 	li	4,0
    880 	li	5,0
    881 	li	6,0
    882 	li	7,0
    883 	li	8,0
    884 	li	9,0
    885 	li	10,0
    886 do_syscall:
    887 	crorc	6,6,6
    888 	sc
    889 	/* sc continues at 'lr', hence this
    890 	constitutes an automatic return */
    891 
    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):
    895 	trap
    896 
    897 .globl VG_(trampoline_stuff_end)
    898 VG_(trampoline_stuff_end):
    899 
    900 	/* and a trailing page of unexecutable code */
    901 	UD2_PAGE
    902 
    903 #	undef UD2_16
    904 #	undef UD2_64
    905 #	undef UD2_256
    906 #	undef UD2_1024
    907 #	undef UD2_PAGE
    908 
    909 /*---------------- x86-darwin ----------------*/
    910 #else
    911 #if defined(VGP_x86_darwin)
    912 
    913         /* a leading page of unexecutable code */
    914 .fill 2048, 2, 0x0b0f /* `ud2` */
    915 
    916 .globl VG_(trampoline_stuff_start)
    917 VG_(trampoline_stuff_start):
    918 
    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
    922 	version) */
    923         movl    $ __NR_DARWIN_FAKE_SIGRETURN, %eax
    924         int     $0x80
    925         ud2
    926 
    927 .globl VG_(x86_darwin_REDIR_FOR_strlen)
    928 VG_(x86_darwin_REDIR_FOR_strlen):
    929         movl    4(%esp), %edx
    930         movl    %edx, %eax
    931         jmp     1f
    932 0:
    933         incl    %eax
    934 1:
    935         cmpb    $0, (%eax)
    936         jne     0b
    937         subl    %edx, %eax
    938         ret
    939 
    940 .globl VG_(x86_darwin_REDIR_FOR_strcat)
    941 VG_(x86_darwin_REDIR_FOR_strcat):
    942         pushl   %esi
    943         movl    8(%esp), %esi
    944         movl    12(%esp), %ecx
    945         movl    %esi, %edx
    946         jmp     1f
    947 0:
    948         incl    %edx
    949 1:
    950         cmpb    $0, (%edx)
    951         jne     0b
    952 2:
    953         movzbl  (%ecx), %eax
    954         incl    %ecx
    955         movb    %al, (%edx)
    956         incl    %edx
    957         testb   %al, %al
    958         jne     2b
    959         movl    %esi, %eax
    960         popl    %esi
    961         ret
    962 
    963 
    964 .globl VG_(x86_darwin_REDIR_FOR_strcmp)
    965 VG_(x86_darwin_REDIR_FOR_strcmp):
    966         movl    4(%esp), %edx
    967         movl    8(%esp), %ecx
    968         jmp     1f
    969 0:
    970         incl    %edx
    971         incl    %ecx
    972 1:
    973         movzbl  (%edx), %eax
    974         testb   %al, %al
    975         je      2f
    976         cmpb    (%ecx), %al
    977         je      0b
    978 2:
    979         movzbl  (%ecx),%edx
    980         movzbl  %al,%eax
    981         subl    %edx, %eax
    982         ret
    983 
    984 
    985 .globl VG_(x86_darwin_REDIR_FOR_strcpy)
    986 VG_(x86_darwin_REDIR_FOR_strcpy):
    987 	pushl	%ebp
    988 	movl	%esp, %ebp
    989 	pushl	%esi
    990 	movl	8(%ebp), %esi
    991 	movl	12(%ebp), %ecx
    992 	movl	%esi, %edx
    993 	jmp	1f
    994 0:
    995 	incl	%ecx
    996 	incl	%edx
    997 1:
    998 	movzbl	(%ecx), %eax
    999 	testb	%al, %al
   1000 	movb	%al, (%edx)
   1001 	jne	0b
   1002 	movl	%esi, %eax
   1003 	popl	%esi
   1004 	leave
   1005 	ret
   1006 
   1007 .globl VG_(x86_darwin_REDIR_FOR_strlcat)
   1008 VG_(x86_darwin_REDIR_FOR_strlcat):
   1009 	pushl	%ebp
   1010 	movl	%esp, %ebp
   1011 	pushl	%edi
   1012 	pushl	%esi
   1013 	subl	$16, %esp
   1014 	movl	8(%ebp), %esi
   1015 	movl	16(%ebp), %ecx
   1016 	movl	%esi, %edx
   1017 	leal	(%ecx,%esi), %eax
   1018 	jmp	1f
   1019 0:
   1020 	incl	%edx
   1021 1:
   1022 	cmpl	%edx, %eax
   1023 	je	2f
   1024 	cmpb	$0, (%edx)
   1025 	jne	0b
   1026 2:
   1027 	movl	%edx, %edi
   1028 	subl	%esi, %edi
   1029 	movl	%ecx, %esi
   1030 	subl	%edi, %esi
   1031 	je	3f
   1032 	movl	12(%ebp), %eax
   1033 	jmp	6f
   1034 3:
   1035 	movl	12(%ebp), %eax
   1036 	movl	%eax, (%esp)
   1037 	call	VG_(x86_darwin_REDIR_FOR_strlen)
   1038 	jmp	7f
   1039 4:
   1040 	cmpl	$1, %esi
   1041 	je	5f
   1042 	movb	%cl, (%edx)
   1043 	decl	%esi
   1044 	incl	%edx
   1045 5:
   1046 	incl	%eax
   1047 6:
   1048 	movzbl	(%eax), %ecx
   1049 	testb	%cl, %cl
   1050 	jne	4b
   1051 	movb	$0, (%edx)
   1052 	subl	12(%ebp), %eax
   1053 7:
   1054 	addl	$16, %esp
   1055 	leal	(%edi,%eax), %eax
   1056 	popl	%esi
   1057 	popl	%edi
   1058 	leave
   1059 	ret
   1060 
   1061 
   1062 .globl VG_(trampoline_stuff_end)
   1063 VG_(trampoline_stuff_end):
   1064 
   1065         /* a trailing page of unexecutable code */
   1066 .fill 2048, 2, 0x0b0f /* `ud2` */
   1067 
   1068 
   1069 /*---------------- amd64-darwin ----------------*/
   1070 #else
   1071 #if defined(VGP_amd64_darwin)
   1072 
   1073         /* a leading page of unexecutable code */
   1074 .fill 2048, 2, 0x0b0f /* `ud2` */
   1075 
   1076 .globl VG_(trampoline_stuff_start)
   1077 VG_(trampoline_stuff_start):
   1078 
   1079 .globl VG_(amd64_darwin_SUBST_FOR_sigreturn)
   1080 VG_(amd64_darwin_SUBST_FOR_sigreturn):
   1081         /* XXX does this need to have any special form? (cf x86-linux
   1082 	version) */
   1083         movq    $ __NR_DARWIN_FAKE_SIGRETURN, %rax
   1084         syscall
   1085         ud2
   1086 
   1087 .globl VG_(amd64_darwin_REDIR_FOR_strlen)
   1088 VG_(amd64_darwin_REDIR_FOR_strlen):
   1089         movq    %rdi, %rax
   1090         jmp     1f
   1091 0:
   1092         incq    %rax
   1093 1:
   1094         cmpb    $0, (%rax)
   1095         jne     0b
   1096         subq    %rdi, %rax
   1097         ret
   1098 
   1099 .globl VG_(amd64_darwin_REDIR_FOR_strcat)
   1100 VG_(amd64_darwin_REDIR_FOR_strcat):
   1101 	movq	%rdi, %rdx
   1102 	jmp	1f
   1103 0:
   1104 	incq	%rdx
   1105 1:
   1106 	cmpb	$0, (%rdx)
   1107 	jne	0b
   1108 2:
   1109 	movzbl	(%rsi), %eax
   1110 	incq	%rsi
   1111 	movb	%al, (%rdx)
   1112 	incq	%rdx
   1113 	testb	%al, %al
   1114 	jne	2b
   1115 	movq	%rdi, %rax
   1116 	ret
   1117 
   1118 
   1119 .globl VG_(amd64_darwin_REDIR_FOR_strcmp)
   1120 VG_(amd64_darwin_REDIR_FOR_strcmp):
   1121 	jmp	1f
   1122 0:
   1123 	incq	%rdi
   1124 	incq	%rsi
   1125 1:
   1126 	movzbl	(%rdi), %eax
   1127 	testb	%al, %al
   1128 	je	2f
   1129 	cmpb	(%rsi), %al
   1130 	je	0b
   1131 2:
   1132 	movzbl	(%rsi), %edx
   1133 	movzbl	%al, %eax
   1134 	subl	%edx, %eax
   1135 	ret
   1136 
   1137 .globl VG_(amd64_darwin_REDIR_FOR_strcpy)
   1138 VG_(amd64_darwin_REDIR_FOR_strcpy):
   1139 	pushq	%rbp
   1140 	movq	%rdi, %rdx
   1141 	movq	%rsp, %rbp
   1142 	jmp	1f
   1143 0:
   1144 	incq	%rsi
   1145 	incq	%rdx
   1146 1:
   1147 	movzbl	(%rsi), %eax
   1148 	testb	%al, %al
   1149 	movb	%al, (%rdx)
   1150 	jne	0b
   1151 	leave
   1152 	movq	%rdi, %rax
   1153 	ret
   1154 
   1155 .globl VG_(amd64_darwin_REDIR_FOR_strlcat)
   1156 VG_(amd64_darwin_REDIR_FOR_strlcat):
   1157 	pushq	%rbp
   1158 	leaq	(%rdx,%rdi), %rax
   1159 	movq	%rdi, %rcx
   1160 	movq	%rsp, %rbp
   1161 	pushq	%rbx
   1162 	subq	$8, %rsp
   1163 	jmp	1f
   1164 0:
   1165 	incq	%rcx
   1166 1:
   1167 	cmpq	%rcx, %rax
   1168 	je	2f
   1169 	cmpb	$0, (%rcx)
   1170 	jne	0b
   1171 2:
   1172 	movq	%rcx, %rbx
   1173 	subq	%rdi, %rbx
   1174 	movq	%rdx, %rdi
   1175 	subq	%rbx, %rdi
   1176 	je	3f
   1177 	movq	%rsi, %rax
   1178 	jmp	6f
   1179 3:
   1180 	movq	%rsi, %rdi
   1181 	call	VG_(amd64_darwin_REDIR_FOR_strlen)
   1182 	jmp	7f
   1183 4:
   1184 	cmpq	$1, %rdi
   1185 	je	5f
   1186 	movb	%dl, (%rcx)
   1187 	decq	%rdi
   1188 	incq	%rcx
   1189 5:
   1190 	incq	%rax
   1191 6:
   1192 	movzbl	(%rax), %edx
   1193 	testb	%dl, %dl
   1194 	jne	4b
   1195 	movb	$0, (%rcx)
   1196 	subq	%rsi, %rax
   1197 7:
   1198 	leaq	(%rbx,%rax), %rax
   1199 	addq	$8, %rsp
   1200 	popq	%rbx
   1201 	leave
   1202 	ret
   1203 
   1204 .globl VG_(amd64_darwin_REDIR_FOR_arc4random)
   1205 VG_(amd64_darwin_REDIR_FOR_arc4random):
   1206 	/* not very random, hope dyld won't mind */
   1207 	movq	$0x76616c6772696e64, %rax
   1208 	ret
   1209 
   1210 .globl VG_(trampoline_stuff_end)
   1211 VG_(trampoline_stuff_end):
   1212 
   1213         /* a trailing page of unexecutable code */
   1214 .fill 2048, 2, 0x0b0f /* `ud2` */
   1215 
   1216 
   1217 /*---------------- unknown ----------------*/
   1218 #else
   1219 #  error Unknown platform
   1220 
   1221 #endif
   1222 #endif
   1223 #endif
   1224 #endif
   1225 #endif
   1226 #endif
   1227 #endif
   1228 #endif
   1229 
   1230 #if defined(VGO_linux)
   1231 /* Let the linker know we don't need an executable stack */
   1232 #  if defined(VGP_arm_linux)
   1233    .section .note.GNU-stack,"",%progbits
   1234 #  else
   1235    .section .note.GNU-stack,"",@progbits
   1236 #  endif
   1237 #endif
   1238 
   1239 /*--------------------------------------------------------------------*/
   1240 /*--- end                                                          ---*/
   1241 /*--------------------------------------------------------------------*/
   1242