m_trampoline.S revision 8f943afc22a6a683b78271836c8ddc462b4824a9
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-2011 Julian Seward 11 jseward@acm.org 12 Copyright (C) 2006-2011 OpenWorks LLP 13 info@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) 55VG_(trampoline_stuff_start): 56 57.global VG_(x86_linux_SUBST_FOR_sigreturn) 58VG_(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) 69VG_(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 92VG_(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 121VG_(x86_linux_REDIR_FOR_strlen): 122 pushl %ebp 123 movl %esp, %ebp 124 movl 8(%ebp), %edx 125 movl %edx, %eax 126 jmp 2f 1271: incl %eax 1282: cmpb $0, (%eax) 129 jne 1b 130 subl %edx, %eax 131 popl %ebp 132 ret 133.size VG_(x86_linux_REDIR_FOR_strlen), .-VG_(x86_linux_REDIR_FOR_strlen) 134 135 136.global VG_(trampoline_stuff_end) 137VG_(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) 162VG_(trampoline_stuff_start): 163 164.global VG_(amd64_linux_SUBST_FOR_rt_sigreturn) 165VG_(amd64_linux_SUBST_FOR_rt_sigreturn): 166 /* This is a very specific sequence which GDB uses to 167 recognize signal handler frames. */ 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 174VG_(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 184VG_(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/* There's no particular reason that this needs to be handwritten 193 assembly, but since that's what this file contains, here's a 194 simple strlen implementation (written in C and compiled by gcc.) 195*/ 196.global VG_(amd64_linux_REDIR_FOR_strlen) 197.type VG_(amd64_linux_REDIR_FOR_strlen), @function 198VG_(amd64_linux_REDIR_FOR_strlen): 199.LfnB4: 200 xorl %eax, %eax 201 cmpb $0, (%rdi) 202 movq %rdi, %rdx 203 je .L41 204.L40: addq $1, %rdx 205 cmpb $0, (%rdx) 206 jne .L40 207 movq %rdx, %rax 208 subq %rdi, %rax 209.L41: ret 210.LfnE4: 211.size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen) 212 213 214/* A CIE for the above three functions, followed by their FDEs */ 215 .section .eh_frame,"a",@progbits 216.Lframe1: 217 .long .LEcie1-.LScie1 218.LScie1: 219 .long 0x0 220 .byte 0x1 221 .string "zR" 222 .uleb128 0x1 223 .sleb128 -8 224 .byte 0x10 225 .uleb128 0x1 226 .byte 0x3 227 .byte 0xc 228 .uleb128 0x7 229 .uleb128 0x8 230 .byte 0x90 231 .uleb128 0x1 232 .align 8 233.LEcie1: 234.LSfde2: 235 .long .LEfde2-.LASfde2 236.LASfde2: 237 .long .LASfde2-.Lframe1 238 .long .LfnB2 239 .long .LfnE2-.LfnB2 240 .uleb128 0x0 241 .align 8 242.LEfde2: 243.LSfde3: 244 .long .LEfde3-.LASfde3 245.LASfde3: 246 .long .LASfde3-.Lframe1 247 .long .LfnB3 248 .long .LfnE3-.LfnB3 249 .uleb128 0x0 250 .align 8 251.LEfde3: 252.LSfde4: 253 .long .LEfde4-.LASfde4 254.LASfde4: 255 .long .LASfde4-.Lframe1 256 .long .LfnB4 257 .long .LfnE4-.LfnB4 258 .uleb128 0x0 259 .align 8 260.LEfde4: 261 .previous 262 263.global VG_(trampoline_stuff_end) 264VG_(trampoline_stuff_end): 265 266 /* and a trailing page of unexecutable code */ 267 UD2_PAGE 268 269# undef UD2_16 270# undef UD2_64 271# undef UD2_256 272# undef UD2_1024 273# undef UD2_PAGE 274 275/*---------------- ppc32-linux ----------------*/ 276#else 277#if defined(VGP_ppc32_linux) 278 279# define UD2_16 trap ; trap ; trap; trap 280# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 281# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64 282# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256 283# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024 284 285 /* a leading page of unexecutable code */ 286 UD2_PAGE 287 288.global VG_(trampoline_stuff_start) 289VG_(trampoline_stuff_start): 290 291.global VG_(ppc32_linux_SUBST_FOR_sigreturn) 292VG_(ppc32_linux_SUBST_FOR_sigreturn): 293 li 0,__NR_sigreturn 294 sc 295 .long 0 /*illegal insn*/ 296 297.global VG_(ppc32_linux_SUBST_FOR_rt_sigreturn) 298VG_(ppc32_linux_SUBST_FOR_rt_sigreturn): 299 li 0,__NR_rt_sigreturn 300 sc 301 .long 0 /*illegal insn*/ 302 303/* There's no particular reason that this needs to be handwritten 304 assembly, but since that's what this file contains, here's a 305 simple strlen implementation (written in C and compiled by gcc.) 306*/ 307.global VG_(ppc32_linux_REDIR_FOR_strlen) 308.type VG_(ppc32_linux_REDIR_FOR_strlen), @function 309VG_(ppc32_linux_REDIR_FOR_strlen): 310 lbz 4,0(3) 311 li 9,0 312 cmpwi 0,4,0 313 beq- 0,.L18 314.L19: 315 lbzu 5,1(3) 316 addi 9,9,1 317 cmpwi 0,5,0 318 bne+ 0,.L19 319.L18: 320 mr 3,9 321 blr 322.size VG_(ppc32_linux_REDIR_FOR_strlen), .-VG_(ppc32_linux_REDIR_FOR_strlen) 323 324/* Ditto strcmp */ 325.global VG_(ppc32_linux_REDIR_FOR_strcmp) 326.type VG_(ppc32_linux_REDIR_FOR_strcmp), @function 327VG_(ppc32_linux_REDIR_FOR_strcmp): 328.L20: 329 lbz 0,0(3) 330 cmpwi 7,0,0 331 bne- 7,.L21 332 lbz 0,0(4) 333 li 11,0 334 cmpwi 7,0,0 335 beq- 7,.L22 336.L21: 337 lbz 0,0(3) 338 li 11,-1 339 cmpwi 7,0,0 340 beq- 7,.L22 341 lbz 0,0(4) 342 li 11,1 343 cmpwi 7,0,0 344 beq- 7,.L22 345 lbz 9,0(3) 346 lbz 0,0(4) 347 li 11,-1 348 cmplw 7,9,0 349 blt- 7,.L22 350 lbz 9,0(3) 351 lbz 0,0(4) 352 li 11,1 353 addi 3,3,1 354 addi 4,4,1 355 cmplw 7,9,0 356 ble+ 7,.L20 357.L22: 358 mr 3,11 359 blr 360.size VG_(ppc32_linux_REDIR_FOR_strcmp), .-VG_(ppc32_linux_REDIR_FOR_strcmp) 361 362/* Ditto index/strchr */ 363.global VG_(ppc32_linux_REDIR_FOR_strchr) 364.type VG_(ppc32_linux_REDIR_FOR_strchr), @function 365VG_(ppc32_linux_REDIR_FOR_strchr): 366 lbz 0,0(3) 367 rlwinm 4,4,0,0xff 368 cmpw 7,4,0 369 beqlr 7 370 cmpwi 7,0,0 371 bne 7,.L308 372 b .L304 373.L309: 374 beq 6,.L304 375.L308: 376 lbzu 0,1(3) 377 cmpw 7,4,0 378 cmpwi 6,0,0 379 bne 7,.L309 380 blr 381.L304: 382 li 3,0 383 blr 384.size VG_(ppc32_linux_REDIR_FOR_strchr),.-VG_(ppc32_linux_REDIR_FOR_strchr) 385 386.global VG_(trampoline_stuff_end) 387VG_(trampoline_stuff_end): 388 389 /* and a trailing page of unexecutable code */ 390 UD2_PAGE 391 392# undef UD2_16 393# undef UD2_64 394# undef UD2_256 395# undef UD2_1024 396# undef UD2_PAGE 397 398/*---------------- ppc64-linux ----------------*/ 399#else 400#if defined(VGP_ppc64_linux) 401 402# define UD2_16 trap ; trap ; trap; trap 403# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 404# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64 405# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256 406# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024 407 408 /* a leading page of unexecutable code */ 409 UD2_PAGE 410 411.global VG_(trampoline_stuff_start) 412VG_(trampoline_stuff_start): 413 414.global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn) 415VG_(ppc64_linux_SUBST_FOR_rt_sigreturn): 416 li 0,__NR_rt_sigreturn 417 sc 418 .long 0 /*illegal insn*/ 419 420 /* See comment in pub_core_trampoline.h for what this is for */ 421.global VG_(ppctoc_magic_redirect_return_stub) 422VG_(ppctoc_magic_redirect_return_stub): 423 trap 424 425 /* this function is written using the "dotless" ABI convention */ 426 .align 2 427 .globl VG_(ppc64_linux_REDIR_FOR_strlen) 428 .section ".opd","aw" 429 .align 3 430VG_(ppc64_linux_REDIR_FOR_strlen): 431 .quad .L.VG_(ppc64_linux_REDIR_FOR_strlen),.TOC.@tocbase,0 432 .previous 433 .size VG_(ppc64_linux_REDIR_FOR_strlen), \ 434 .L0end-.L.VG_(ppc64_linux_REDIR_FOR_strlen) 435 .type VG_(ppc64_linux_REDIR_FOR_strlen), @function 436 437.L.VG_(ppc64_linux_REDIR_FOR_strlen): 438 mr 9,3 439 lbz 0,0(3) 440 li 3,0 441 cmpwi 7,0,0 442 beqlr 7 443 li 3,0 444.L01: 445 addi 0,3,1 446 extsw 3,0 447 lbzx 0,9,3 448 cmpwi 7,0,0 449 bne 7,.L01 450 blr 451 .long 0 452 .byte 0,0,0,0,0,0,0,0 453.L0end: 454 455 /* this function is written using the "dotless" ABI convention */ 456 .align 2 457 .globl VG_(ppc64_linux_REDIR_FOR_strchr) 458 .section ".opd","aw" 459 .align 3 460VG_(ppc64_linux_REDIR_FOR_strchr): 461 .quad .L.VG_(ppc64_linux_REDIR_FOR_strchr),.TOC.@tocbase,0 462 .previous 463 .size VG_(ppc64_linux_REDIR_FOR_strchr), \ 464 .L1end-.L.VG_(ppc64_linux_REDIR_FOR_strchr) 465 .type VG_(ppc64_linux_REDIR_FOR_strchr),@function 466 467.L.VG_(ppc64_linux_REDIR_FOR_strchr): 468 lbz 0,0(3) 469 rldicl 4,4,0,56 470 cmpw 7,4,0 471 beqlr 7 472 cmpdi 7,0,0 473 bne 7,.L18 474 b .L14 475.L19: 476 beq 6,.L14 477.L18: 478 lbzu 0,1(3) 479 cmpw 7,4,0 480 cmpdi 6,0,0 481 bne 7,.L19 482 blr 483.L14: 484 li 3,0 485 blr 486 .long 0 487 .byte 0,0,0,0,0,0,0,0 488.L1end: 489 490 491.global VG_(trampoline_stuff_end) 492VG_(trampoline_stuff_end): 493 494 /* and a trailing page of unexecutable code */ 495 UD2_PAGE 496 497# undef UD2_16 498# undef UD2_64 499# undef UD2_256 500# undef UD2_1024 501# undef UD2_PAGE 502 503/*---------------- ppc32-linux ----------------*/ 504 505#elif defined(VGP_arm_linux) 506 507# define UD2_4 .word 0xFFFFFFFF 508# define UD2_16 UD2_4 ; UD2_4 ; UD2_4 ; UD2_4 509# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16 510# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64 511# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256 512# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024 513 514 /* a leading page of unexecutable code */ 515 UD2_PAGE 516 517.global VG_(trampoline_stuff_start) 518VG_(trampoline_stuff_start): 519 520.global VG_(arm_linux_REDIR_FOR_strlen) 521VG_(arm_linux_REDIR_FOR_strlen): 522 mov r2, r0 523 ldrb r0, [r0, #0] @ zero_extendqisi2 524 @ lr needed for prologue 525 cmp r0, #0 526 bxeq lr 527 mov r0, #0 528.L5: 529 add r0, r0, #1 530 ldrb r3, [r0, r2] @ zero_extendqisi2 531 cmp r3, #0 532 bne .L5 533 bx lr 534 UD2_4 535 536//.global VG_(arm_linux_REDIR_FOR_index) 537//VG_(arm_linux_REDIR_FOR_index): 538// ldrb r3, [r0, #0] @ zero_extendqisi2 539// and r1, r1, #255 540// cmp r3, r1 541// @ lr needed for prologue 542// bne .L9 543// bx lr 544//.L12: 545// ldrb r3, [r0, #1]! @ zero_extendqisi2 546// cmp r3, r1 547// beq .L11 548//.L9: 549// cmp r3, #0 550// bne .L12 551// mov r0, #0 552// bx lr 553//.L11: 554// bx lr 555// UD2_4 556 557.global VG_(arm_linux_REDIR_FOR_memcpy) 558VG_(arm_linux_REDIR_FOR_memcpy): 559 stmfd sp!, {r4, r5, lr} 560 subs lr, r2, #0 561 mov r5, r0 562 beq .L2 563 cmp r0, r1 564 bls .L4 565 add r3, r0, lr 566 add r1, lr, r1 567 cmp lr, #3 568 sub r4, r3, #1 569 sub r0, r1, #1 570 ble .L28 571 sub ip, r3, #5 572 sub r1, r1, #5 573.L8: 574 ldrb r3, [r1, #4] @ zero_extendqisi2 575 sub lr, lr, #4 576 strb r3, [ip, #4] 577 ldrb r2, [r1, #3] @ zero_extendqisi2 578 cmp lr, #3 579 strb r2, [ip, #3] 580 ldrb r3, [r1, #2] @ zero_extendqisi2 581 mov r4, ip 582 strb r3, [ip, #2] 583 ldrb r2, [r1, #1] @ zero_extendqisi2 584 mov r0, r1 585 strb r2, [ip, #1] 586 sub r1, r1, #4 587 sub ip, ip, #4 588 bgt .L8 589 cmp lr, #0 590 beq .L2 591.L28: 592 sub r2, lr, #1 593.L21: 594 sub r2, r2, #1 595 ldrb r3, [r0], #-1 @ zero_extendqisi2 596 cmn r2, #1 597 strb r3, [r4], #-1 598 bne .L21 599.L2: 600 mov r0, r5 601 ldmfd sp!, {r4, r5, pc} 602.L4: 603 bcs .L2 604 cmp lr, #3 605 mov ip, r0 606 ble .L29 607.L19: 608 ldrb r3, [r1, #0] @ zero_extendqisi2 609 sub lr, lr, #4 610 strb r3, [ip, #0] 611 ldrb r2, [r1, #1] @ zero_extendqisi2 612 cmp lr, #3 613 strb r2, [ip, #1] 614 ldrb r3, [r1, #2] @ zero_extendqisi2 615 strb r3, [ip, #2] 616 ldrb r2, [r1, #3] @ zero_extendqisi2 617 add r1, r1, #4 618 strb r2, [ip, #3] 619 add ip, ip, #4 620 bgt .L19 621 cmp lr, #0 622 beq .L2 623.L29: 624 sub r2, lr, #1 625.L20: 626 sub r2, r2, #1 627 ldrb r3, [r1], #1 @ zero_extendqisi2 628 cmn r2, #1 629 strb r3, [ip], #1 630 bne .L20 631 mov r0, r5 632 ldmfd sp!, {r4, r5, pc} 633 UD2_4 634 635.global VG_(trampoline_stuff_end) 636VG_(trampoline_stuff_end): 637 638 /* and a trailing page of unexecutable code */ 639 UD2_PAGE 640 641# undef UD2_4 642# undef UD2_16 643# undef UD2_64 644# undef UD2_256 645# undef UD2_1024 646# undef UD2_PAGE 647 648/*---------------- x86-darwin ----------------*/ 649#else 650#if defined(VGP_x86_darwin) 651 652 /* a leading page of unexecutable code */ 653.fill 2048, 2, 0x0b0f /* `ud2` */ 654 655.globl VG_(trampoline_stuff_start) 656VG_(trampoline_stuff_start): 657 658.globl VG_(x86_darwin_SUBST_FOR_sigreturn) 659VG_(x86_darwin_SUBST_FOR_sigreturn): 660 /* XXX does this need to have any special form? (cf x86-linux 661 version) */ 662 movl $ __NR_DARWIN_FAKE_SIGRETURN, %eax 663 int $0x80 664 ud2 665 666.globl VG_(x86_darwin_REDIR_FOR_strlen) 667VG_(x86_darwin_REDIR_FOR_strlen): 668 movl 4(%esp), %edx 669 movl %edx, %eax 670 jmp 1f 6710: 672 incl %eax 6731: 674 cmpb $0, (%eax) 675 jne 0b 676 subl %edx, %eax 677 ret 678 679.globl VG_(x86_darwin_REDIR_FOR_strcat) 680VG_(x86_darwin_REDIR_FOR_strcat): 681 pushl %esi 682 movl 8(%esp), %esi 683 movl 12(%esp), %ecx 684 movl %esi, %edx 685 jmp 1f 6860: 687 incl %edx 6881: 689 cmpb $0, (%edx) 690 jne 0b 6912: 692 movzbl (%ecx), %eax 693 incl %ecx 694 movb %al, (%edx) 695 incl %edx 696 testb %al, %al 697 jne 2b 698 movl %esi, %eax 699 popl %esi 700 ret 701 702 703.globl VG_(x86_darwin_REDIR_FOR_strcmp) 704VG_(x86_darwin_REDIR_FOR_strcmp): 705 movl 4(%esp), %edx 706 movl 8(%esp), %ecx 707 jmp 1f 7080: 709 incl %edx 710 incl %ecx 7111: 712 movzbl (%edx), %eax 713 testb %al, %al 714 je 2f 715 cmpb (%ecx), %al 716 je 0b 7172: 718 movzbl (%ecx),%edx 719 movzbl %al,%eax 720 subl %edx, %eax 721 ret 722 723 724.globl VG_(x86_darwin_REDIR_FOR_strcpy) 725VG_(x86_darwin_REDIR_FOR_strcpy): 726 pushl %ebp 727 movl %esp, %ebp 728 pushl %esi 729 movl 8(%ebp), %esi 730 movl 12(%ebp), %ecx 731 movl %esi, %edx 732 jmp 1f 7330: 734 incl %ecx 735 incl %edx 7361: 737 movzbl (%ecx), %eax 738 testb %al, %al 739 movb %al, (%edx) 740 jne 0b 741 movl %esi, %eax 742 popl %esi 743 leave 744 ret 745 746.globl VG_(x86_darwin_REDIR_FOR_strlcat) 747VG_(x86_darwin_REDIR_FOR_strlcat): 748 pushl %ebp 749 movl %esp, %ebp 750 pushl %edi 751 pushl %esi 752 subl $16, %esp 753 movl 8(%ebp), %esi 754 movl 16(%ebp), %ecx 755 movl %esi, %edx 756 leal (%ecx,%esi), %eax 757 jmp 1f 7580: 759 incl %edx 7601: 761 cmpl %edx, %eax 762 je 2f 763 cmpb $0, (%edx) 764 jne 0b 7652: 766 movl %edx, %edi 767 subl %esi, %edi 768 movl %ecx, %esi 769 subl %edi, %esi 770 je 3f 771 movl 12(%ebp), %eax 772 jmp 6f 7733: 774 movl 12(%ebp), %eax 775 movl %eax, (%esp) 776 call VG_(x86_darwin_REDIR_FOR_strlen) 777 jmp 7f 7784: 779 cmpl $1, %esi 780 je 5f 781 movb %cl, (%edx) 782 decl %esi 783 incl %edx 7845: 785 incl %eax 7866: 787 movzbl (%eax), %ecx 788 testb %cl, %cl 789 jne 4b 790 movb $0, (%edx) 791 subl 12(%ebp), %eax 7927: 793 addl $16, %esp 794 leal (%edi,%eax), %eax 795 popl %esi 796 popl %edi 797 leave 798 ret 799 800 801.globl VG_(trampoline_stuff_end) 802VG_(trampoline_stuff_end): 803 804 /* a trailing page of unexecutable code */ 805.fill 2048, 2, 0x0b0f /* `ud2` */ 806 807 808/*---------------- amd64-darwin ----------------*/ 809#else 810#if defined(VGP_amd64_darwin) 811 812 /* a leading page of unexecutable code */ 813.fill 2048, 2, 0x0b0f /* `ud2` */ 814 815.globl VG_(trampoline_stuff_start) 816VG_(trampoline_stuff_start): 817 818.globl VG_(amd64_darwin_SUBST_FOR_sigreturn) 819VG_(amd64_darwin_SUBST_FOR_sigreturn): 820 /* XXX does this need to have any special form? (cf x86-linux 821 version) */ 822 movq $ __NR_DARWIN_FAKE_SIGRETURN, %rax 823 syscall 824 ud2 825 826.globl VG_(amd64_darwin_REDIR_FOR_strlen) 827VG_(amd64_darwin_REDIR_FOR_strlen): 828 movq %rdi, %rax 829 jmp 1f 8300: 831 incq %rax 8321: 833 cmpb $0, (%rax) 834 jne 0b 835 subq %rdi, %rax 836 ret 837 838.globl VG_(amd64_darwin_REDIR_FOR_strcat) 839VG_(amd64_darwin_REDIR_FOR_strcat): 840 movq %rdi, %rdx 841 jmp 1f 8420: 843 incq %rdx 8441: 845 cmpb $0, (%rdx) 846 jne 0b 8472: 848 movzbl (%rsi), %eax 849 incq %rsi 850 movb %al, (%rdx) 851 incq %rdx 852 testb %al, %al 853 jne 2b 854 movq %rdi, %rax 855 ret 856 857 858.globl VG_(amd64_darwin_REDIR_FOR_strcmp) 859VG_(amd64_darwin_REDIR_FOR_strcmp): 860 jmp 1f 8610: 862 incq %rdi 863 incq %rsi 8641: 865 movzbl (%rdi), %eax 866 testb %al, %al 867 je 2f 868 cmpb (%rsi), %al 869 je 0b 8702: 871 movzbl (%rsi), %edx 872 movzbl %al, %eax 873 subl %edx, %eax 874 ret 875 876.globl VG_(amd64_darwin_REDIR_FOR_strcpy) 877VG_(amd64_darwin_REDIR_FOR_strcpy): 878 pushq %rbp 879 movq %rdi, %rdx 880 movq %rsp, %rbp 881 jmp 1f 8820: 883 incq %rsi 884 incq %rdx 8851: 886 movzbl (%rsi), %eax 887 testb %al, %al 888 movb %al, (%rdx) 889 jne 0b 890 leave 891 movq %rdi, %rax 892 ret 893 894.globl VG_(amd64_darwin_REDIR_FOR_strlcat) 895VG_(amd64_darwin_REDIR_FOR_strlcat): 896 pushq %rbp 897 leaq (%rdx,%rdi), %rax 898 movq %rdi, %rcx 899 movq %rsp, %rbp 900 pushq %rbx 901 subq $8, %rsp 902 jmp 1f 9030: 904 incq %rcx 9051: 906 cmpq %rcx, %rax 907 je 2f 908 cmpb $0, (%rcx) 909 jne 0b 9102: 911 movq %rcx, %rbx 912 subq %rdi, %rbx 913 movq %rdx, %rdi 914 subq %rbx, %rdi 915 je 3f 916 movq %rsi, %rax 917 jmp 6f 9183: 919 movq %rsi, %rdi 920 call VG_(amd64_darwin_REDIR_FOR_strlen) 921 jmp 7f 9224: 923 cmpq $1, %rdi 924 je 5f 925 movb %dl, (%rcx) 926 decq %rdi 927 incq %rcx 9285: 929 incq %rax 9306: 931 movzbl (%rax), %edx 932 testb %dl, %dl 933 jne 4b 934 movb $0, (%rcx) 935 subq %rsi, %rax 9367: 937 leaq (%rbx,%rax), %rax 938 addq $8, %rsp 939 popq %rbx 940 leave 941 ret 942 943.globl VG_(amd64_darwin_REDIR_FOR_arc4random) 944VG_(amd64_darwin_REDIR_FOR_arc4random): 945 /* not very random, hope dyld won't mind */ 946 movq $0x76616c6772696e64, %rax 947 ret 948 949.globl VG_(trampoline_stuff_end) 950VG_(trampoline_stuff_end): 951 952 /* a trailing page of unexecutable code */ 953.fill 2048, 2, 0x0b0f /* `ud2` */ 954 955 956/*---------------- s390x-linux ----------------*/ 957#else 958#if defined(VGP_s390x_linux) 959 960 /* a leading page of unexecutable code */ 961 .fill 2048, 2, 0x0000 962 963.global VG_(trampoline_stuff_start) 964VG_(trampoline_stuff_start): 965 966.global VG_(s390x_linux_SUBST_FOR_sigreturn) 967VG_(s390x_linux_SUBST_FOR_sigreturn): 968 svc __NR_sigreturn 969 .short 0 970 971.global VG_(s390x_linux_SUBST_FOR_rt_sigreturn) 972VG_(s390x_linux_SUBST_FOR_rt_sigreturn): 973 /* Old gcc unwinding code checks for a sig(_rt)_return svc and then 974 for ra = cfa to decide if it is a sig_rt_frame or not. Since we 975 set ra to this trampoline, but the cfa is still in the stack, 976 the unwinder thinks, that this is a non-rt frame and causes a 977 crash in the gcc unwinder - which is used by the thread library 978 and others. Therefore we add a lr 1,1 nop, to let the gcc 979 unwinder bail out gracefully. This might also affect unwinding 980 across the signal frame - tough luck. fixs390 */ 981 lr 1,1 982 svc __NR_rt_sigreturn 983 .short 0 984 985.globl VG_(trampoline_stuff_end) 986VG_(trampoline_stuff_end): 987 .fill 2048, 2, 0x0000 988 989/*---------------- unknown ----------------*/ 990#else 991# error Unknown platform 992 993#endif 994#endif 995#endif 996#endif 997#endif 998#endif 999#endif 1000 1001#if defined(VGO_linux) 1002/* Let the linker know we don't need an executable stack */ 1003# if defined(VGP_arm_linux) 1004 .section .note.GNU-stack,"",%progbits 1005# else 1006 .section .note.GNU-stack,"",@progbits 1007# endif 1008#endif 1009 1010/*--------------------------------------------------------------------*/ 1011/*--- end ---*/ 1012/*--------------------------------------------------------------------*/ 1013