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-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 = "&amp;"; break;
    770          case '<': alt = "&lt;"; break;
    771          case '>': alt = "&gt;"; 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