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@acm.org 12 Copyright (C) 2006-2010 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.global VG_(trampoline_stuff_end) 116VG_(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) 141VG_(trampoline_stuff_start): 142 143.global VG_(amd64_linux_SUBST_FOR_rt_sigreturn) 144VG_(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 153VG_(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 163VG_(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 177VG_(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) 243VG_(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) 268VG_(trampoline_stuff_start): 269 270.global VG_(ppc32_linux_SUBST_FOR_sigreturn) 271VG_(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) 277VG_(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 288VG_(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 306VG_(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 344VG_(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) 366VG_(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) 391VG_(trampoline_stuff_start): 392 393.global VG_(ppc64_linux_SUBST_FOR_rt_sigreturn) 394VG_(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) 401VG_(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 409VG_(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 439VG_(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) 471VG_(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) 497VG_(trampoline_stuff_start): 498 499.global VG_(arm_linux_REDIR_FOR_strlen) 500VG_(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) 537VG_(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) 615VG_(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) 643VG_(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) 652VG_(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 740do___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 750do_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) 760VG_(ppctoc_magic_redirect_return_stub): 761 trap 762 763.globl VG_(trampoline_stuff_end) 764VG_(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) 786VG_(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) 794VG_(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 877do_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 886do_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) 894VG_(ppctoc_magic_redirect_return_stub): 895 trap 896 897.globl VG_(trampoline_stuff_end) 898VG_(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) 917VG_(trampoline_stuff_start): 918 919.globl VG_(x86_darwin_SUBST_FOR_sigreturn) 920VG_(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) 928VG_(x86_darwin_REDIR_FOR_strlen): 929 movl 4(%esp), %edx 930 movl %edx, %eax 931 jmp 1f 9320: 933 incl %eax 9341: 935 cmpb $0, (%eax) 936 jne 0b 937 subl %edx, %eax 938 ret 939 940.globl VG_(x86_darwin_REDIR_FOR_strcat) 941VG_(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 9470: 948 incl %edx 9491: 950 cmpb $0, (%edx) 951 jne 0b 9522: 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) 965VG_(x86_darwin_REDIR_FOR_strcmp): 966 movl 4(%esp), %edx 967 movl 8(%esp), %ecx 968 jmp 1f 9690: 970 incl %edx 971 incl %ecx 9721: 973 movzbl (%edx), %eax 974 testb %al, %al 975 je 2f 976 cmpb (%ecx), %al 977 je 0b 9782: 979 movzbl (%ecx),%edx 980 movzbl %al,%eax 981 subl %edx, %eax 982 ret 983 984 985.globl VG_(x86_darwin_REDIR_FOR_strcpy) 986VG_(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 9940: 995 incl %ecx 996 incl %edx 9971: 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) 1008VG_(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 10190: 1020 incl %edx 10211: 1022 cmpl %edx, %eax 1023 je 2f 1024 cmpb $0, (%edx) 1025 jne 0b 10262: 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 10343: 1035 movl 12(%ebp), %eax 1036 movl %eax, (%esp) 1037 call VG_(x86_darwin_REDIR_FOR_strlen) 1038 jmp 7f 10394: 1040 cmpl $1, %esi 1041 je 5f 1042 movb %cl, (%edx) 1043 decl %esi 1044 incl %edx 10455: 1046 incl %eax 10476: 1048 movzbl (%eax), %ecx 1049 testb %cl, %cl 1050 jne 4b 1051 movb $0, (%edx) 1052 subl 12(%ebp), %eax 10537: 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) 1063VG_(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) 1077VG_(trampoline_stuff_start): 1078 1079.globl VG_(amd64_darwin_SUBST_FOR_sigreturn) 1080VG_(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) 1088VG_(amd64_darwin_REDIR_FOR_strlen): 1089 movq %rdi, %rax 1090 jmp 1f 10910: 1092 incq %rax 10931: 1094 cmpb $0, (%rax) 1095 jne 0b 1096 subq %rdi, %rax 1097 ret 1098 1099.globl VG_(amd64_darwin_REDIR_FOR_strcat) 1100VG_(amd64_darwin_REDIR_FOR_strcat): 1101 movq %rdi, %rdx 1102 jmp 1f 11030: 1104 incq %rdx 11051: 1106 cmpb $0, (%rdx) 1107 jne 0b 11082: 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) 1120VG_(amd64_darwin_REDIR_FOR_strcmp): 1121 jmp 1f 11220: 1123 incq %rdi 1124 incq %rsi 11251: 1126 movzbl (%rdi), %eax 1127 testb %al, %al 1128 je 2f 1129 cmpb (%rsi), %al 1130 je 0b 11312: 1132 movzbl (%rsi), %edx 1133 movzbl %al, %eax 1134 subl %edx, %eax 1135 ret 1136 1137.globl VG_(amd64_darwin_REDIR_FOR_strcpy) 1138VG_(amd64_darwin_REDIR_FOR_strcpy): 1139 pushq %rbp 1140 movq %rdi, %rdx 1141 movq %rsp, %rbp 1142 jmp 1f 11430: 1144 incq %rsi 1145 incq %rdx 11461: 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) 1156VG_(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 11640: 1165 incq %rcx 11661: 1167 cmpq %rcx, %rax 1168 je 2f 1169 cmpb $0, (%rcx) 1170 jne 0b 11712: 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 11793: 1180 movq %rsi, %rdi 1181 call VG_(amd64_darwin_REDIR_FOR_strlen) 1182 jmp 7f 11834: 1184 cmpq $1, %rdi 1185 je 5f 1186 movb %dl, (%rcx) 1187 decq %rdi 1188 incq %rcx 11895: 1190 incq %rax 11916: 1192 movzbl (%rax), %edx 1193 testb %dl, %dl 1194 jne 4b 1195 movb $0, (%rcx) 1196 subq %rsi, %rax 11977: 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) 1205VG_(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) 1211VG_(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