Home | History | Annotate | Download | only in coregrind
      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 = "&amp;"; break;
    723          case '<': alt = "&lt;"; break;
    724          case '>': alt = "&gt;"; 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