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-2017 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","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","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_x86_solaris) 516 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 517 { 518 UInt res, err; 519 Bool restart; 520 521 do { 522 /* The Solaris kernel does not restart syscalls automatically so it is 523 done here. */ 524 __asm__ __volatile__ ( 525 "movl %[n], %%eax\n" /* push n */ 526 "pushl %%eax\n" 527 "movl %[buf], %%eax\n" /* push buf */ 528 "pushl %%eax\n" 529 "movl $2, %%eax\n" /* push stderr */ 530 "pushl %%eax\n" 531 "movl $"VG_STRINGIFY(__NR_write)", %%eax\n" 532 "pushl %%eax\n" /* push fake return address */ 533 "int $0x91\n" /* write(stderr, buf, n) */ 534 "movl $0, %%edx\n" /* assume no error */ 535 "jnc 1f\n" /* jump if no error */ 536 "movl $1, %%edx\n" /* set error flag */ 537 "1: " 538 "addl $16, %%esp\n" /* pop x4 */ 539 : "=&a" (res), "=d" (err) 540 : [buf] "g" (buf), [n] "g" (n) 541 : "cc"); 542 restart = err && (res == VKI_EINTR || res == VKI_ERESTART); 543 } while (restart); 544 545 return res; 546 } 547 548 static UInt local_sys_getpid ( void ) 549 { 550 UInt res; 551 552 /* The getpid() syscall never returns EINTR or ERESTART so there is no need 553 for restarting it. */ 554 __asm__ __volatile__ ( 555 "movl $"VG_STRINGIFY(__NR_getpid)", %%eax\n" 556 "int $0x91\n" /* getpid() */ 557 : "=a" (res) 558 : 559 : "edx", "cc"); 560 561 return res; 562 } 563 564 #elif defined(VGP_amd64_solaris) 565 static UInt local_sys_write_stderr ( const HChar* buf, Int n ) 566 { 567 ULong res, err; 568 Bool restart; 569 570 do { 571 /* The Solaris kernel does not restart syscalls automatically so it is 572 done here. */ 573 __asm__ __volatile__ ( 574 "movq $2, %%rdi\n" /* push stderr */ 575 "movq $"VG_STRINGIFY(__NR_write)", %%rax\n" 576 "syscall\n" /* write(stderr, buf, n) */ 577 "movq $0, %%rdx\n" /* assume no error */ 578 "jnc 1f\n" /* jump if no error */ 579 "movq $1, %%rdx\n" /* set error flag */ 580 "1: " 581 : "=a" (res), "=d" (err) 582 : "S" (buf), "d" (n) 583 : "cc"); 584 restart = err && (res == VKI_EINTR || res == VKI_ERESTART); 585 } while (restart); 586 587 return res; 588 } 589 590 static UInt local_sys_getpid ( void ) 591 { 592 UInt res; 593 594 /* The getpid() syscall never returns EINTR or ERESTART so there is no need 595 for restarting it. */ 596 __asm__ __volatile__ ( 597 "movq $"VG_STRINGIFY(__NR_getpid)", %%rax\n" 598 "syscall\n" /* getpid() */ 599 : "=a" (res) 600 : 601 : "edx", "cc"); 602 603 return res; 604 } 605 606 #else 607 # error Unknown platform 608 #endif 609 610 611 /* ----- generic ----- */ 612 613 /* strlen, so we don't need m_libc */ 614 static Int local_strlen ( const HChar* str ) 615 { 616 Int i = 0; 617 while (str[i] != 0) i++; 618 return i; 619 } 620 621 static HChar local_toupper ( HChar c ) 622 { 623 if (c >= 'a' && c <= 'z') 624 return c + ('A' - 'a'); 625 else 626 return c; 627 } 628 629 /* Emit buf[0 .. n-1] to stderr. Unfortunately platform-specific. 630 */ 631 static void emit ( const HChar* buf, Int n ) 632 { 633 if (n >= 1) 634 (void)local_sys_write_stderr(buf, n); 635 } 636 637 638 /*------------------------------------------------------------*/ 639 /*--- A simple, generic, vprintf implementation. ---*/ 640 /*------------------------------------------------------------*/ 641 642 /* ----------------------------------------------- 643 Distantly derived from: 644 645 vprintf replacement for Checker. 646 Copyright 1993, 1994, 1995 Tristan Gingold 647 Written September 1993 Tristan Gingold 648 Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE 649 650 (Checker itself was GPL'd.) 651 ----------------------------------------------- */ 652 653 /* Some flags. */ 654 #define VG_MSG_SIGNED 1 /* The value is signed. */ 655 #define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */ 656 #define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */ 657 #define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */ 658 #define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */ 659 #define VG_MSG_ALTFORMAT 32 /* Convert the value to alternate format */ 660 661 /* Copy a string into the buffer. */ 662 static 663 UInt myvprintf_str ( void(*send)(HChar,void*), 664 void* send_arg2, 665 Int flags, 666 Int width, 667 const HChar* str, 668 Bool capitalise ) 669 { 670 # define MAYBE_TOUPPER(ch) (capitalise ? local_toupper(ch) : (ch)) 671 UInt ret = 0; 672 Int i, extra; 673 Int len = local_strlen(str); 674 675 if (width == 0) { 676 ret += len; 677 for (i = 0; i < len; i++) 678 send(MAYBE_TOUPPER(str[i]), send_arg2); 679 return ret; 680 } 681 682 if (len > width) { 683 ret += width; 684 for (i = 0; i < width; i++) 685 send(MAYBE_TOUPPER(str[i]), send_arg2); 686 return ret; 687 } 688 689 extra = width - len; 690 if (! (flags & VG_MSG_LJUSTIFY)) { 691 ret += extra; 692 for (i = 0; i < extra; i++) 693 send(' ', send_arg2); 694 } 695 ret += len; 696 for (i = 0; i < len; i++) 697 send(MAYBE_TOUPPER(str[i]), send_arg2); 698 if (flags & VG_MSG_LJUSTIFY) { 699 ret += extra; 700 for (i = 0; i < extra; i++) 701 send(' ', send_arg2); 702 } 703 704 # undef MAYBE_TOUPPER 705 return ret; 706 } 707 708 709 /* Copy a string into the buffer, escaping bad XML chars. */ 710 static 711 UInt myvprintf_str_XML_simplistic ( void(*send)(HChar,void*), 712 void* send_arg2, 713 const HChar* str ) 714 { 715 UInt ret = 0; 716 Int i; 717 Int len = local_strlen(str); 718 const HChar* alt; 719 720 for (i = 0; i < len; i++) { 721 switch (str[i]) { 722 case '&': alt = "&"; break; 723 case '<': alt = "<"; break; 724 case '>': alt = ">"; break; 725 default: alt = NULL; 726 } 727 728 if (alt) { 729 while (*alt) { 730 send(*alt, send_arg2); 731 ret++; 732 alt++; 733 } 734 } else { 735 send(str[i], send_arg2); 736 ret++; 737 } 738 } 739 740 return ret; 741 } 742 743 744 /* Write P into the buffer according to these args: 745 * If SIGN is true, p is a signed. 746 * BASE is the base. 747 * If WITH_ZERO is true, '0' must be added. 748 * WIDTH is the width of the field. 749 */ 750 static 751 UInt myvprintf_int64 ( void(*send)(HChar,void*), 752 void* send_arg2, 753 Int flags, 754 Int base, 755 Int width, 756 Bool capitalised, 757 ULong p ) 758 { 759 /* To print an ULong base 2 needs 64 characters. If commas are requested, 760 add 21. Plus 1 for a possible sign plus 1 for \0. Makes 87 -- so let's 761 say 90. The size of BUF needs to be max(90, WIDTH + 1) */ 762 HChar buf[width + 1 > 90 ? width + 1 : 90]; 763 Int ind = 0; 764 Int i, nc = 0; 765 Bool neg = False; 766 const HChar* digits = capitalised ? "0123456789ABCDEF" : "0123456789abcdef"; 767 UInt ret = 0; 768 769 if (base < 2 || base > 16) 770 return ret; 771 772 if ((flags & VG_MSG_SIGNED) && (Long)p < 0) { 773 p = - (Long)p; 774 neg = True; 775 } 776 777 if (p == 0) 778 buf[ind++] = '0'; 779 else { 780 while (p > 0) { 781 if (flags & VG_MSG_COMMA && 10 == base && 782 0 == (ind-nc) % 3 && 0 != ind) 783 { 784 buf[ind++] = ','; 785 nc++; 786 } 787 buf[ind++] = digits[p % base]; 788 p /= base; 789 } 790 } 791 792 if (neg) 793 buf[ind++] = '-'; 794 795 if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) { 796 for(; ind < width; ind++) { 797 buf[ind] = (flags & VG_MSG_ZJUSTIFY) ? '0': ' '; 798 } 799 } 800 801 /* Reverse copy to buffer. */ 802 ret += ind; 803 for (i = ind -1; i >= 0; i--) { 804 send(buf[i], send_arg2); 805 } 806 if (width > 0 && (flags & VG_MSG_LJUSTIFY)) { 807 for(; ind < width; ind++) { 808 ret++; 809 /* Never pad with zeroes on RHS -- changes the value! */ 810 send(' ', send_arg2); 811 } 812 } 813 return ret; 814 } 815 816 817 /* A simple vprintf(). */ 818 /* EXPORTED */ 819 UInt 820 VG_(debugLog_vprintf) ( 821 void(*send)(HChar,void*), 822 void* send_arg2, 823 const HChar* format, 824 va_list vargs 825 ) 826 { 827 UInt ret = 0; 828 Int i; 829 Int flags; 830 Int width, precision; 831 Int n_ls = 0; 832 Bool is_long, is_sizet, caps; 833 834 /* We assume that vargs has already been initialised by the 835 caller, using va_start, and that the caller will similarly 836 clean up with va_end. 837 */ 838 839 for (i = 0; format[i] != 0; i++) { 840 if (format[i] != '%') { 841 send(format[i], send_arg2); 842 ret++; 843 continue; 844 } 845 i++; 846 /* A '%' has been found. Ignore a trailing %. */ 847 if (format[i] == 0) 848 break; 849 if (format[i] == '%') { 850 /* '%%' is replaced by '%'. */ 851 send('%', send_arg2); 852 ret++; 853 continue; 854 } 855 flags = 0; 856 n_ls = 0; 857 width = 0; /* length of the field. */ 858 precision = -1; /* unspecified precision */ 859 while (1) { 860 switch (format[i]) { 861 case '(': 862 flags |= VG_MSG_PAREN; 863 break; 864 case ',': 865 case '\'': 866 /* If ',' or '\'' follows '%', commas will be inserted. */ 867 flags |= VG_MSG_COMMA; 868 break; 869 case '-': 870 /* If '-' follows '%', justify on the left. */ 871 flags |= VG_MSG_LJUSTIFY; 872 break; 873 case '0': 874 /* If '0' follows '%', pads will be inserted. */ 875 flags |= VG_MSG_ZJUSTIFY; 876 break; 877 case '#': 878 /* If '#' follows '%', alternative format will be used. */ 879 flags |= VG_MSG_ALTFORMAT; 880 break; 881 default: 882 goto parse_fieldwidth; 883 } 884 i++; 885 } 886 parse_fieldwidth: 887 /* Compute the field length. */ 888 if (format[i] == '*') { 889 width = va_arg(vargs, Int); 890 ++i; 891 } else { 892 while (format[i] >= '0' && format[i] <= '9') { 893 width *= 10; 894 width += format[i++] - '0'; 895 } 896 } 897 /* Parse precision, if any. Only meaningful for %f. For all other 898 format specifiers the precision will be silently ignored. */ 899 if (format[i] == '.') { 900 ++i; 901 if (format[i] == '*') { 902 precision = va_arg(vargs, Int); 903 ++i; 904 } else { 905 precision = 0; 906 while (format[i] >= '0' && format[i] <= '9') { 907 precision *= 10; 908 precision += format[i++] - '0'; 909 } 910 } 911 } 912 913 is_sizet = False; 914 if (format[i] == 'z') { 915 is_sizet = True; 916 ++i; 917 } else { 918 while (format[i] == 'l') { 919 i++; 920 n_ls++; 921 } 922 } 923 924 // %d means print a 32-bit integer. 925 // %ld means print a word-size integer. 926 // %lld means print a 64-bit integer. 927 if (0 == n_ls) { is_long = False; } 928 else if (1 == n_ls) { is_long = ( sizeof(void*) == sizeof(Long) ); } 929 else { is_long = True; } 930 931 switch (format[i]) { 932 case 'o': /* %o */ 933 if (flags & VG_MSG_ALTFORMAT) { 934 ret += 2; 935 send('0',send_arg2); 936 } 937 if (is_sizet) 938 ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 939 (ULong)(va_arg (vargs, SizeT))); 940 else if (is_long) 941 ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 942 (ULong)(va_arg (vargs, ULong))); 943 else 944 ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 945 (ULong)(va_arg (vargs, UInt))); 946 break; 947 case 'd': /* %d */ 948 flags |= VG_MSG_SIGNED; 949 if (is_long) 950 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 951 (ULong)(va_arg (vargs, Long))); 952 else 953 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 954 (ULong)(va_arg (vargs, Int))); 955 break; 956 case 'u': /* %u */ 957 if (is_sizet) 958 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 959 (ULong)(va_arg (vargs, SizeT))); 960 else if (is_long) 961 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 962 (ULong)(va_arg (vargs, ULong))); 963 else 964 ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 965 (ULong)(va_arg (vargs, UInt))); 966 break; 967 case 'p': 968 if (format[i+1] == 'S') { 969 i++; 970 /* %pS, like %s but escaping chars for XML safety */ 971 /* Note: simplistic; ignores field width and flags */ 972 const HChar *str = va_arg (vargs, HChar *); 973 if (str == NULL) 974 str = "(null)"; 975 ret += myvprintf_str_XML_simplistic(send, send_arg2, str); 976 } else if (format[i+1] == 's') { 977 i++; 978 /* %ps, synonym for %s with --xml=no / %pS with --xml=yes */ 979 const HChar *str = va_arg (vargs, HChar *); 980 if (str == NULL) 981 str = "(null)"; 982 if (clo_xml) 983 ret += myvprintf_str_XML_simplistic(send, send_arg2, str); 984 else 985 ret += myvprintf_str(send, send_arg2, flags, width, str, 986 False); 987 } else { 988 /* %p */ 989 ret += 2; 990 send('0',send_arg2); 991 send('x',send_arg2); 992 ret += myvprintf_int64(send, send_arg2, flags, 16, width, True, 993 (ULong)((UWord)va_arg (vargs, void *))); 994 } 995 break; 996 case 'x': /* %x */ 997 case 'X': /* %X */ 998 caps = toBool(format[i] == 'X'); 999 if (flags & VG_MSG_ALTFORMAT) { 1000 ret += 2; 1001 send('0',send_arg2); 1002 send('x',send_arg2); 1003 } 1004 if (is_sizet) 1005 ret += myvprintf_int64(send, send_arg2, flags, 16, width, False, 1006 (ULong)(va_arg (vargs, SizeT))); 1007 else if (is_long) 1008 ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps, 1009 (ULong)(va_arg (vargs, ULong))); 1010 else 1011 ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps, 1012 (ULong)(va_arg (vargs, UInt))); 1013 break; 1014 case 'c': /* %c */ 1015 ret++; 1016 send(va_arg (vargs, int), send_arg2); 1017 break; 1018 case 's': case 'S': { /* %s */ 1019 const HChar *str = va_arg (vargs, HChar *); 1020 if (str == NULL) str = "(null)"; 1021 ret += myvprintf_str(send, send_arg2, 1022 flags, width, str, format[i]=='S'); 1023 break; 1024 } 1025 case 'f': { 1026 /* Print a floating point number in the format x.y without 1027 any exponent. Capabilities are extremely limited, basically 1028 a joke, but good enough for our needs. */ 1029 Double val = va_arg (vargs, Double); 1030 Bool is_negative = False; 1031 Int cnt; 1032 1033 if (val < 0.0) { 1034 is_negative = True; 1035 val = - val; 1036 } 1037 /* If the integral part of the floating point number cannot be 1038 represented by an ULONG_MAX, print '*' characters */ 1039 if (val > (Double)(~0ULL)) { 1040 if (width == 0) width = 6; // say 1041 for (cnt = 0; cnt < width; ++cnt) 1042 send('*', send_arg2); 1043 ret += width; 1044 break; 1045 } 1046 /* The integral part of the floating point number is representable 1047 by an ULong. */ 1048 ULong ipval = val; 1049 Double frac = val - ipval; 1050 1051 if (precision == -1) precision = 6; // say 1052 1053 /* Silently limit the precision to 10 digits. */ 1054 if (precision > 10) precision = 10; 1055 1056 /* Determine fractional part, possibly round up */ 1057 ULong factor = 1; 1058 for (cnt = 0; cnt < precision; ++cnt) 1059 factor *= 10; 1060 ULong frval = frac * factor; 1061 if ((frac * factor - frval) > 0.5) // round up 1062 frval += 1; 1063 /* Check rounding. */ 1064 if (frval == factor) 1065 ipval += 1; 1066 frval %= factor; 1067 1068 /* Find out how many characters are needed to print the number */ 1069 1070 /* The integral part... */ 1071 UInt ipwidth, num_digit = 1; // at least one digit 1072 ULong x, old_x = 0; 1073 for (x = 10; ; old_x = x, x *= 10, ++num_digit) { 1074 if (x <= old_x) break; // overflow occurred 1075 if (ipval < x) break; 1076 } 1077 ipwidth = num_digit; // width of integral part. 1078 if (is_negative) ++num_digit; 1079 if (precision != 0) 1080 num_digit += 1 + precision; 1081 1082 // Print the number 1083 1084 // Fill in blanks on the left 1085 if (num_digit < width && (flags & VG_MSG_LJUSTIFY) == 0) { 1086 for (cnt = 0; cnt < width - num_digit; ++cnt) 1087 send(' ', send_arg2); 1088 ret += width - num_digit; 1089 } 1090 // Sign, maybe 1091 if (is_negative) { 1092 send('-', send_arg2); 1093 ret += 1; 1094 } 1095 // Integral part 1096 ret += myvprintf_int64(send, send_arg2, 0, 10, ipwidth, False, 1097 ipval); 1098 // Decimal point and fractional part 1099 if (precision != 0) { 1100 send('.', send_arg2); 1101 ret += 1; 1102 1103 ret += myvprintf_int64(send, send_arg2, VG_MSG_ZJUSTIFY, 10, 1104 precision, False, frval); 1105 } 1106 // Fill in blanks on the right 1107 if (num_digit < width && (flags & VG_MSG_LJUSTIFY) != 0) { 1108 for (cnt = 0; cnt < width - num_digit; ++cnt) 1109 send(' ', send_arg2); 1110 ret += width - num_digit; 1111 } 1112 break; 1113 } 1114 1115 // case 'y': { /* %y - print symbol */ 1116 // Addr a = va_arg(vargs, Addr); 1117 // 1118 // HChar *name; 1119 // if (VG_(get_fnname_w_offset)(a, &name)) { 1120 // HChar buf[1 + VG_strlen(name) + 1 + 1]; 1121 // if (flags & VG_MSG_PAREN) { 1122 // VG_(sprintf)(str, "(%s)", name): 1123 // } else { 1124 // VG_(sprintf)(str, "%s", name): 1125 // } 1126 // ret += myvprintf_str(send, flags, width, buf, 0); 1127 // } 1128 // break; 1129 // } 1130 default: 1131 break; 1132 } 1133 } 1134 return ret; 1135 } 1136 1137 1138 /*------------------------------------------------------------*/ 1139 /*--- Debuglog stuff. ---*/ 1140 /*------------------------------------------------------------*/ 1141 1142 /* Only print messages whose stated level is less than or equal to 1143 this. By default, it makes this entire subsystem silent. */ 1144 1145 static Int loglevel = 0; 1146 1147 /* Module startup. */ 1148 /* EXPORTED */ 1149 void VG_(debugLog_startup) ( Int level, const HChar* who ) 1150 { 1151 if (level < 0) level = 0; 1152 if (level > 10) level = 10; 1153 loglevel = level; 1154 VG_(debugLog)(1, "debuglog", 1155 "DebugLog system started by %s, " 1156 "level %d logging requested\n", 1157 who, loglevel); 1158 } 1159 1160 /* Get the logging threshold level, as set by the most recent call to 1161 VG_(debugLog_startup), or zero if there have been no such calls so 1162 far. */ 1163 /* EXPORTED */ 1164 Int VG_(debugLog_getLevel) ( void ) 1165 { 1166 return loglevel; 1167 } 1168 1169 1170 /* ------------ */ 1171 1172 typedef 1173 struct { 1174 HChar buf[100]; 1175 Int n; 1176 } 1177 printf_buf; 1178 1179 static void add_to_buf ( HChar c, void* p ) 1180 { 1181 printf_buf* buf = (printf_buf*)p; 1182 1183 if (buf->n >= 100-10 /*paranoia*/ ) { 1184 emit( buf->buf, local_strlen(buf->buf) ); 1185 buf->n = 0; 1186 buf->buf[buf->n] = 0; 1187 } 1188 buf->buf[buf->n++] = c; 1189 buf->buf[buf->n] = 0; 1190 } 1191 1192 /* Send a logging message. Nothing is output unless 'level' 1193 is <= the current loglevel. */ 1194 /* EXPORTED */ 1195 void VG_(debugLog) ( Int level, const HChar* modulename, 1196 const HChar* format, ... ) 1197 { 1198 UInt pid; 1199 Int indent, depth, i; 1200 va_list vargs; 1201 printf_buf buf; 1202 1203 if (level > loglevel) 1204 return; 1205 1206 indent = 2*level - 1; 1207 if (indent < 1) indent = 1; 1208 1209 buf.n = 0; 1210 buf.buf[0] = 0; 1211 pid = local_sys_getpid(); 1212 1213 // Print one '>' in front of the messages for each level of self-hosting 1214 // being performed. 1215 depth = RUNNING_ON_VALGRIND; 1216 for (i = 0; i < depth; i++) { 1217 (void)myvprintf_str ( add_to_buf, &buf, 0, 1, ">", False ); 1218 } 1219 1220 (void)myvprintf_str ( add_to_buf, &buf, 0, 2, "--", False ); 1221 (void)myvprintf_int64 ( add_to_buf, &buf, 0, 10, 1, False, (ULong)pid ); 1222 (void)myvprintf_str ( add_to_buf, &buf, 0, 1, ":", False ); 1223 (void)myvprintf_int64 ( add_to_buf, &buf, 0, 10, 1, False, (ULong)level ); 1224 (void)myvprintf_str ( add_to_buf, &buf, 0, 1, ":", False ); 1225 (void)myvprintf_str ( add_to_buf, &buf, 0, 8, modulename, False ); 1226 (void)myvprintf_str ( add_to_buf, &buf, 0, indent, "", False ); 1227 1228 va_start(vargs,format); 1229 1230 (void) VG_(debugLog_vprintf) ( add_to_buf, &buf, format, vargs ); 1231 1232 if (buf.n > 0) { 1233 emit( buf.buf, local_strlen(buf.buf) ); 1234 } 1235 1236 va_end(vargs); 1237 } 1238 1239 1240 1241 /*--------------------------------------------------------------------*/ 1242 /*--- end m_debuglog.c ---*/ 1243 /*--------------------------------------------------------------------*/ 1244