2 /*--------------------------------------------------------------------*/
3 /*--- Debug (not-for-user) logging; also vprintf. m_debuglog.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2013 Julian Seward
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
32 /* Performs low-level debug logging that can safely run immediately
33 after startup. To minimise the dependencies on any other parts of
34 the system, the only place the debug output may go is file
35 descriptor 2 (stderr).
37 /* This is the first-initialised module in the entire system!
38 Therefore it is CRITICAL that it does not depend on any other code
39 running first. Hence only the following very limited includes. We
40 cannot depend (directly or indirectly) on any dynamic memory
41 allocation facilities, nor on the m_libc facilities, since the
42 latter depend on this module. DO NOT MESS WITH THESE INCLUDES
43 UNLESS YOU ARE 100% CERTAIN YOU UNDERSTAND THE CONSEQUENCES.
46 /* This module is also notable because it is linked into both
49 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
50 of syscalls rather than the vanilla version, if a _nocancel version
51 is available. See docs/internals/Darwin-notes.txt for the reason
54 #include "pub_core_basics.h" /* basic types */
55 #include "pub_core_vkiscnums.h" /* for syscall numbers */
56 #include "pub_core_debuglog.h" /* our own iface */
57 #include "pub_core_clreq.h" /* for RUNNING_ON_VALGRIND */
61 void VG_(debugLog_setXml
)(Bool xml
)
66 /*------------------------------------------------------------*/
67 /*--- Stuff to make us completely independent. ---*/
68 /*------------------------------------------------------------*/
70 /* ----- Platform-specifics ----- */
72 #if defined(VGP_x86_linux)
74 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
80 "movl $"VG_STRINGIFY(__NR_write
)", %%eax\n" /* %eax = __NR_write */
81 "movl $2, %%ebx\n" /* %ebx = stderr */
82 "int $0x80\n" /* write(stderr, buf, n) */
84 : /*wr*/ "=a" (result
)
85 : /*rd*/ "c" (buf
), "d" (n
)
86 : /*trash*/ "edi", "memory", "cc"
89 return result
>= 0 ? result
: -1;
92 static UInt
local_sys_getpid ( void )
96 "movl $"VG_STRINGIFY(__NR_getpid
)", %%eax\n" /* %eax = __NR_getpid */
97 "int $0x80\n" /* getpid() */
98 "movl %%eax, %0\n" /* set __res = eax */
105 #elif defined(VGP_amd64_linux)
107 __attribute__((noinline
))
108 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
110 volatile Long block
[2];
111 block
[0] = (Long
)buf
;
114 "subq $256, %%rsp\n" /* don't trash the stack redzone */
115 "pushq %%r15\n" /* r15 is callee-save */
116 "movq %0, %%r15\n" /* r15 = &block */
117 "pushq %%r15\n" /* save &block */
118 "movq $"VG_STRINGIFY(__NR_write
)", %%rax\n" /* rax = __NR_write */
119 "movq $2, %%rdi\n" /* rdi = stderr */
120 "movq 0(%%r15), %%rsi\n" /* rsi = buf */
121 "movq 8(%%r15), %%rdx\n" /* rdx = n */
122 "syscall\n" /* write(stderr, buf, n) */
123 "popq %%r15\n" /* reestablish &block */
124 "movq %%rax, 0(%%r15)\n" /* block[0] = result */
125 "popq %%r15\n" /* restore r15 */
126 "addq $256, %%rsp\n" /* restore stack ptr */
129 : /*trash*/ "rax", "rdi", "rsi", "rdx", "memory", "cc"
133 return (UInt
)block
[0];
136 static UInt
local_sys_getpid ( void )
140 "movq $"VG_STRINGIFY(__NR_getpid
)", %%rax\n" /* %rax = __NR_getpid */
141 "syscall\n" /* getpid() */
142 "movl %%eax, %0\n" /* set __res = %eax */
149 #elif defined(VGP_ppc32_linux)
151 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
153 volatile Int block
[2];
158 "mr 5,%0\n\t" /* r5 = &block[0] */
159 "stw 5,0(1)\n\t" /* stash on stack */
160 "li 0,"VG_STRINGIFY(__NR_write
)"\n\t" /* set %r0 = __NR_write */
161 "li 3,2\n\t" /* set %r3 = stderr */
162 "lwz 4,0(5)\n\t" /* set %r4 = buf */
163 "lwz 5,4(5)\n\t" /* set %r5 = n */
164 "sc\n\t" /* write(stderr, buf, n) */
167 "stw 3,0(5)\n" /* block[0] = result */
170 : "cc","memory","cr0","ctr",
171 "r0","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12"
175 return (UInt
)block
[0];
178 static UInt
local_sys_getpid ( void )
180 register UInt __res
__asm__ ("r3");
186 : "cc","memory","cr0","ctr",
187 "r0","r2","r4","r5","r6","r7","r8","r9","r10","r11","r12"
192 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
194 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
196 volatile Long block
[2];
197 block
[0] = (Long
)buf
;
201 "mr 5,%0\n\t" /* r5 = &block[0] */
202 "std 5,0(1)\n\t" /* stash on stack */
203 "li 0,"VG_STRINGIFY(__NR_write
)"\n\t" /* %r0 = __NR_write */
204 "li 3,2\n\t" /* set %r3 = stderr */
205 "ld 4,0(5)\n\t" /* set %r4 = buf */
206 "ld 5,8(5)\n\t" /* set %r5 = n */
207 "sc\n\t" /* write(stderr, buf, n) */
210 "std 3,0(5)\n" /* block[0] = result */
213 : "cc","memory","cr0","ctr",
214 "r0","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12"
218 return (UInt
)(Int
)block
[0];
221 static UInt
local_sys_getpid ( void )
223 register ULong __res
__asm__ ("r3");
229 : "cc","memory","cr0","ctr",
230 "r0","r2","r4","r5","r6","r7","r8","r9","r10","r11","r12"
235 #elif defined(VGP_arm_linux)
237 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
239 volatile Int block
[2];
243 "mov r0, #2\n\t" /* stderr */
244 "ldr r1, [%0]\n\t" /* buf */
245 "ldr r2, [%0, #4]\n\t" /* n */
246 "mov r7, #"VG_STRINGIFY(__NR_write
)"\n\t"
247 "svc 0x0\n" /* write() */
251 : "r0","r1","r2","r7"
255 return (UInt
)block
[0];
258 static UInt
local_sys_getpid ( void )
262 "mov r7, #"VG_STRINGIFY(__NR_getpid
)"\n"
263 "svc 0x0\n" /* getpid() */
271 #elif defined(VGP_arm64_linux)
273 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
275 volatile ULong block
[2];
276 block
[0] = (ULong
)buf
;
279 "mov x0, #2\n\t" /* stderr */
280 "ldr x1, [%0]\n\t" /* buf */
281 "ldr x2, [%0, #8]\n\t" /* n */
282 "mov x8, #"VG_STRINGIFY(__NR_write
)"\n\t"
283 "svc 0x0\n" /* write() */
287 : "x0","x1","x2","x7"
291 return (UInt
)block
[0];
294 static UInt
local_sys_getpid ( void )
298 "mov x8, #"VG_STRINGIFY(__NR_getpid
)"\n"
299 "svc 0x0\n" /* getpid() */
307 #elif defined(VGP_x86_darwin)
309 /* We would use VG_DARWIN_SYSNO_TO_KERNEL instead of VG_DARWIN_SYSNO_INDEX
310 except that the former has a C ternary ?: operator which isn't valid in
311 asm code. Both macros give the same results for Unix-class syscalls (which
312 these all are, as identified by the use of 'int 0x80'). */
313 __attribute__((noinline
))
314 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
318 "movl %2, %%eax\n" /* push n */
320 "movl %1, %%eax\n" /* push buf */
322 "movl $2, %%eax\n" /* push stderr */
324 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_INDEX(__NR_write_nocancel
))
326 "pushl %%eax\n" /* push fake return address */
327 "int $0x80\n" /* write(stderr, buf, n) */
328 "jnc 1f\n" /* jump if no error */
329 "movl $-1, %%eax\n" /* return -1 if error */
331 "movl %%eax, %0\n" /* __res = eax */
332 "addl $16, %%esp\n" /* pop x4 */
340 static UInt
local_sys_getpid ( void )
344 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_INDEX(__NR_getpid
))", %%eax\n"
345 "int $0x80\n" /* getpid() */
346 "movl %%eax, %0\n" /* set __res = eax */
353 #elif defined(VGP_amd64_darwin)
355 __attribute__((noinline
))
356 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
360 "movq $2, %%rdi\n" /* push stderr */
361 "movq %1, %%rsi\n" /* push buf */
362 "movl %2, %%edx\n" /* push n */
363 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_FOR_KERNEL(__NR_write_nocancel
))
365 "syscall\n" /* write(stderr, buf, n) */
366 "jnc 1f\n" /* jump if no error */
367 "movq $-1, %%rax\n" /* return -1 if error */
369 "movl %%eax, %0\n" /* __res = eax */
372 : "rdi", "rsi", "rdx", "rcx", "rax", "cc" );
376 static UInt
local_sys_getpid ( void )
380 "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_FOR_KERNEL(__NR_getpid
))", %%eax\n"
381 "syscall\n" /* getpid() */
382 "movl %%eax, %0\n" /* set __res = eax */
385 : "rax", "rcx", "cc" );
389 #elif defined(VGP_s390x_linux)
391 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
393 register Int r2
asm("2") = 2; /* file descriptor STDERR */
394 register const HChar
* r3
asm("3") = buf
;
395 register ULong r4
asm("4") = n
;
396 register ULong r2_res
asm("2");
399 __asm__
__volatile__ (
409 if (__res
>= (ULong
)(-125))
411 return (UInt
)(__res
);
414 static UInt
local_sys_getpid ( void )
416 register ULong r2
asm("2");
419 __asm__
__volatile__ (
426 if (__res
>= (ULong
)(-125))
428 return (UInt
)(__res
);
431 #elif defined(VGP_mips32_linux)
433 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
435 volatile Int block
[2];
439 "li $4, 2\n\t" /* stderr */
440 "lw $5, 0(%0)\n\t" /* buf */
441 "lw $6, 4(%0)\n\t" /* n */
443 "li $2, %1\n\t" /* set v0 = __NR_write */
444 "syscall\n\t" /* write() */
447 : "r" (block
), "n" (__NR_write
)
448 : "2", "4", "5", "6", "7"
452 return (UInt
)block
[0];
455 static UInt
local_sys_getpid ( void )
459 "li $2, %1\n\t" /* set v0 = __NR_getpid */
460 "syscall\n\t" /* getpid() */
469 #elif defined(VGP_mips64_linux)
471 static UInt
local_sys_write_stderr ( const HChar
* buf
, Int n
)
473 volatile Long block
[2];
474 block
[0] = (Long
)buf
;
477 "li $4, 2\n\t" /* std output*/
478 "ld $5, 0(%0)\n\t" /*$5 = buf*/
479 "ld $6, 8(%0)\n\t" /*$6 = n */
481 "li $2, %1\n\t" /* set v0 = __NR_write */
485 : /*rd*/ "r" (block
), "n" (__NR_write
)
486 : "2", "4", "5", "6", "7"
490 return (UInt
)(Int
)block
[0];
493 static UInt
local_sys_getpid ( void )
497 "li $2, %1\n\t" /* set v0 = __NR_getpid */
498 "syscall\n\t" /* getpid() */
504 return (UInt
)(__res
);
508 # error Unknown platform
512 /* ----- generic ----- */
514 /* strlen, so we don't need m_libc */
515 static Int
local_strlen ( const HChar
* str
)
518 while (str
[i
] != 0) i
++;
522 static HChar
local_toupper ( HChar c
)
524 if (c
>= 'a' && c
<= 'z')
525 return c
+ ('A' - 'a');
530 /* Emit buf[0 .. n-1] to stderr. Unfortunately platform-specific.
532 static void emit ( const HChar
* buf
, Int n
)
535 (void)local_sys_write_stderr(buf
, n
);
539 /*------------------------------------------------------------*/
540 /*--- A simple, generic, vprintf implementation. ---*/
541 /*------------------------------------------------------------*/
543 /* -----------------------------------------------
544 Distantly derived from:
546 vprintf replacement for Checker.
547 Copyright 1993, 1994, 1995 Tristan Gingold
548 Written September 1993 Tristan Gingold
549 Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE
551 (Checker itself was GPL'd.)
552 ----------------------------------------------- */
555 #define VG_MSG_SIGNED 1 /* The value is signed. */
556 #define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
557 #define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
558 #define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
559 #define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
560 #define VG_MSG_ALTFORMAT 32 /* Convert the value to alternate format */
562 /* Copy a string into the buffer. */
564 UInt
myvprintf_str ( void(*send
)(HChar
,void*),
571 # define MAYBE_TOUPPER(ch) (capitalise ? local_toupper(ch) : (ch))
574 Int len
= local_strlen(str
);
578 for (i
= 0; i
< len
; i
++)
579 send(MAYBE_TOUPPER(str
[i
]), send_arg2
);
585 for (i
= 0; i
< width
; i
++)
586 send(MAYBE_TOUPPER(str
[i
]), send_arg2
);
591 if (flags
& VG_MSG_LJUSTIFY
) {
593 for (i
= 0; i
< extra
; i
++)
594 send(' ', send_arg2
);
597 for (i
= 0; i
< len
; i
++)
598 send(MAYBE_TOUPPER(str
[i
]), send_arg2
);
599 if (!(flags
& VG_MSG_LJUSTIFY
)) {
601 for (i
= 0; i
< extra
; i
++)
602 send(' ', send_arg2
);
605 # undef MAYBE_TOUPPER
610 /* Copy a string into the buffer, escaping bad XML chars. */
612 UInt
myvprintf_str_XML_simplistic ( void(*send
)(HChar
,void*),
618 Int len
= local_strlen(str
);
621 for (i
= 0; i
< len
; i
++) {
623 case '&': alt
= "&"; break;
624 case '<': alt
= "<"; break;
625 case '>': alt
= ">"; break;
631 send(*alt
, send_arg2
);
636 send(str
[i
], send_arg2
);
645 /* Write P into the buffer according to these args:
646 * If SIGN is true, p is a signed.
648 * If WITH_ZERO is true, '0' must be added.
649 * WIDTH is the width of the field.
652 UInt
myvprintf_int64 ( void(*send
)(HChar
,void*),
664 const HChar
* digits
= capitalised
? "0123456789ABCDEF" : "0123456789abcdef";
667 if (base
< 2 || base
> 16)
670 if ((flags
& VG_MSG_SIGNED
) && (Long
)p
< 0) {
679 if (flags
& VG_MSG_COMMA
&& 10 == base
&&
680 0 == (ind
-nc
) % 3 && 0 != ind
)
685 buf
[ind
++] = digits
[p
% base
];
693 if (width
> 0 && !(flags
& VG_MSG_LJUSTIFY
)) {
694 for(; ind
< width
; ind
++) {
695 /* vg_assert(ind < 39); */
700 buf
[ind
] = (flags
& VG_MSG_ZJUSTIFY
) ? '0': ' ';
704 /* Reverse copy to buffer. */
706 for (i
= ind
-1; i
>= 0; i
--) {
707 send(buf
[i
], send_arg2
);
709 if (width
> 0 && (flags
& VG_MSG_LJUSTIFY
)) {
710 for(; ind
< width
; ind
++) {
712 /* Never pad with zeroes on RHS -- changes the value! */
713 send(' ', send_arg2
);
720 /* A simple vprintf(). */
723 VG_(debugLog_vprintf
) (
724 void(*send
)(HChar
,void*),
737 /* We assume that vargs has already been initialised by the
738 caller, using va_start, and that the caller will similarly
739 clean up with va_end.
742 for (i
= 0; format
[i
] != 0; i
++) {
743 if (format
[i
] != '%') {
744 send(format
[i
], send_arg2
);
749 /* A '%' has been found. Ignore a trailing %. */
752 if (format
[i
] == '%') {
753 /* '%%' is replaced by '%'. */
754 send('%', send_arg2
);
760 width
= 0; /* length of the field. */
764 flags
|= VG_MSG_PAREN
;
768 /* If ',' or '\'' follows '%', commas will be inserted. */
769 flags
|= VG_MSG_COMMA
;
772 /* If '-' follows '%', justify on the left. */
773 flags
|= VG_MSG_LJUSTIFY
;
776 /* If '0' follows '%', pads will be inserted. */
777 flags
|= VG_MSG_ZJUSTIFY
;
780 /* If '#' follows '%', alternative format will be used. */
781 flags
|= VG_MSG_ALTFORMAT
;
784 goto parse_fieldwidth
;
789 /* Compute the field length. */
790 while (format
[i
] >= '0' && format
[i
] <= '9') {
792 width
+= format
[i
++] - '0';
794 while (format
[i
] == 'l') {
799 // %d means print a 32-bit integer.
800 // %ld means print a word-size integer.
801 // %lld means print a 64-bit integer.
802 if (0 == n_ls
) { is_long
= False
; }
803 else if (1 == n_ls
) { is_long
= ( sizeof(void*) == sizeof(Long
) ); }
804 else { is_long
= True
; }
808 if (flags
& VG_MSG_ALTFORMAT
) {
813 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 8, width
, False
,
814 (ULong
)(va_arg (vargs
, ULong
)));
816 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 8, width
, False
,
817 (ULong
)(va_arg (vargs
, UInt
)));
820 flags
|= VG_MSG_SIGNED
;
822 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 10, width
, False
,
823 (ULong
)(va_arg (vargs
, Long
)));
825 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 10, width
, False
,
826 (ULong
)(va_arg (vargs
, Int
)));
830 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 10, width
, False
,
831 (ULong
)(va_arg (vargs
, ULong
)));
833 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 10, width
, False
,
834 (ULong
)(va_arg (vargs
, UInt
)));
837 if (format
[i
+1] == 'S') {
839 /* %pS, like %s but escaping chars for XML safety */
840 /* Note: simplistic; ignores field width and flags */
841 const HChar
*str
= va_arg (vargs
, HChar
*);
844 ret
+= myvprintf_str_XML_simplistic(send
, send_arg2
, str
);
845 } else if (format
[i
+1] == 's') {
847 /* %ps, synonym for %s with --xml=no / %pS with --xml=yes */
848 const HChar
*str
= va_arg (vargs
, HChar
*);
852 ret
+= myvprintf_str_XML_simplistic(send
, send_arg2
, str
);
854 ret
+= myvprintf_str(send
, send_arg2
, flags
, width
, str
,
861 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 16, width
, True
,
862 (ULong
)((UWord
)va_arg (vargs
, void *)));
867 caps
= toBool(format
[i
] == 'X');
868 if (flags
& VG_MSG_ALTFORMAT
) {
874 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 16, width
, caps
,
875 (ULong
)(va_arg (vargs
, ULong
)));
877 ret
+= myvprintf_int64(send
, send_arg2
, flags
, 16, width
, caps
,
878 (ULong
)(va_arg (vargs
, UInt
)));
882 send(va_arg (vargs
, int), send_arg2
);
884 case 's': case 'S': { /* %s */
885 const HChar
*str
= va_arg (vargs
, HChar
*);
886 if (str
== NULL
) str
= "(null)";
887 ret
+= myvprintf_str(send
, send_arg2
,
888 flags
, width
, str
, format
[i
]=='S');
892 // case 'y': { /* %y - print symbol */
893 // Addr a = va_arg(vargs, Addr);
896 // if (VG_(get_fnname_w_offset)(a, &name)) {
897 // HChar buf[1 + VG_strlen(name) + 1 + 1];
898 // if (flags & VG_MSG_PAREN) {
899 // VG_(sprintf)(str, "(%s)", name):
901 // VG_(sprintf)(str, "%s", name):
903 // ret += myvprintf_str(send, flags, width, buf, 0);
915 /*------------------------------------------------------------*/
916 /*--- Debuglog stuff. ---*/
917 /*------------------------------------------------------------*/
919 /* Only print messages whose stated level is less than or equal to
920 this. By default, it makes this entire subsystem silent. */
922 static Int loglevel
= 0;
924 /* Module startup. */
926 void VG_(debugLog_startup
) ( Int level
, const HChar
* who
)
928 if (level
< 0) level
= 0;
929 if (level
> 10) level
= 10;
931 VG_(debugLog
)(1, "debuglog",
932 "DebugLog system started by %s, "
933 "level %d logging requested\n",
937 /* Get the logging threshold level, as set by the most recent call to
938 VG_(debugLog_startup), or zero if there have been no such calls so
941 Int
VG_(debugLog_getLevel
) ( void )
956 static void add_to_buf ( HChar c
, void* p
)
958 printf_buf
* buf
= (printf_buf
*)p
;
960 if (buf
->n
>= 100-10 /*paranoia*/ ) {
961 emit( buf
->buf
, local_strlen(buf
->buf
) );
963 buf
->buf
[buf
->n
] = 0;
965 buf
->buf
[buf
->n
++] = c
;
966 buf
->buf
[buf
->n
] = 0;
969 /* Send a logging message. Nothing is output unless 'level'
970 is <= the current loglevel. */
972 void VG_(debugLog
) ( Int level
, const HChar
* modulename
,
973 const HChar
* format
, ... )
976 Int indent
, depth
, i
;
980 if (level
> loglevel
)
983 indent
= 2*level
- 1;
984 if (indent
< 1) indent
= 1;
988 pid
= local_sys_getpid();
990 // Print one '>' in front of the messages for each level of self-hosting
992 depth
= RUNNING_ON_VALGRIND
;
993 for (i
= 0; i
< depth
; i
++) {
994 (void)myvprintf_str ( add_to_buf
, &buf
, 0, 1, ">", False
);
997 (void)myvprintf_str ( add_to_buf
, &buf
, 0, 2, "--", False
);
998 (void)myvprintf_int64 ( add_to_buf
, &buf
, 0, 10, 1, False
, (ULong
)pid
);
999 (void)myvprintf_str ( add_to_buf
, &buf
, 0, 1, ":", False
);
1000 (void)myvprintf_int64 ( add_to_buf
, &buf
, 0, 10, 1, False
, (ULong
)level
);
1001 (void)myvprintf_str ( add_to_buf
, &buf
, 0, 1, ":", False
);
1002 (void)myvprintf_str ( add_to_buf
, &buf
, 0, 8, modulename
, False
);
1003 (void)myvprintf_str ( add_to_buf
, &buf
, 0, indent
, "", False
);
1005 va_start(vargs
,format
);
1007 (void) VG_(debugLog_vprintf
) ( add_to_buf
, &buf
, format
, vargs
);
1010 emit( buf
.buf
, local_strlen(buf
.buf
) );
1018 /*--------------------------------------------------------------------*/
1019 /*--- end m_debuglog.c ---*/
1020 /*--------------------------------------------------------------------*/