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