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-2013 Julian Seward
     11      jseward (at) acm.org
     12   Copyright (C) 2006-2013 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 /* 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
    121 VG_(x86_linux_REDIR_FOR_strlen):
    122         pushl   %ebp
    123         movl    %esp, %ebp
    124         movl    8(%ebp), %edx
    125         movl    %edx, %eax
    126         jmp     2f
    127 1:      incl    %eax
    128 2:      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 
    136 .global VG_(trampoline_stuff_end)
    137 VG_(trampoline_stuff_end):
    138 
    139 	/* 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
    147 
    148 /*---------------------- amd64-linux ----------------------*/
    149 #else
    150 #if defined(VGP_amd64_linux)
    151 
    152 #	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 
    161 .global VG_(trampoline_stuff_start)
    162 VG_(trampoline_stuff_start):
    163 
    164 .global VG_(amd64_linux_SUBST_FOR_rt_sigreturn)
    165 VG_(amd64_linux_SUBST_FOR_rt_sigreturn):
    166         /* This is a very specific sequence which GDB uses to
    167            recognize signal handler frames. */
    168         movq    $__NR_rt_sigreturn, %rax
    169         syscall
    170         ud2
    171 
    172 .global VG_(amd64_linux_REDIR_FOR_vgettimeofday)
    173 .type   VG_(amd64_linux_REDIR_FOR_vgettimeofday), @function
    174 VG_(amd64_linux_REDIR_FOR_vgettimeofday):
    175 .LfnB2:
    176         movq    $__NR_gettimeofday, %rax
    177         syscall
    178         ret
    179 .LfnE2:
    180 .size VG_(amd64_linux_REDIR_FOR_vgettimeofday), .-.LfnB2
    181 
    182 .global VG_(amd64_linux_REDIR_FOR_vtime)
    183 .type   VG_(amd64_linux_REDIR_FOR_vtime), @function
    184 VG_(amd64_linux_REDIR_FOR_vtime):
    185 .LfnB3:
    186         movq    $__NR_time, %rax
    187         syscall
    188         ret
    189 .LfnE3:
    190 .size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
    191 
    192 .global VG_(amd64_linux_REDIR_FOR_vgetcpu)
    193 .type   VG_(amd64_linux_REDIR_FOR_vgetcpu), @function
    194 VG_(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 
    202 /* 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
    208 VG_(amd64_linux_REDIR_FOR_strlen):
    209 .LfnB5:
    210 	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
    220 .LfnE5:
    221 .size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
    222 
    223 
    224 /* A CIE for the above four functions, followed by their FDEs */
    225 	.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:
    262 .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:
    271 .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:
    280 	.previous
    281 
    282 .global VG_(trampoline_stuff_end)
    283 VG_(trampoline_stuff_end):
    284 
    285 	/* 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
    293 
    294 /*---------------- ppc32-linux ----------------*/
    295 #else
    296 #if defined(VGP_ppc32_linux)
    297 
    298 #	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 
    307 .global VG_(trampoline_stuff_start)
    308 VG_(trampoline_stuff_start):
    309 
    310 .global VG_(ppc32_linux_SUBST_FOR_sigreturn)
    311 VG_(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)
    317 VG_(ppc32_linux_SUBST_FOR_rt_sigreturn):
    318 	li 0,__NR_rt_sigreturn
    319         sc
    320         .long 0	/*illegal insn*/
    321 
    322 /* 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)
    327 .type   VG_(ppc32_linux_REDIR_FOR_strlen), @function
    328 VG_(ppc32_linux_REDIR_FOR_strlen):
    329         lbz 4,0(3)
    330         li 9,0
    331         cmpwi 0,4,0
    332         beq- 0,.L18
    333 .L19:
    334         lbzu 5,1(3)
    335         addi 9,9,1
    336         cmpwi 0,5,0
    337         bne+ 0,.L19
    338 .L18:
    339         mr 3,9
    340         blr
    341 .size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen)
    342 
    343 /* Ditto strcmp */
    344 .global VG_(ppc32_linux_REDIR_FOR_strcmp)
    345 .type   VG_(ppc32_linux_REDIR_FOR_strcmp), @function
    346 VG_(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
    379 .size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp)
    380 
    381 /* Ditto index/strchr */
    382 .global VG_(ppc32_linux_REDIR_FOR_strchr)
    383 .type   VG_(ppc32_linux_REDIR_FOR_strchr), @function
    384 VG_(ppc32_linux_REDIR_FOR_strchr):
    385         lbz 0,0(3)
    386         rlwinm 4,4,0,0xff
    387         cmpw 7,4,0
    388         beqlr 7
    389         cmpwi 7,0,0
    390         bne 7,.L308
    391         b .L304
    392 .L309:
    393         beq 6,.L304
    394 .L308:
    395         lbzu 0,1(3)
    396         cmpw 7,4,0
    397         cmpwi 6,0,0
    398         bne 7,.L309
    399         blr
    400 .L304:
    401         li 3,0
    402         blr
    403 .size   VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr)
    404 
    405 .global VG_(trampoline_stuff_end)
    406 VG_(trampoline_stuff_end):
    407 
    408 	/* and a trailing page of unexecutable code */
    409 	UD2_PAGE
    410 
    411 #	undef UD2_16
    412 #	undef UD2_64
    413 #	undef UD2_256
    414 #	undef UD2_1024
    415 #	undef UD2_PAGE
    416 
    417 /*---------------- ppc64-linux ----------------*/
    418 #else
    419 #if defined(VGP_ppc64_linux)
    420 
    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)
    431 VG_(trampoline_stuff_start):
    432 
    433 .global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn)
    434 VG_(ppc64_linux_SUBST_FOR_rt_sigreturn):
    435 	li 0,__NR_rt_sigreturn
    436         sc
    437         .long 0	/*illegal insn*/
    438 
    439 	/* See comment in pub_core_trampoline.h for what this is for */
    440 .global VG_(ppctoc_magic_redirect_return_stub)
    441 VG_(ppctoc_magic_redirect_return_stub):
    442 	trap
    443 
    444 	/* this function is written using the "dotless" ABI convention */
    445 	.align 2
    446 	.globl VG_(ppc64_linux_REDIR_FOR_strlen)
    447 	.section        ".opd","aw"
    448 	.align 3
    449 VG_(ppc64_linux_REDIR_FOR_strlen):
    450 	.quad   .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0
    451 	.previous
    452 	.size	VG_(ppc64_linux_REDIR_FOR_strlen), \
    453 			.L0end-.L.VG_(ppc64_linux_REDIR_FOR_strlen)
    454 	.type	VG_(ppc64_linux_REDIR_FOR_strlen), @function
    455 
    456 .L.VG_(ppc64_linux_REDIR_FOR_strlen):
    457         mr 9,3
    458         lbz 0,0(3)
    459         li 3,0
    460         cmpwi 7,0,0
    461         beqlr 7
    462         li 3,0
    463 .L01:
    464         addi 0,3,1
    465         extsw 3,0
    466         lbzx 0,9,3
    467         cmpwi 7,0,0
    468         bne 7,.L01
    469         blr
    470         .long 0
    471         .byte 0,0,0,0,0,0,0,0
    472 .L0end:
    473 
    474         /* this function is written using the "dotless" ABI convention */
    475         .align 2
    476         .globl VG_(ppc64_linux_REDIR_FOR_strchr)
    477 	.section        ".opd","aw"
    478 	.align 3
    479 VG_(ppc64_linux_REDIR_FOR_strchr):
    480         .quad   .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0
    481         .previous
    482         .size   VG_(ppc64_linux_REDIR_FOR_strchr), \
    483                         .L1end-.L.VG_(ppc64_linux_REDIR_FOR_strchr)
    484         .type   VG_(ppc64_linux_REDIR_FOR_strchr),@function
    485 
    486 .L.VG_(ppc64_linux_REDIR_FOR_strchr):
    487         lbz 0,0(3)
    488         rldicl 4,4,0,56
    489         cmpw 7,4,0
    490         beqlr 7
    491         cmpdi 7,0,0
    492         bne 7,.L18
    493         b .L14
    494 .L19:
    495         beq 6,.L14
    496 .L18:
    497         lbzu 0,1(3)
    498         cmpw 7,4,0
    499         cmpdi 6,0,0
    500         bne 7,.L19
    501         blr
    502 .L14:
    503         li 3,0
    504         blr
    505         .long 0
    506         .byte 0,0,0,0,0,0,0,0
    507 .L1end:
    508 
    509 
    510 .global VG_(trampoline_stuff_end)
    511 VG_(trampoline_stuff_end):
    512 
    513 	/* and a trailing page of unexecutable code */
    514 	UD2_PAGE
    515 
    516 #	undef UD2_16
    517 #	undef UD2_64
    518 #	undef UD2_256
    519 #	undef UD2_1024
    520 #	undef UD2_PAGE
    521 
    522 /*---------------- arm-linux ----------------*/
    523 #else
    524 #if defined(VGP_arm_linux)
    525 
    526 #       define UD2_4      .word 0xFFFFFFFF
    527 #	define UD2_16     UD2_4    ; UD2_4    ; UD2_4    ; UD2_4
    528 #	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
    529 #	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
    530 #	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
    531 #	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
    532 
    533 	/* a leading page of unexecutable code */
    534 	UD2_PAGE
    535 
    536 .global VG_(trampoline_stuff_start)
    537 VG_(trampoline_stuff_start):
    538 
    539 .global VG_(arm_linux_SUBST_FOR_sigreturn)
    540 .type   VG_(arm_linux_SUBST_FOR_sigreturn),#function
    541 VG_(arm_linux_SUBST_FOR_sigreturn):
    542 	mov r7, # __NR_sigreturn
    543         svc #0
    544         .long 0xFFFFFFFF /*illegal insn*/
    545 .size VG_(arm_linux_SUBST_FOR_sigreturn), .-VG_(arm_linux_SUBST_FOR_sigreturn)
    546 
    547 .global VG_(arm_linux_SUBST_FOR_rt_sigreturn)
    548 .type   VG_(arm_linux_SUBST_FOR_rt_sigreturn),#function
    549 VG_(arm_linux_SUBST_FOR_rt_sigreturn):
    550 	mov r7, # __NR_rt_sigreturn
    551         svc #0
    552         .long 0xFFFFFFFF /*illegal insn*/
    553 .size VG_(arm_linux_SUBST_FOR_rt_sigreturn), .-VG_(arm_linux_SUBST_FOR_rt_sigreturn)
    554 
    555 .global VG_(arm_linux_REDIR_FOR_strlen)
    556 VG_(arm_linux_REDIR_FOR_strlen):
    557 	mov	r2, r0
    558 	ldrb	r0, [r0, #0]	@ zero_extendqisi2
    559 	@ lr needed for prologue
    560 	cmp	r0, #0
    561 	bxeq	lr
    562 	mov	r0, #0
    563 .L5:
    564 	add	r0, r0, #1
    565 	ldrb	r3, [r0, r2]	@ zero_extendqisi2
    566 	cmp	r3, #0
    567 	bne	.L5
    568 	bx	lr
    569 	UD2_4
    570 
    571 //.global VG_(arm_linux_REDIR_FOR_index)
    572 //VG_(arm_linux_REDIR_FOR_index):
    573 //	ldrb	r3, [r0, #0]	@ zero_extendqisi2
    574 //	and	r1, r1, #255
    575 //	cmp	r3, r1
    576 //	@ lr needed for prologue
    577 //	bne	.L9
    578 //	bx	lr
    579 //.L12:
    580 //	ldrb	r3, [r0, #1]!	@ zero_extendqisi2
    581 //	cmp	r3, r1
    582 //	beq	.L11
    583 //.L9:
    584 //	cmp	r3, #0
    585 //	bne	.L12
    586 //	mov	r0, #0
    587 //	bx	lr
    588 //.L11:
    589 //	bx	lr
    590 //	UD2_4
    591 
    592 .global VG_(arm_linux_REDIR_FOR_memcpy)
    593 VG_(arm_linux_REDIR_FOR_memcpy):
    594 	stmfd	sp!, {r4, r5, lr}
    595 	subs	lr, r2, #0
    596 	mov	r5, r0
    597 	beq	.L2
    598 	cmp	r0, r1
    599 	bls	.L4
    600 	add	r3, r0, lr
    601 	add	r1, lr, r1
    602 	cmp	lr, #3
    603 	sub	r4, r3, #1
    604 	sub	r0, r1, #1
    605 	ble	.L28
    606 	sub	ip, r3, #5
    607 	sub	r1, r1, #5
    608 .L8:
    609 	ldrb	r3, [r1, #4]	@ zero_extendqisi2
    610 	sub	lr, lr, #4
    611 	strb	r3, [ip, #4]
    612 	ldrb	r2, [r1, #3]	@ zero_extendqisi2
    613 	cmp	lr, #3
    614 	strb	r2, [ip, #3]
    615 	ldrb	r3, [r1, #2]	@ zero_extendqisi2
    616 	mov	r4, ip
    617 	strb	r3, [ip, #2]
    618 	ldrb	r2, [r1, #1]	@ zero_extendqisi2
    619 	mov	r0, r1
    620 	strb	r2, [ip, #1]
    621 	sub	r1, r1, #4
    622 	sub	ip, ip, #4
    623 	bgt	.L8
    624 	cmp	lr, #0
    625 	beq	.L2
    626 .L28:
    627 	sub	r2, lr, #1
    628 .L21:
    629 	sub	r2, r2, #1
    630 	ldrb	r3, [r0], #-1	@ zero_extendqisi2
    631 	cmn	r2, #1
    632 	strb	r3, [r4], #-1
    633 	bne	.L21
    634 .L2:
    635 	mov	r0, r5
    636 	ldmfd	sp!, {r4, r5, pc}
    637 .L4:
    638 	bcs	.L2
    639 	cmp	lr, #3
    640 	mov	ip, r0
    641 	ble	.L29
    642 .L19:
    643 	ldrb	r3, [r1, #0]	@ zero_extendqisi2
    644 	sub	lr, lr, #4
    645 	strb	r3, [ip, #0]
    646 	ldrb	r2, [r1, #1]	@ zero_extendqisi2
    647 	cmp	lr, #3
    648 	strb	r2, [ip, #1]
    649 	ldrb	r3, [r1, #2]	@ zero_extendqisi2
    650 	strb	r3, [ip, #2]
    651 	ldrb	r2, [r1, #3]	@ zero_extendqisi2
    652 	add	r1, r1, #4
    653 	strb	r2, [ip, #3]
    654 	add	ip, ip, #4
    655 	bgt	.L19
    656 	cmp	lr, #0
    657 	beq	.L2
    658 .L29:
    659 	sub	r2, lr, #1
    660 .L20:
    661 	sub	r2, r2, #1
    662 	ldrb	r3, [r1], #1	@ zero_extendqisi2
    663 	cmn	r2, #1
    664 	strb	r3, [ip], #1
    665 	bne	.L20
    666 	mov	r0, r5
    667 	ldmfd	sp!, {r4, r5, pc}
    668 	UD2_4
    669 
    670 .global VG_(trampoline_stuff_end)
    671 VG_(trampoline_stuff_end):
    672 
    673 	/* and a trailing page of unexecutable code */
    674 	UD2_PAGE
    675 
    676 #	undef UD2_4
    677 #	undef UD2_16
    678 #	undef UD2_64
    679 #	undef UD2_256
    680 #	undef UD2_1024
    681 #	undef UD2_PAGE
    682 
    683 /*---------------- arm64-linux ----------------*/
    684 #else
    685 #if defined(VGP_arm64_linux)
    686 
    687 #       define UD2_4      .word 0xFFFFFFFF
    688 #	define UD2_16     UD2_4    ; UD2_4    ; UD2_4    ; UD2_4
    689 #	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
    690 #	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
    691 #	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
    692 #	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
    693 
    694 	/* a leading page of unexecutable code */
    695 	UD2_PAGE
    696 
    697 .global VG_(trampoline_stuff_start)
    698 VG_(trampoline_stuff_start):
    699 
    700 .global VG_(arm64_linux_SUBST_FOR_rt_sigreturn)
    701 .type   VG_(arm64_linux_SUBST_FOR_rt_sigreturn),#function
    702 VG_(arm64_linux_SUBST_FOR_rt_sigreturn):
    703 	mov x8, # __NR_rt_sigreturn
    704         svc #0
    705         .long 0xFFFFFFFF /*illegal insn*/
    706 .size VG_(arm64_linux_SUBST_FOR_rt_sigreturn), \
    707         .-VG_(arm64_linux_SUBST_FOR_rt_sigreturn)
    708 
    709 .global VG_(arm64_linux_REDIR_FOR_strlen)
    710 .type   VG_(arm64_linux_REDIR_FOR_strlen),#function
    711 VG_(arm64_linux_REDIR_FOR_strlen):
    712 	mov	x2, x0
    713 	ldrb	w0, [x0]
    714 	cbz	w0, .L5
    715 	mov	x0, 0
    716 .L4:
    717 	add	x0, x0, 1
    718 	ldrb	w1, [x2,x0]
    719 	cbnz	w1, .L4
    720 	ret
    721 .L5:
    722 	mov	x0, 0
    723 	ret
    724 .size VG_(arm64_linux_REDIR_FOR_strlen), .-VG_(arm64_linux_REDIR_FOR_strlen)
    725 
    726 .global VG_(arm64_linux_REDIR_FOR_index)
    727 .type   VG_(arm64_linux_REDIR_FOR_index),#function
    728 VG_(arm64_linux_REDIR_FOR_index):
    729         ldrb    w2, [x0]
    730         uxtb    w1, w1
    731         cmp     w2, w1
    732         beq     .L11
    733 .L13:
    734         cbz     w2, .L16
    735         ldrb    w2, [x0,1]!
    736         cmp     w2, w1
    737         bne     .L13
    738 .L11:
    739         ret
    740 .L16:
    741         mov     x0, 0
    742         ret
    743 .size VG_(arm64_linux_REDIR_FOR_index), .-VG_(arm64_linux_REDIR_FOR_index)
    744 
    745 .global VG_(arm64_linux_REDIR_FOR_strcmp)
    746 .type   VG_(arm64_linux_REDIR_FOR_strcmp),#function
    747 VG_(arm64_linux_REDIR_FOR_strcmp):
    748         ldrb    w2, [x0]
    749         ldrb    w3, [x1]
    750         cmp     w2, w3
    751         bcc     .L22
    752 .L21:
    753         bhi     .L25
    754         cbz     w2, .L26
    755         ldrb    w2, [x0,1]!
    756         ldrb    w3, [x1,1]!
    757         cmp     w2, w3
    758         bcs     .L21
    759 .L22:
    760         mov     x0, -1
    761         ret
    762 .L25:
    763         mov     x0, 1
    764         ret
    765 .L26:
    766         mov     x0, 0
    767         ret
    768 .size VG_(arm64_linux_REDIR_FOR_strcmp), .-VG_(arm64_linux_REDIR_FOR_strcmp)
    769 
    770 .global VG_(trampoline_stuff_end)
    771 VG_(trampoline_stuff_end):
    772 
    773 	/* and a trailing page of unexecutable code */
    774 	UD2_PAGE
    775 
    776 #	undef UD2_4
    777 #	undef UD2_16
    778 #	undef UD2_64
    779 #	undef UD2_256
    780 #	undef UD2_1024
    781 #	undef UD2_PAGE
    782 
    783 /*---------------- x86-darwin ----------------*/
    784 #else
    785 #if defined(VGP_x86_darwin)
    786 
    787         /* a leading page of unexecutable code */
    788 .fill 2048, 2, 0x0b0f /* `ud2` */
    789 
    790 .globl VG_(trampoline_stuff_start)
    791 VG_(trampoline_stuff_start):
    792 
    793 .globl VG_(x86_darwin_SUBST_FOR_sigreturn)
    794 VG_(x86_darwin_SUBST_FOR_sigreturn):
    795         /* XXX does this need to have any special form? (cf x86-linux
    796 	version) */
    797         movl    $ __NR_DARWIN_FAKE_SIGRETURN, %eax
    798         int     $0x80
    799         ud2
    800 
    801 .globl VG_(x86_darwin_REDIR_FOR_strlen)
    802 VG_(x86_darwin_REDIR_FOR_strlen):
    803         movl    4(%esp), %edx
    804         movl    %edx, %eax
    805         jmp     1f
    806 0:
    807         incl    %eax
    808 1:
    809         cmpb    $0, (%eax)
    810         jne     0b
    811         subl    %edx, %eax
    812         ret
    813 
    814 .globl VG_(x86_darwin_REDIR_FOR_strcat)
    815 VG_(x86_darwin_REDIR_FOR_strcat):
    816         pushl   %esi
    817         movl    8(%esp), %esi
    818         movl    12(%esp), %ecx
    819         movl    %esi, %edx
    820         jmp     1f
    821 0:
    822         incl    %edx
    823 1:
    824         cmpb    $0, (%edx)
    825         jne     0b
    826 2:
    827         movzbl  (%ecx), %eax
    828         incl    %ecx
    829         movb    %al, (%edx)
    830         incl    %edx
    831         testb   %al, %al
    832         jne     2b
    833         movl    %esi, %eax
    834         popl    %esi
    835         ret
    836 
    837 
    838 .globl VG_(x86_darwin_REDIR_FOR_strcmp)
    839 VG_(x86_darwin_REDIR_FOR_strcmp):
    840         movl    4(%esp), %edx
    841         movl    8(%esp), %ecx
    842         jmp     1f
    843 0:
    844         incl    %edx
    845         incl    %ecx
    846 1:
    847         movzbl  (%edx), %eax
    848         testb   %al, %al
    849         je      2f
    850         cmpb    (%ecx), %al
    851         je      0b
    852 2:
    853         movzbl  (%ecx),%edx
    854         movzbl  %al,%eax
    855         subl    %edx, %eax
    856         ret
    857 
    858 
    859 .globl VG_(x86_darwin_REDIR_FOR_strcpy)
    860 VG_(x86_darwin_REDIR_FOR_strcpy):
    861 	pushl	%ebp
    862 	movl	%esp, %ebp
    863 	pushl	%esi
    864 	movl	8(%ebp), %esi
    865 	movl	12(%ebp), %ecx
    866 	movl	%esi, %edx
    867 	jmp	1f
    868 0:
    869 	incl	%ecx
    870 	incl	%edx
    871 1:
    872 	movzbl	(%ecx), %eax
    873 	testb	%al, %al
    874 	movb	%al, (%edx)
    875 	jne	0b
    876 	movl	%esi, %eax
    877 	popl	%esi
    878 	leave
    879 	ret
    880 
    881 .globl VG_(x86_darwin_REDIR_FOR_strlcat)
    882 VG_(x86_darwin_REDIR_FOR_strlcat):
    883 	pushl	%ebp
    884 	movl	%esp, %ebp
    885 	pushl	%edi
    886 	pushl	%esi
    887 	subl	$16, %esp
    888 	movl	8(%ebp), %esi
    889 	movl	16(%ebp), %ecx
    890 	movl	%esi, %edx
    891 	leal	(%ecx,%esi), %eax
    892 	jmp	1f
    893 0:
    894 	incl	%edx
    895 1:
    896 	cmpl	%edx, %eax
    897 	je	2f
    898 	cmpb	$0, (%edx)
    899 	jne	0b
    900 2:
    901 	movl	%edx, %edi
    902 	subl	%esi, %edi
    903 	movl	%ecx, %esi
    904 	subl	%edi, %esi
    905 	je	3f
    906 	movl	12(%ebp), %eax
    907 	jmp	6f
    908 3:
    909 	movl	12(%ebp), %eax
    910 	movl	%eax, (%esp)
    911 	call	VG_(x86_darwin_REDIR_FOR_strlen)
    912 	jmp	7f
    913 4:
    914 	cmpl	$1, %esi
    915 	je	5f
    916 	movb	%cl, (%edx)
    917 	decl	%esi
    918 	incl	%edx
    919 5:
    920 	incl	%eax
    921 6:
    922 	movzbl	(%eax), %ecx
    923 	testb	%cl, %cl
    924 	jne	4b
    925 	movb	$0, (%edx)
    926 	subl	12(%ebp), %eax
    927 7:
    928 	addl	$16, %esp
    929 	leal	(%edi,%eax), %eax
    930 	popl	%esi
    931 	popl	%edi
    932 	leave
    933 	ret
    934 
    935 
    936 .globl VG_(trampoline_stuff_end)
    937 VG_(trampoline_stuff_end):
    938 
    939         /* a trailing page of unexecutable code */
    940 .fill 2048, 2, 0x0b0f /* `ud2` */
    941 
    942 
    943 /*---------------- amd64-darwin ----------------*/
    944 #else
    945 #if defined(VGP_amd64_darwin)
    946 
    947         /* a leading page of unexecutable code */
    948 .fill 2048, 2, 0x0b0f /* `ud2` */
    949 
    950 .globl VG_(trampoline_stuff_start)
    951 VG_(trampoline_stuff_start):
    952 
    953 .globl VG_(amd64_darwin_SUBST_FOR_sigreturn)
    954 VG_(amd64_darwin_SUBST_FOR_sigreturn):
    955         /* XXX does this need to have any special form? (cf x86-linux
    956 	version) */
    957         movq    $ __NR_DARWIN_FAKE_SIGRETURN, %rax
    958         syscall
    959         ud2
    960 
    961 .globl VG_(amd64_darwin_REDIR_FOR_strlen)
    962 VG_(amd64_darwin_REDIR_FOR_strlen):
    963         movq    %rdi, %rax
    964         jmp     1f
    965 0:
    966         incq    %rax
    967 1:
    968         cmpb    $0, (%rax)
    969         jne     0b
    970         subq    %rdi, %rax
    971         ret
    972 
    973 .globl VG_(amd64_darwin_REDIR_FOR_strcat)
    974 VG_(amd64_darwin_REDIR_FOR_strcat):
    975 	movq	%rdi, %rdx
    976 	jmp	1f
    977 0:
    978 	incq	%rdx
    979 1:
    980 	cmpb	$0, (%rdx)
    981 	jne	0b
    982 2:
    983 	movzbl	(%rsi), %eax
    984 	incq	%rsi
    985 	movb	%al, (%rdx)
    986 	incq	%rdx
    987 	testb	%al, %al
    988 	jne	2b
    989 	movq	%rdi, %rax
    990 	ret
    991 
    992 
    993 .globl VG_(amd64_darwin_REDIR_FOR_strcmp)
    994 VG_(amd64_darwin_REDIR_FOR_strcmp):
    995 	jmp	1f
    996 0:
    997 	incq	%rdi
    998 	incq	%rsi
    999 1:
   1000 	movzbl	(%rdi), %eax
   1001 	testb	%al, %al
   1002 	je	2f
   1003 	cmpb	(%rsi), %al
   1004 	je	0b
   1005 2:
   1006 	movzbl	(%rsi), %edx
   1007 	movzbl	%al, %eax
   1008 	subl	%edx, %eax
   1009 	ret
   1010 
   1011 .globl VG_(amd64_darwin_REDIR_FOR_strcpy)
   1012 VG_(amd64_darwin_REDIR_FOR_strcpy):
   1013 	pushq	%rbp
   1014 	movq	%rdi, %rdx
   1015 	movq	%rsp, %rbp
   1016 	jmp	1f
   1017 0:
   1018 	incq	%rsi
   1019 	incq	%rdx
   1020 1:
   1021 	movzbl	(%rsi), %eax
   1022 	testb	%al, %al
   1023 	movb	%al, (%rdx)
   1024 	jne	0b
   1025 	leave
   1026 	movq	%rdi, %rax
   1027 	ret
   1028 
   1029 .globl VG_(amd64_darwin_REDIR_FOR_strlcat)
   1030 VG_(amd64_darwin_REDIR_FOR_strlcat):
   1031 	pushq	%rbp
   1032 	leaq	(%rdx,%rdi), %rax
   1033 	movq	%rdi, %rcx
   1034 	movq	%rsp, %rbp
   1035 	pushq	%rbx
   1036 	subq	$8, %rsp
   1037 	jmp	1f
   1038 0:
   1039 	incq	%rcx
   1040 1:
   1041 	cmpq	%rcx, %rax
   1042 	je	2f
   1043 	cmpb	$0, (%rcx)
   1044 	jne	0b
   1045 2:
   1046 	movq	%rcx, %rbx
   1047 	subq	%rdi, %rbx
   1048 	movq	%rdx, %rdi
   1049 	subq	%rbx, %rdi
   1050 	je	3f
   1051 	movq	%rsi, %rax
   1052 	jmp	6f
   1053 3:
   1054 	movq	%rsi, %rdi
   1055 	call	VG_(amd64_darwin_REDIR_FOR_strlen)
   1056 	jmp	7f
   1057 4:
   1058 	cmpq	$1, %rdi
   1059 	je	5f
   1060 	movb	%dl, (%rcx)
   1061 	decq	%rdi
   1062 	incq	%rcx
   1063 5:
   1064 	incq	%rax
   1065 6:
   1066 	movzbl	(%rax), %edx
   1067 	testb	%dl, %dl
   1068 	jne	4b
   1069 	movb	$0, (%rcx)
   1070 	subq	%rsi, %rax
   1071 7:
   1072 	leaq	(%rbx,%rax), %rax
   1073 	addq	$8, %rsp
   1074 	popq	%rbx
   1075 	leave
   1076 	ret
   1077 
   1078 .globl VG_(amd64_darwin_REDIR_FOR_arc4random)
   1079 VG_(amd64_darwin_REDIR_FOR_arc4random):
   1080 	/* not very random, hope dyld won't mind */
   1081 	movq	$0x76616c6772696e64, %rax
   1082 	ret
   1083 
   1084 .globl VG_(trampoline_stuff_end)
   1085 VG_(trampoline_stuff_end):
   1086 
   1087         /* a trailing page of unexecutable code */
   1088 .fill 2048, 2, 0x0b0f /* `ud2` */
   1089 
   1090 
   1091 /*---------------- s390x-linux ----------------*/
   1092 #else
   1093 #if defined(VGP_s390x_linux)
   1094 
   1095         /* a leading page of unexecutable code */
   1096 	.fill 2048, 2, 0x0000
   1097 
   1098 .global VG_(trampoline_stuff_start)
   1099 VG_(trampoline_stuff_start):
   1100 
   1101 .global VG_(s390x_linux_SUBST_FOR_sigreturn)
   1102 VG_(s390x_linux_SUBST_FOR_sigreturn):
   1103         svc __NR_sigreturn
   1104 	.short 0
   1105 
   1106 .global VG_(s390x_linux_SUBST_FOR_rt_sigreturn)
   1107 VG_(s390x_linux_SUBST_FOR_rt_sigreturn):
   1108         /* Old gcc unwinding code checks for a sig(_rt)_return svc and then
   1109            for ra = cfa to decide if it is a sig_rt_frame or not. Since we
   1110            set ra to this trampoline, but the cfa is still in the stack,
   1111            the unwinder thinks, that this is a non-rt frame  and causes a
   1112            crash in the gcc unwinder - which is used by the thread library
   1113            and others. Therefore we add a lr 1,1 nop, to let the gcc
   1114            unwinder bail out gracefully. This might also affect unwinding
   1115            across the signal frame - tough luck. fixs390 */
   1116         lr 1,1
   1117         svc __NR_rt_sigreturn
   1118 	.short 0
   1119 
   1120 .globl VG_(trampoline_stuff_end)
   1121 VG_(trampoline_stuff_end):
   1122 	.fill 2048, 2, 0x0000
   1123 
   1124 /*---------------------- mips32-linux ----------------------*/
   1125 #else
   1126 #if defined(VGP_mips32_linux)
   1127 
   1128 #	define UD2_16     trap ; trap ; trap; trap
   1129 #	define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
   1130 #	define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
   1131 #	define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
   1132 #	define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
   1133 
   1134 
   1135 .global VG_(trampoline_stuff_start)
   1136 VG_(trampoline_stuff_start):
   1137 
   1138 .global VG_(mips32_linux_SUBST_FOR_sigreturn)
   1139 VG_(mips32_linux_SUBST_FOR_sigreturn):
   1140         li $v0,__NR_sigreturn
   1141         syscall
   1142         nop
   1143         .long 0	/*illegal insn*/
   1144 
   1145 .global VG_(mips32_linux_SUBST_FOR_rt_sigreturn)
   1146 VG_(mips32_linux_SUBST_FOR_rt_sigreturn):
   1147 	li $v0,__NR_rt_sigreturn
   1148         syscall
   1149         nop
   1150         .long 0	/*illegal insn*/
   1151 
   1152 /* There's no particular reason that this needs to be handwritten
   1153    assembly, but since that's what this file contains, here's a
   1154    simple strlen implementation (written in C and compiled by gcc.)
   1155 */
   1156 .global VG_(mips32_linux_REDIR_FOR_strlen)
   1157 .type   VG_(mips32_linux_REDIR_FOR_strlen), @function
   1158 VG_(mips32_linux_REDIR_FOR_strlen):
   1159       li $v0, 0
   1160       //la $a0, string
   1161       j strlen_cond
   1162    strlen_loop:
   1163       addi $v0, $v0, 1
   1164       addi $a0, $a0, 1
   1165    strlen_cond:
   1166       lbu $t0, ($a0)
   1167       bne $t0, $zero, strlen_loop
   1168     jr $ra
   1169 
   1170 .size VG_(mips32_linux_REDIR_FOR_strlen), .-VG_(mips32_linux_REDIR_FOR_strlen)
   1171 
   1172 .global VG_(trampoline_stuff_end)
   1173 VG_(trampoline_stuff_end):
   1174 
   1175 
   1176 #	undef UD2_16
   1177 #	undef UD2_64
   1178 #	undef UD2_256
   1179 #	undef UD2_1024
   1180 #	undef UD2_PAGE
   1181 
   1182 /*---------------------- mips64-linux ----------------------*/
   1183 #else
   1184 #if defined(VGP_mips64_linux)
   1185 
   1186 #       define UD2_16     trap ; trap ; trap; trap
   1187 #       define UD2_64     UD2_16   ; UD2_16   ; UD2_16   ; UD2_16
   1188 #       define UD2_256    UD2_64   ; UD2_64   ; UD2_64   ; UD2_64
   1189 #       define UD2_1024   UD2_256  ; UD2_256  ; UD2_256  ; UD2_256
   1190 #       define UD2_PAGE   UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
   1191 
   1192 .global VG_(trampoline_stuff_start)
   1193 VG_(trampoline_stuff_start):
   1194 
   1195 .global VG_(mips64_linux_SUBST_FOR_rt_sigreturn)
   1196 VG_(mips64_linux_SUBST_FOR_rt_sigreturn):
   1197         li $2,__NR_rt_sigreturn
   1198         syscall
   1199         nop
   1200         .long 0	/*illegal insn*/
   1201 
   1202 /* There's no particular reason that this needs to be handwritten
   1203    assembly, but since that's what this file contains, here's a
   1204    simple strlen implementation (written in C and compiled by gcc.)
   1205 */
   1206 .global VG_(mips64_linux_REDIR_FOR_strlen)
   1207 .type   VG_(mips64_linux_REDIR_FOR_strlen), @function
   1208 VG_(mips64_linux_REDIR_FOR_strlen):
   1209         lbu $12, 0($4)
   1210         li  $13, 0
   1211         beq $12, $0, M01
   1212         nop
   1213 
   1214 M02:
   1215         addiu $13, $13, 1
   1216         addiu $4, $4, 1
   1217         lbu $12, 0($4)
   1218         bne $12, $0, M02
   1219         nop
   1220 
   1221 M01:
   1222         move $2, $13
   1223         jr $31
   1224         nop
   1225 
   1226 .size VG_(mips64_linux_REDIR_FOR_strlen), .-VG_(mips64_linux_REDIR_FOR_strlen)
   1227 
   1228 .global VG_(trampoline_stuff_end)
   1229 VG_(trampoline_stuff_end):
   1230 
   1231 
   1232 #	undef UD2_16
   1233 #	undef UD2_64
   1234 #	undef UD2_256
   1235 #	undef UD2_1024
   1236 #	undef UD2_PAGE
   1237 
   1238 /*---------------- unknown ----------------*/
   1239 #else
   1240 #  error Unknown platform
   1241 
   1242 #endif
   1243 #endif
   1244 #endif
   1245 #endif
   1246 #endif
   1247 #endif
   1248 #endif
   1249 #endif
   1250 #endif
   1251 #endif
   1252 #endif
   1253 
   1254 #if defined(VGO_linux)
   1255 /* Let the linker know we don't need an executable stack */
   1256 #  if defined(VGP_arm_linux)
   1257    .section .note.GNU-stack,"",%progbits
   1258 #  else
   1259    .section .note.GNU-stack,"",@progbits
   1260 #  endif
   1261 #endif
   1262 
   1263 /*--------------------------------------------------------------------*/
   1264 /*--- end                                                          ---*/
   1265 /*--------------------------------------------------------------------*/
   1266