1 /* -*- mode: C; c-basic-offset: 3; -*- */ 2 3 /*--------------------------------------------------------------------*/ 4 /*--- Debug (not-for-user) logging; also vprintf. m_debuglog.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2015 Julian Seward 12 jseward (at) acm.org 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30 */ 31 32 33 /* Performs low-level debug logging that can safely run immediately 34 after startup. To minimise the dependencies on any other parts of 35 the system, the only place the debug output may go is file 36 descriptor 2 (stderr). 37 */ 38 /* This is the first-initialised module in the entire system! 39 Therefore it is CRITICAL that it does not depend on any other code 40 running first. Hence only the following very limited includes. We 41 cannot depend (directly or indirectly) on any dynamic memory 42 allocation facilities, nor on the m_libc facilities, since the 43 latter depend on this module. DO NOT MESS WITH THESE INCLUDES 44 UNLESS YOU ARE 100% CERTAIN YOU UNDERSTAND THE CONSEQUENCES. 45 */ 46 47 /* This module is also notable because it is linked into both 48 stage1 and stage2. */ 49 50 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions 51 of syscalls rather than the vanilla version, if a _nocancel version 52 is available. See docs/internals/Darwin-notes.txt for the reason 53 why. */ 54 55 #include "pub_core_basics.h" /* basic types */ 56 #include "pub_core_vkiscnums.h" /* for syscall numbers */ 57 #include "pub_core_debuglog.h" /* our own iface */ 58 #include "pub_core_clreq.h" /* for RUNNING_ON_VALGRIND */ 59 #if defined(VGO_solaris) 60 #include "pub_core_vki.h" /* for EINTR and ERESTART */ 61 #endif 62 63 static Bool clo_xml; 64 65 void VG_(debugLog_setXml)(Bool xml) 66 { 67 clo_xml = xml; 68 } 69 70 /*------------------------------------------------------------*/ 71 /*--- Stuff to make us completely independent. ---*/ 72 /*------------------------------------------------------------*/ 73 74 /* ----- Platform-specifics ----- */ 75 76 #if defined(VGP_x86_linux) 77 78 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 79 { 80 Int result; 81 82 __asm__ volatile ( 83 "pushl %%ebx\n" 84 "movl $"VG_STRINGIFY(__NR_write)", %%eax\n" /* %eax = __NR_write */ 85 "movl $2, %%ebx\n" /* %ebx = stderr */ 86 "int $0x80\n" /* write(stderr, buf, n) */ 87 "popl %%ebx\n" 88 : /*wr*/ "=a" (result) 89 : /*rd*/ "c" (buf), "d" (n) 90 : /*trash*/ "edi", "memory", "cc" 91 ); 92 93 return result >= 0 ? result : -1; 94 } 95 96 static UInt local_sys_getpid ( void ) 97 { 98 UInt __res; 99 __asm__ volatile ( 100 "movl $"VG_STRINGIFY(__NR_getpid)", %%eax\n" /* %eax = __NR_getpid */ 101 "int $0x80\n" /* getpid() */ 102 "movl %%eax, %0\n" /* set __res = eax */ 103 : "=mr" (__res) 104 : 105 : "eax" ); 106 return __res; 107 } 108 109 #elif defined(VGP_amd64_linux) 110 111 __attribute__((noinline)) 112 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 113 { 114 volatile Long block[2]; 115 block[0] = (Long)buf; 116 block[1] = n; 117 __asm__ volatile ( 118 "subq $256, %%rsp\n" /* don't trash the stack redzone */ 119 "pushq %%r15\n" /* r15 is callee-save */ 120 "movq %0, %%r15\n" /* r15 = &block */ 121 "pushq %%r15\n" /* save &block */ 122 "movq $"VG_STRINGIFY(__NR_write)", %%rax\n" /* rax = __NR_write */ 123 "movq $2, %%rdi\n" /* rdi = stderr */ 124 "movq 0(%%r15), %%rsi\n" /* rsi = buf */ 125 "movq 8(%%r15), %%rdx\n" /* rdx = n */ 126 "syscall\n" /* write(stderr, buf, n) */ 127 "popq %%r15\n" /* reestablish &block */ 128 "movq %%rax, 0(%%r15)\n" /* block[0] = result */ 129 "popq %%r15\n" /* restore r15 */ 130 "addq $256, %%rsp\n" /* restore stack ptr */ 131 : /*wr*/ 132 : /*rd*/ "r" (block) 133 : /*trash*/ "rax", "rdi", "rsi", "rdx", "memory", "cc" 134 ); 135 if (block[0] < 0) 136 block[0] = -1; 137 return (UInt)block[0]; 138 } 139 140 static UInt local_sys_getpid ( void ) 141 { 142 UInt __res; 143 __asm__ volatile ( 144 "movq $"VG_STRINGIFY(__NR_getpid)", %%rax\n" /* %rax = __NR_getpid */ 145 "syscall\n" /* getpid() */ 146 "movl %%eax, %0\n" /* set __res = %eax */ 147 : "=mr" (__res) 148 : 149 : "rax" ); 150 return __res; 151 } 152 153 #elif defined(VGP_ppc32_linux) 154 155 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 156 { 157 volatile Int block[2]; 158 block[0] = (Int)buf; 159 block[1] = n; 160 __asm__ volatile ( 161 "addi 1,1,-256\n\t" 162 "mr 5,%0\n\t" /* r5 = &block[0] */ 163 "stw 5,0(1)\n\t" /* stash on stack */ 164 "li 0,"VG_STRINGIFY(__NR_write)"\n\t" /* set %r0 = __NR_write */ 165 "li 3,2\n\t" /* set %r3 = stderr */ 166 "lwz 4,0(5)\n\t" /* set %r4 = buf */ 167 "lwz 5,4(5)\n\t" /* set %r5 = n */ 168 "sc\n\t" /* write(stderr, buf, n) */ 169 "lwz 5,0(1)\n\t" 170 "addi 1,1,256\n\t" 171 "stw 3,0(5)\n" /* block[0] = result */ 172 : 173 : "b" (block) 174 : "cc","memory","cr0","ctr", 175 "r0","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12" 176 ); 177 if (block[0] < 0) 178 block[0] = -1; 179 return (UInt)block[0]; 180 } 181 182 static UInt local_sys_getpid ( void ) 183 { 184 register UInt __res __asm__ ("r3"); 185 __asm__ volatile ( 186 "li 0, %1\n\t" 187 "sc" 188 : "=&r" (__res) 189 : "i" (__NR_getpid) 190 : "cc","memory","cr0","ctr", 191 "r0","r2","r4","r5","r6","r7","r8","r9","r10","r11","r12" 192 ); 193 return __res; 194 } 195 196 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 197 198 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 199 { 200 volatile Long block[2]; 201 block[0] = (Long)buf; 202 block[1] = (Long)n; 203 __asm__ volatile ( 204 "addi 1,1,-256\n\t" 205 "mr 5,%0\n\t" /* r5 = &block[0] */ 206 "std 5,0(1)\n\t" /* stash on stack */ 207 "li 0,"VG_STRINGIFY(__NR_write)"\n\t" /* %r0 = __NR_write */ 208 "li 3,2\n\t" /* set %r3 = stderr */ 209 "ld 4,0(5)\n\t" /* set %r4 = buf */ 210 "ld 5,8(5)\n\t" /* set %r5 = n */ 211 "sc\n\t" /* write(stderr, buf, n) */ 212 "ld 5,0(1)\n\t" 213 "addi 1,1,256\n\t" 214 "std 3,0(5)\n" /* block[0] = result */ 215 : 216 : "b" (block) 217 : "cc","memory","cr0","ctr", 218 "r0","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12" 219 ); 220 if (block[0] < 0) 221 block[0] = -1; 222 return (UInt)(Int)block[0]; 223 } 224 225 static UInt local_sys_getpid ( void ) 226 { 227 register ULong __res __asm__ ("r3"); 228 __asm__ volatile ( 229 "li 0, %1\n\t" 230 "sc" 231 : "=&r" (__res) 232 : "i" (__NR_getpid) 233 : "cc","memory","cr0","ctr", 234 "r0","r2","r4","r5","r6","r7","r8","r9","r10","r11","r12" 235 ); 236 return (UInt)__res; 237 } 238 239 #elif defined(VGP_arm_linux) 240 241 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 242 { 243 volatile Int block[2]; 244 block[0] = (Int)buf; 245 block[1] = n; 246 __asm__ volatile ( 247 "mov r0, #2\n\t" /* stderr */ 248 "ldr r1, [%0]\n\t" /* buf */ 249 "ldr r2, [%0, #4]\n\t" /* n */ 250 "push {r6,r7}\n\t" 251 "mov r7, #"VG_STRINGIFY(__NR_write)"\n\t" 252 "svc 0x0\n" /* write() */ 253 "pop {r6,r7}\n\t" 254 "str r0, [%0]\n\t" 255 : 256 : "r" (block) 257 : "r0","r1","r2" 258 ); 259 if (block[0] < 0) 260 block[0] = -1; 261 return (UInt)block[0]; 262 } 263 264 static UInt local_sys_getpid ( void ) 265 { 266 UInt __res; 267 __asm__ volatile ( 268 "push {r6,r7}\n\t" 269 "mov r7, #"VG_STRINGIFY(__NR_getpid)"\n\t" 270 "svc 0x0\n\t" /* getpid() */ 271 "pop {r6,r7}\n\t" 272 "mov %0, r0\n\t" 273 : "=r" (__res) 274 : 275 : "r0" ); 276 return __res; 277 } 278 279 #elif defined(VGP_arm64_linux) 280 281 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 282 { 283 volatile ULong block[2]; 284 block[0] = (ULong)buf; 285 block[1] = (ULong)n; 286 __asm__ volatile ( 287 "mov x0, #2\n\t" /* stderr */ 288 "ldr x1, [%0]\n\t" /* buf */ 289 "ldr x2, [%0, #8]\n\t" /* n */ 290 "mov x8, #"VG_STRINGIFY(__NR_write)"\n\t" 291 "svc 0x0\n" /* write() */ 292 "str x0, [%0]\n\t" 293 : 294 : "r" (block) 295 : "x0","x1","x2","x7" 296 ); 297 if (block[0] < 0) 298 block[0] = -1; 299 return (UInt)block[0]; 300 } 301 302 static UInt local_sys_getpid ( void ) 303 { 304 UInt __res; 305 __asm__ volatile ( 306 "mov x8, #"VG_STRINGIFY(__NR_getpid)"\n" 307 "svc 0x0\n" /* getpid() */ 308 "mov %0, x0\n" 309 : "=r" (__res) 310 : 311 : "x0", "x8" ); 312 return (UInt)__res; 313 } 314 315 #elif defined(VGP_x86_darwin) 316 317 /* We would use VG_DARWIN_SYSNO_TO_KERNEL instead of VG_DARWIN_SYSNO_INDEX 318 except that the former has a C ternary ?: operator which isn't valid in 319 asm code. Both macros give the same results for Unix-class syscalls (which 320 these all are, as identified by the use of 'int 0x80'). */ 321 __attribute__((noinline)) 322 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 323 { 324 UInt __res; 325 __asm__ volatile ( 326 "movl %2, %%eax\n" /* push n */ 327 "pushl %%eax\n" 328 "movl %1, %%eax\n" /* push buf */ 329 "pushl %%eax\n" 330 "movl $2, %%eax\n" /* push stderr */ 331 "pushl %%eax\n" 332 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_INDEX(__NR_write_nocancel)) 333 ", %%eax\n" 334 "pushl %%eax\n" /* push fake return address */ 335 "int $0x80\n" /* write(stderr, buf, n) */ 336 "jnc 1f\n" /* jump if no error */ 337 "movl $-1, %%eax\n" /* return -1 if error */ 338 "1: " 339 "movl %%eax, %0\n" /* __res = eax */ 340 "addl $16, %%esp\n" /* pop x4 */ 341 : "=mr" (__res) 342 : "g" (buf), "g" (n) 343 : "eax", "edx", "cc" 344 ); 345 return __res; 346 } 347 348 static UInt local_sys_getpid ( void ) 349 { 350 UInt __res; 351 __asm__ volatile ( 352 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_INDEX(__NR_getpid))", %%eax\n" 353 "int $0x80\n" /* getpid() */ 354 "movl %%eax, %0\n" /* set __res = eax */ 355 : "=mr" (__res) 356 : 357 : "eax", "cc" ); 358 return __res; 359 } 360 361 #elif defined(VGP_amd64_darwin) 362 363 __attribute__((noinline)) 364 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 365 { 366 UInt __res; 367 __asm__ volatile ( 368 "movq $2, %%rdi\n" /* push stderr */ 369 "movq %1, %%rsi\n" /* push buf */ 370 "movl %2, %%edx\n" /* push n */ 371 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_FOR_KERNEL(__NR_write_nocancel)) 372 ", %%eax\n" 373 "syscall\n" /* write(stderr, buf, n) */ 374 "jnc 1f\n" /* jump if no error */ 375 "movq $-1, %%rax\n" /* return -1 if error */ 376 "1: " 377 "movl %%eax, %0\n" /* __res = eax */ 378 : "=mr" (__res) 379 : "g" (buf), "g" (n) 380 : "rdi", "rsi", "rdx", "rcx", "rax", "cc" ); 381 return __res; 382 } 383 384 static UInt local_sys_getpid ( void ) 385 { 386 UInt __res; 387 __asm__ volatile ( 388 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_FOR_KERNEL(__NR_getpid))", %%eax\n" 389 "syscall\n" /* getpid() */ 390 "movl %%eax, %0\n" /* set __res = eax */ 391 : "=mr" (__res) 392 : 393 : "rax", "rcx", "cc" ); 394 return __res; 395 } 396 397 #elif defined(VGP_s390x_linux) 398 399 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 400 { 401 register Int r2 asm("2") = 2; /* file descriptor STDERR */ 402 register const HChar* r3 asm("3") = buf; 403 register ULong r4 asm("4") = n; 404 register ULong r2_res asm("2"); 405 ULong __res; 406 407 __asm__ __volatile__ ( 408 "svc %b1\n" 409 : "=d" (r2_res) 410 : "i" (__NR_write), 411 "0" (r2), 412 "d" (r3), 413 "d" (r4) 414 : "cc", "memory"); 415 __res = r2_res; 416 417 if (__res >= (ULong)(-125)) 418 __res = -1; 419 return (UInt)(__res); 420 } 421 422 static UInt local_sys_getpid ( void ) 423 { 424 register ULong r2 asm("2"); 425 ULong __res; 426 427 __asm__ __volatile__ ( 428 "svc %b1\n" 429 : "=d" (r2) 430 : "i" (__NR_getpid) 431 : "cc", "memory"); 432 __res = r2; 433 434 if (__res >= (ULong)(-125)) 435 __res = -1; 436 return (UInt)(__res); 437 } 438 439 #elif defined(VGP_mips32_linux) 440 441 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 442 { 443 volatile Int block[2]; 444 block[0] = (Int)buf; 445 block[1] = n; 446 __asm__ volatile ( 447 "li $4, 2\n\t" /* stderr */ 448 "lw $5, 0(%0)\n\t" /* buf */ 449 "lw $6, 4(%0)\n\t" /* n */ 450 "move $7, $0\n\t" 451 "li $2, %1\n\t" /* set v0 = __NR_write */ 452 "syscall\n\t" /* write() */ 453 "nop\n\t" 454 : 455 : "r" (block), "n" (__NR_write) 456 : "2", "4", "5", "6", "7" 457 ); 458 if (block[0] < 0) 459 block[0] = -1; 460 return (UInt)block[0]; 461 } 462 463 static UInt local_sys_getpid ( void ) 464 { 465 UInt __res; 466 __asm__ volatile ( 467 "li $2, %1\n\t" /* set v0 = __NR_getpid */ 468 "syscall\n\t" /* getpid() */ 469 "nop\n\t" 470 "move %0, $2\n" 471 : "=r" (__res) 472 : "n" (__NR_getpid) 473 : "$2" ); 474 return __res; 475 } 476 477 #elif defined(VGP_mips64_linux) 478 479 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 480 { 481 volatile Long block[2]; 482 block[0] = (Long)buf; 483 block[1] = n; 484 __asm__ volatile ( 485 "li $4, 2\n\t" /* std output*/ 486 "ld $5, 0(%0)\n\t" /*$5 = buf*/ 487 "ld $6, 8(%0)\n\t" /*$6 = n */ 488 "move $7, $0\n\t" 489 "li $2, %1\n\t" /* set v0 = __NR_write */ 490 "\tsyscall\n" 491 "\tnop\n" 492 : /*wr*/ 493 : /*rd*/ "r" (block), "n" (__NR_write) 494 : "2", "4", "5", "6", "7" 495 ); 496 if (block[0] < 0) 497 block[0] = -1; 498 return (UInt)(Int)block[0]; 499 } 500 501 static UInt local_sys_getpid ( void ) 502 { 503 ULong __res; 504 __asm__ volatile ( 505 "li $2, %1\n\t" /* set v0 = __NR_getpid */ 506 "syscall\n\t" /* getpid() */ 507 "nop\n\t" 508 "move %0, $2\n" 509 : "=r" (__res) 510 : "n" (__NR_getpid) 511 : "$2" ); 512 return (UInt)(__res); 513 } 514 515 #elif defined(VGP_tilegx_linux) 516 517 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 518 { 519 volatile Long block[2]; 520 block[0] = (Long)buf; 521 block[1] = n; 522 Long __res = 0; 523 __asm__ volatile ( 524 "movei r0, 2 \n\t" /* stderr */ 525 "move r1, %1 \n\t" /* buf */ 526 "move r2, %2 \n\t" /* n */ 527 "move r3, zero \n\t" 528 "moveli r10, %3 \n\t" /* set r10 = __NR_write */ 529 "swint1 \n\t" /* write() */ 530 "nop \n\t" 531 "move %0, r0 \n\t" /* save return into block[0] */ 532 : "=r"(__res) 533 : "r" (block[0]), "r"(block[1]), "n" (__NR_write) 534 : "r0", "r1", "r2", "r3", "r4", "r5"); 535 if (__res < 0) 536 __res = -1; 537 return (UInt)__res; 538 } 539 540 static UInt local_sys_getpid ( void ) 541 { 542 UInt __res, __err; 543 __res = 0; 544 __err = 0; 545 __asm__ volatile ( 546 "moveli r10, %2\n\t" /* set r10 = __NR_getpid */ 547 "swint1\n\t" /* getpid() */ 548 "nop\n\t" 549 "move %0, r0\n" 550 "move %1, r1\n" 551 : "=r" (__res), "=r"(__err) 552 : "n" (__NR_getpid) 553 : "r0", "r1", "r2", "r3", "r4", 554 "r5", "r6", "r7", "r8", "r9", 555 "r10", "r11", "r12", "r13", "r14", 556 "r15", "r16", "r17", "r18", "r19", 557 "r20", "r21", "r22", "r23", "r24", 558 "r25", "r26", "r27", "r28", "r29"); 559 return __res; 560 } 561 562 #elif defined(VGP_x86_solaris) 563 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 564 { 565 UInt res, err; 566 Bool restart; 567 568 do { 569 /* The Solaris kernel does not restart syscalls automatically so it is 570 done here. */ 571 __asm__ __volatile__ ( 572 "movl %[n], %%eax\n" /* push n */ 573 "pushl %%eax\n" 574 "movl %[buf], %%eax\n" /* push buf */ 575 "pushl %%eax\n" 576 "movl $2, %%eax\n" /* push stderr */ 577 "pushl %%eax\n" 578 "movl $"VG_STRINGIFY(__NR_write)", %%eax\n" 579 "pushl %%eax\n" /* push fake return address */ 580 "int $0x91\n" /* write(stderr, buf, n) */ 581 "movl $0, %%edx\n" /* assume no error */ 582 "jnc 1f\n" /* jump if no error */ 583 "movl $1, %%edx\n" /* set error flag */ 584 "1: " 585 "addl $16, %%esp\n" /* pop x4 */ 586 : "=&a" (res), "=d" (err) 587 : [buf] "g" (buf), [n] "g" (n) 588 : "cc"); 589 restart = err && (res == VKI_EINTR || res == VKI_ERESTART); 590 } while (restart); 591 592 return res; 593 } 594 595 static UInt local_sys_getpid ( void ) 596 { 597 UInt res; 598 599 /* The getpid() syscall never returns EINTR or ERESTART so there is no need 600 for restarting it. */ 601 __asm__ __volatile__ ( 602 "movl $"VG_STRINGIFY(__NR_getpid)", %%eax\n" 603 "int $0x91\n" /* getpid() */ 604 : "=a" (res) 605 : 606 : "edx", "cc"); 607 608 return res; 609 } 610 611 #elif defined(VGP_amd64_solaris) 612 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 613 { 614 ULong res, err; 615 Bool restart; 616 617 do { 618 /* The Solaris kernel does not restart syscalls automatically so it is 619 done here. */ 620 __asm__ __volatile__ ( 621 "movq $2, %%rdi\n" /* push stderr */ 622 "movq $"VG_STRINGIFY(__NR_write)", %%rax\n" 623 "syscall\n" /* write(stderr, buf, n) */ 624 "movq $0, %%rdx\n" /* assume no error */ 625 "jnc 1f\n" /* jump if no error */ 626 "movq $1, %%rdx\n" /* set error flag */ 627 "1: " 628 : "=a" (res), "=d" (err) 629 : "S" (buf), "d" (n) 630 : "cc"); 631 restart = err && (res == VKI_EINTR || res == VKI_ERESTART); 632 } while (restart); 633 634 return res; 635 } 636 637 static UInt local_sys_getpid ( void ) 638 { 639 UInt res; 640 641 /* The getpid() syscall never returns EINTR or ERESTART so there is no need 642 for restarting it. */ 643 __asm__ __volatile__ ( 644 "movq $"VG_STRINGIFY(__NR_getpid)", %%rax\n" 645 "syscall\n" /* getpid() */ 646 : "=a" (res) 647 : 648 : "edx", "cc"); 649 650 return res; 651 } 652 653 #else 654 # error Unknown platform 655 #endif 656 657 658 /* ----- generic ----- */ 659 660 /* strlen, so we don't need m_libc */ 661 static Int local_strlen ( const HChar* str ) 662 { 663 Int i = 0; 664 while (str[i] != 0) i++; 665 return i; 666 } 667 668 static HChar local_toupper ( HChar c ) 669 { 670 if (c >= 'a' && c <= 'z') 671 return c + ('A' - 'a'); 672 else 673 return c; 674 } 675 676 /* Emit buf[0 .. n-1] to stderr. Unfortunately platform-specific. 677 */ 678 static void emit ( const HChar* buf, Int n ) 679 { 680 if (n >= 1) 681 (void)local_sys_write_stderr(buf, n); 682 } 683 684 685 /*------------------------------------------------------------*/ 686 /*--- A simple, generic, vprintf implementation. ---*/ 687 /*------------------------------------------------------------*/ 688 689 /* ----------------------------------------------- 690 Distantly derived from: 691 692 vprintf replacement for Checker. 693 Copyright 1993, 1994, 1995 Tristan Gingold 694 Written September 1993 Tristan Gingold 695 Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE 696 697 (Checker itself was GPL'd.) 698 ----------------------------------------------- */ 699 700 /* Some flags. */ 701 #define VG_MSG_SIGNED 1 /* The value is signed. */ 702 #define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */ 703 #define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */ 704 #define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */ 705 #define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */ 706 #define VG_MSG_ALTFORMAT 32 /* Convert the value to alternate format */ 707 708 /* Copy a string into the buffer. */ 709 static 710 UInt myvprintf_str ( void(*send)(HChar,void*), 711 void* send_arg2, 712 Int flags, 713 Int width, 714 const HChar* str, 715 Bool capitalise ) 716 { 717 # define MAYBE_TOUPPER(ch) (capitalise ? local_toupper(ch) : (ch)) 718 UInt ret = 0; 719 Int i, extra; 720 Int len = local_strlen(str); 721 722 if (width == 0) { 723 ret += len; 724 for (i = 0; i < len; i++) 725 send(MAYBE_TOUPPER(str[i]), send_arg2); 726 return ret; 727 } 728 729 if (len > width) { 730 ret += width; 731 for (i = 0; i < width; i++) 732 send(MAYBE_TOUPPER(str[i]), send_arg2); 733 return ret; 734 } 735 736 extra = width - len; 737 if (! (flags & VG_MSG_LJUSTIFY)) { 738 ret += extra; 739 for (i = 0; i < extra; i++) 740 send(' ', send_arg2); 741 } 742 ret += len; 743 for (i = 0; i < len; i++) 744 send(MAYBE_TOUPPER(str[i]), send_arg2); 745 if (flags & VG_MSG_LJUSTIFY) { 746 ret += extra; 747 for (i = 0; i < extra; i++) 748 send(' ', send_arg2); 749 } 750 751 # undef MAYBE_TOUPPER 752 return ret; 753 } 754 755 756 /* Copy a string into the buffer, escaping bad XML chars. */ 757 static 758 UInt myvprintf_str_XML_simplistic ( void(*send)(HChar,void*), 759 void* send_arg2, 760 const HChar* str ) 761 { 762 UInt ret = 0; 763 Int i; 764 Int len = local_strlen(str); 765 const HChar* alt; 766 767 for (i = 0; i < len; i++) { 768 switch (str[i]) { 769 case '&': alt = "&"; break; 770 case '<': alt = "<"; break; 771 case '>': alt = ">"; break; 772 default: alt = NULL; 773 } 774 775 if (alt) { 776 while (*alt) { 777 send(*alt, send_arg2); 778 ret++; 779 alt++; 780 } 781 } else { 782 send(str[i], send_arg2); 783 ret++; 784 } 785 } 786 787 return ret; 788 } 789 790 791 /* Write P into the buffer according to these args: 792 * If SIGN is true, p is a signed. 793 * BASE is the base. 794 * If WITH_ZERO is true, '0' must be added. 795 * WIDTH is the width of the field. 796 */ 797 static 798 UInt myvprintf_int64 ( void(*send)(HChar,void*), 799 void* send_arg2, 800 Int flags, 801 Int base, 802 Int width, 803 Bool capitalised, 804 ULong p ) 805 { 806 /* To print an ULong base 2 needs 64 characters. If commas are requested, 807 add 21. Plus 1 for a possible sign plus 1 for \0. Makes 87 -- so let's 808 say 90. The size of BUF needs to be max(90, WIDTH + 1) */ 809 HChar buf[width + 1 > 90 ? width + 1 : 90]; 810 Int ind = 0; 811 Int i, nc = 0; 812 Bool neg = False; 813 const HChar* digits = capitalised ? "0123456789ABCDEF" : "0123456789abcdef"; 814 UInt ret = 0; 815 816 if (base < 2 || base > 16) 817 return ret; 818 819 if ((flags & VG_MSG_SIGNED) && (Long)p < 0) { 820 p = - (Long)p; 821 neg = True; 822 } 823 824 if (p == 0) 825 buf[ind++] = '0'; 826 else { 827 while (p > 0) { 828 if (flags & VG_MSG_COMMA && 10 == base && 829 0 == (ind-nc) % 3 && 0 != ind) 830 { 831 buf[ind++] = ','; 832 nc++; 833 } 834 buf[ind++] = digits[p % base]; 835 p /= base; 836 } 837 } 838 839 if (neg) 840 buf[ind++] = '-'; 841 842 if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) { 843 for(; ind < width; ind++) { 844 buf[ind] = (flags & VG_MSG_ZJUSTIFY) ? '0': ' '; 845 } 846 } 847 848 /* Reverse copy to buffer. */ 849 ret += ind; 850 for (i = ind -1; i >= 0; i--) { 851 send(buf[i], send_arg2); 852 } 853 if (width > 0 && (flags & VG_MSG_LJUSTIFY)) { 854 for(; ind < width; ind++) { 855 ret++; 856 /* Never pad with zeroes on RHS -- changes the value! */ 857 send(' ', send_arg2); 858 } 859 } 860 return ret; 861 } 862 863 864 /* A simple vprintf(). */ 865 /* EXPORTED */ 866 UInt 867 VG_(debugLog_vprintf) ( 868 void(*send)(HChar,void*), 869 void* send_arg2, 870 const HChar* format, 871 va_list vargs 872 ) 873 { 874 UInt ret = 0; 875 Int i; 876 Int flags; 877 Int width, precision; 878 Int n_ls = 0; 879 Bool is_long, is_sizet, caps; 880 881 /* We assume that vargs has already been initialised by the 882 caller, using va_start, and that the caller will similarly 883 clean up with va_end. 884 */ 885 886 for (i = 0; format[i] != 0; i++) { 887 if (format[i] != '%') { 888 send(format[i], send_arg2); 889 ret++; 890 continue; 891 } 892 i++; 893 /* A '%' has been found. Ignore a trailing %. */ 894 if (format[i] == 0) 895 break; 896 if (format[i] == '%') { 897 /* '%%' is replaced by '%'. */ 898 send('%', send_arg2); 899 ret++; 900 continue; 901 } 902 flags = 0; 903 n_ls = 0; 904 width = 0; /* length of the field. */ 905 precision = -1; /* unspecified precision */ 906 while (1) { 907 switch (format[i]) { 908 case '(': 909 flags |= VG_MSG_PAREN; 910 break; 911 case ',': 912 case '\'': 913 /* If ',' or '\'' follows '%', commas will be inserted. */ 914 flags |= VG_MSG_COMMA; 915 break; 916 case '-': 917 /* If '-' follows '%', justify on the left. */ 918 flags |= VG_MSG_LJUSTIFY; 919 break; 920 case '0': 921 /* If '0' follows '%', pads will be inserted. */ 922 flags |= VG_MSG_ZJUSTIFY; 923 break; 924 case '#': 925 /* If '#' follows '%', alternative format will be used. */ 926 flags |= VG_MSG_ALTFORMAT; 927 break; 928 default: 929 goto parse_fieldwidth; 930 } 931 i++; 932 } 933 parse_fieldwidth: 934 /* Compute the field length. */ 935 if (format[i] == '*') { 936 width = va_arg(vargs, Int); 937 ++i; 938 } else { 939 while (format[i] >= '0' && format[i] <= '9') { 940 width *= 10; 941 width += format[i++] - '0'; 942 } 943 } 944 /* Parse precision, if any. Only meaningful for %f. For all other 945 format specifiers the precision will be silently ignored. */ 946 if (format[i] == '.') { 947 ++i; 948 if (format[i] == '*') { 949 precision = va_arg(vargs, Int); 950 ++i; 951 } else { 952 precision = 0; 953 while (format[i] >= '0' && format[i] <= '9') { 954 precision *= 10; 955 precision += format[i++] - '0'; 956 } 957 } 958 } 959 960 is_sizet = False; 961 if (format[i] == 'z') { 962 is_sizet = True; 963 ++i; 964 } else { 965 while (format[i] == 'l') { 966 i++; 967 n_ls++; 968 } 969 } 970 971 // %d means print a 32-bit integer. 972 // %ld means print a word-size integer. 973 // %lld means print a 64-bit integer. 974 if (0 == n_ls) { is_long = False; } 975 else if (1 == n_ls) { is_long = ( sizeof(void*) == sizeof(Long) ); } 976 else { is_long = True; } 977 978 switch (format[i]) { 979 case 'o': /* %o */ 980 if (flags & VG_MSG_ALTFORMAT) { 981 ret += 2; 982 send('0',send_arg2); 983 } 984 if (is_sizet) 985 ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 986 (ULong)(va_arg (vargs, SizeT))); 987 else if (is_long) 988 ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 989 (ULong)(va_arg (vargs, ULong))); 990 else 991 ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 992 (ULong)(va_arg (vargs, UInt))); 993 break; 994 case 'd': /* %d */ 995 flags |= VG_MSG_SIGNED; 996 if (is_long) 997 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 998 (ULong)(va_arg (vargs, Long))); 999 else 1000 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 1001 (ULong)(va_arg (vargs, Int))); 1002 break; 1003 case 'u': /* %u */ 1004 if (is_sizet) 1005 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 1006 (ULong)(va_arg (vargs, SizeT))); 1007 else if (is_long) 1008 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 1009 (ULong)(va_arg (vargs, ULong))); 1010 else 1011 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 1012 (ULong)(va_arg (vargs, UInt))); 1013 break; 1014 case 'p': 1015 if (format[i+1] == 'S') { 1016 i++; 1017 /* %pS, like %s but escaping chars for XML safety */ 1018 /* Note: simplistic; ignores field width and flags */ 1019 const HChar *str = va_arg (vargs, HChar *); 1020 if (str == NULL) 1021 str = "(null)"; 1022 ret += myvprintf_str_XML_simplistic(send, send_arg2, str); 1023 } else if (format[i+1] == 's') { 1024 i++; 1025 /* %ps, synonym for %s with --xml=no / %pS with --xml=yes */ 1026 const HChar *str = va_arg (vargs, HChar *); 1027 if (str == NULL) 1028 str = "(null)"; 1029 if (clo_xml) 1030 ret += myvprintf_str_XML_simplistic(send, send_arg2, str); 1031 else 1032 ret += myvprintf_str(send, send_arg2, flags, width, str, 1033 False); 1034 } else { 1035 /* %p */ 1036 ret += 2; 1037 send('0',send_arg2); 1038 send('x',send_arg2); 1039 ret += myvprintf_int64(send, send_arg2, flags, 16, width, True, 1040 (ULong)((UWord)va_arg (vargs, void *))); 1041 } 1042 break; 1043 case 'x': /* %x */ 1044 case 'X': /* %X */ 1045 caps = toBool(format[i] == 'X'); 1046 if (flags & VG_MSG_ALTFORMAT) { 1047 ret += 2; 1048 send('0',send_arg2); 1049 send('x',send_arg2); 1050 } 1051 if (is_sizet) 1052 ret += myvprintf_int64(send, send_arg2, flags, 16, width, False, 1053 (ULong)(va_arg (vargs, SizeT))); 1054 else if (is_long) 1055 ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps, 1056 (ULong)(va_arg (vargs, ULong))); 1057 else 1058 ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps, 1059 (ULong)(va_arg (vargs, UInt))); 1060 break; 1061 case 'c': /* %c */ 1062 ret++; 1063 send(va_arg (vargs, int), send_arg2); 1064 break; 1065 case 's': case 'S': { /* %s */ 1066 const HChar *str = va_arg (vargs, HChar *); 1067 if (str == NULL) str = "(null)"; 1068 ret += myvprintf_str(send, send_arg2, 1069 flags, width, str, format[i]=='S'); 1070 break; 1071 } 1072 case 'f': { 1073 /* Print a floating point number in the format x.y without 1074 any exponent. Capabilities are extremely limited, basically 1075 a joke, but good enough for our needs. */ 1076 Double val = va_arg (vargs, Double); 1077 Bool is_negative = False; 1078 Int cnt; 1079 1080 if (val < 0.0) { 1081 is_negative = True; 1082 val = - val; 1083 } 1084 /* If the integral part of the floating point number cannot be 1085 represented by an ULONG_MAX, print '*' characters */ 1086 if (val > (Double)(~0ULL)) { 1087 if (width == 0) width = 6; // say 1088 for (cnt = 0; cnt < width; ++cnt) 1089 send('*', send_arg2); 1090 ret += width; 1091 break; 1092 } 1093 /* The integral part of the floating point number is representable 1094 by an ULong. */ 1095 ULong ipval = val; 1096 Double frac = val - ipval; 1097 1098 if (precision == -1) precision = 6; // say 1099 1100 /* Silently limit the precision to 10 digits. */ 1101 if (precision > 10) precision = 10; 1102 1103 /* Determine fractional part, possibly round up */ 1104 ULong factor = 1; 1105 for (cnt = 0; cnt < precision; ++cnt) 1106 factor *= 10; 1107 ULong frval = frac * factor; 1108 if ((frac * factor - frval) > 0.5) // round up 1109 frval += 1; 1110 /* Check rounding. */ 1111 if (frval == factor) 1112 ipval += 1; 1113 frval %= factor; 1114 1115 /* Find out how many characters are needed to print the number */ 1116 1117 /* The integral part... */ 1118 UInt ipwidth, num_digit = 1; // at least one digit 1119 ULong x, old_x = 0; 1120 for (x = 10; ; old_x = x, x *= 10, ++num_digit) { 1121 if (x <= old_x) break; // overflow occurred 1122 if (ipval < x) break; 1123 } 1124 ipwidth = num_digit; // width of integral part. 1125 if (is_negative) ++num_digit; 1126 if (precision != 0) 1127 num_digit += 1 + precision; 1128 1129 // Print the number 1130 1131 // Fill in blanks on the left 1132 if (num_digit < width && (flags & VG_MSG_LJUSTIFY) == 0) { 1133 for (cnt = 0; cnt < width - num_digit; ++cnt) 1134 send(' ', send_arg2); 1135 ret += width - num_digit; 1136 } 1137 // Sign, maybe 1138 if (is_negative) { 1139 send('-', send_arg2); 1140 ret += 1; 1141 } 1142 // Integral part 1143 ret += myvprintf_int64(send, send_arg2, 0, 10, ipwidth, False, 1144 ipval); 1145 // Decimal point and fractional part 1146 if (precision != 0) { 1147 send('.', send_arg2); 1148 ret += 1; 1149 1150 ret += myvprintf_int64(send, send_arg2, VG_MSG_ZJUSTIFY, 10, 1151 precision, False, frval); 1152 } 1153 // Fill in blanks on the right 1154 if (num_digit < width && (flags & VG_MSG_LJUSTIFY) != 0) { 1155 for (cnt = 0; cnt < width - num_digit; ++cnt) 1156 send(' ', send_arg2); 1157 ret += width - num_digit; 1158 } 1159 break; 1160 } 1161 1162 // case 'y': { /* %y - print symbol */ 1163 // Addr a = va_arg(vargs, Addr); 1164 // 1165 // HChar *name; 1166 // if (VG_(get_fnname_w_offset)(a, &name)) { 1167 // HChar buf[1 + VG_strlen(name) + 1 + 1]; 1168 // if (flags & VG_MSG_PAREN) { 1169 // VG_(sprintf)(str, "(%s)", name): 1170 // } else { 1171 // VG_(sprintf)(str, "%s", name): 1172 // } 1173 // ret += myvprintf_str(send, flags, width, buf, 0); 1174 // } 1175 // break; 1176 // } 1177 default: 1178 break; 1179 } 1180 } 1181 return ret; 1182 } 1183 1184 1185 /*------------------------------------------------------------*/ 1186 /*--- Debuglog stuff. ---*/ 1187 /*------------------------------------------------------------*/ 1188 1189 /* Only print messages whose stated level is less than or equal to 1190 this. By default, it makes this entire subsystem silent. */ 1191 1192 static Int loglevel = 0; 1193 1194 /* Module startup. */ 1195 /* EXPORTED */ 1196 void VG_(debugLog_startup) ( Int level, const HChar* who ) 1197 { 1198 if (level < 0) level = 0; 1199 if (level > 10) level = 10; 1200 loglevel = level; 1201 VG_(debugLog)(1, "debuglog", 1202 "DebugLog system started by %s, " 1203 "level %d logging requested\n", 1204 who, loglevel); 1205 } 1206 1207 /* Get the logging threshold level, as set by the most recent call to 1208 VG_(debugLog_startup), or zero if there have been no such calls so 1209 far. */ 1210 /* EXPORTED */ 1211 Int VG_(debugLog_getLevel) ( void ) 1212 { 1213 return loglevel; 1214 } 1215 1216 1217 /* ------------ */ 1218 1219 typedef 1220 struct { 1221 HChar buf[100]; 1222 Int n; 1223 } 1224 printf_buf; 1225 1226 static void add_to_buf ( HChar c, void* p ) 1227 { 1228 printf_buf* buf = (printf_buf*)p; 1229 1230 if (buf->n >= 100-10 /*paranoia*/ ) { 1231 emit( buf->buf, local_strlen(buf->buf) ); 1232 buf->n = 0; 1233 buf->buf[buf->n] = 0; 1234 } 1235 buf->buf[buf->n++] = c; 1236 buf->buf[buf->n] = 0; 1237 } 1238 1239 /* Send a logging message. Nothing is output unless 'level' 1240 is <= the current loglevel. */ 1241 /* EXPORTED */ 1242 void VG_(debugLog) ( Int level, const HChar* modulename, 1243 const HChar* format, ... ) 1244 { 1245 UInt pid; 1246 Int indent, depth, i; 1247 va_list vargs; 1248 printf_buf buf; 1249 1250 if (level > loglevel) 1251 return; 1252 1253 indent = 2*level - 1; 1254 if (indent < 1) indent = 1; 1255 1256 buf.n = 0; 1257 buf.buf[0] = 0; 1258 pid = local_sys_getpid(); 1259 1260 // Print one '>' in front of the messages for each level of self-hosting 1261 // being performed. 1262 depth = RUNNING_ON_VALGRIND; 1263 for (i = 0; i < depth; i++) { 1264 (void)myvprintf_str ( add_to_buf, &buf, 0, 1, ">", False ); 1265 } 1266 1267 (void)myvprintf_str ( add_to_buf, &buf, 0, 2, "--", False ); 1268 (void)myvprintf_int64 ( add_to_buf, &buf, 0, 10, 1, False, (ULong)pid ); 1269 (void)myvprintf_str ( add_to_buf, &buf, 0, 1, ":", False ); 1270 (void)myvprintf_int64 ( add_to_buf, &buf, 0, 10, 1, False, (ULong)level ); 1271 (void)myvprintf_str ( add_to_buf, &buf, 0, 1, ":", False ); 1272 (void)myvprintf_str ( add_to_buf, &buf, 0, 8, modulename, False ); 1273 (void)myvprintf_str ( add_to_buf, &buf, 0, indent, "", False ); 1274 1275 va_start(vargs,format); 1276 1277 (void) VG_(debugLog_vprintf) ( add_to_buf, &buf, format, vargs ); 1278 1279 if (buf.n > 0) { 1280 emit( buf.buf, local_strlen(buf.buf) ); 1281 } 1282 1283 va_end(vargs); 1284 } 1285 1286 1287 1288 /*--------------------------------------------------------------------*/ 1289 /*--- end m_debuglog.c ---*/ 1290 /*--------------------------------------------------------------------*/ 1291