1
2/*--------------------------------------------------------------------*/
3/*--- Libc printing.                                 m_libcprint.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2013 Julian Seward
11      jseward@acm.org
12
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.
17
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.
22
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
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31#include "pub_core_basics.h"
32#include "pub_core_vki.h"
33#include "pub_core_debuglog.h"
34#include "pub_core_gdbserver.h"  // VG_(gdb_printf)
35#include "pub_core_libcbase.h"
36#include "pub_core_libcassert.h"
37#include "pub_core_libcfile.h"   // VG_(write)(), VG_(write_socket)()
38#include "pub_core_libcprint.h"
39#include "pub_core_libcproc.h"   // VG_(getpid)(), VG_(read_millisecond_timer()
40#include "pub_core_options.h"
41#include "pub_core_clreq.h"      // For RUNNING_ON_VALGRIND
42
43
44/* ---------------------------------------------------------------------
45   Writing to file or a socket
46   ------------------------------------------------------------------ */
47
48/* The destination sinks for normal and XML output.  These have their
49   initial values here; they are set to final values by
50   m_main.main_process_cmd_line_options().  See comment at the top of
51   that function for the associated logic.
52   After startup, the gdbserver monitor command might temporarily
53   set the fd of log_output_sink to -2 to indicate that output is
54   to be given to gdb rather than output to the startup fd */
55OutputSink VG_(log_output_sink) = {  2, False }; /* 2 = stderr */
56OutputSink VG_(xml_output_sink) = { -1, False }; /* disabled */
57
58/* Do the low-level send of a message to the logging sink. */
59static
60void send_bytes_to_logging_sink ( OutputSink* sink, const HChar* msg, Int nbytes )
61{
62   if (sink->is_socket) {
63      Int rc = VG_(write_socket)( sink->fd, msg, nbytes );
64      if (rc == -1) {
65         // For example, the listener process died.  Switch back to stderr.
66         sink->is_socket = False;
67         sink->fd = 2;
68         VG_(write)( sink->fd, msg, nbytes );
69      }
70   } else {
71      /* sink->fd could have been set to -1 in the various
72         sys-wrappers for sys_fork, if --child-silent-after-fork=yes
73         is in effect.  That is a signal that we should not produce
74         any more output. */
75      if (sink->fd >= 0)
76         VG_(write)( sink->fd, msg, nbytes );
77      else if (sink->fd == -2 && nbytes > 0)
78         /* send to gdb the provided data, which must be
79            a null terminated string with len >= 1 */
80         VG_(gdb_printf)("%s", msg);
81   }
82}
83
84
85/* ---------------------------------------------------------------------
86   printf() and friends
87   ------------------------------------------------------------------ */
88
89/* --------- printf --------- */
90
91typedef
92   struct {
93      HChar       buf[512];
94      Int         buf_used;
95      OutputSink* sink;
96   }
97   printf_buf_t;
98
99// Adds a single char to the buffer.  When the buffer gets sufficiently
100// full, we write its contents to the logging sink.
101static void add_to__printf_buf ( HChar c, void *p )
102{
103   printf_buf_t *b = (printf_buf_t *)p;
104
105   if (b->buf_used > sizeof(b->buf) - 2 ) {
106      send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
107      b->buf_used = 0;
108   }
109   b->buf[b->buf_used++] = c;
110   b->buf[b->buf_used]   = 0;
111   tl_assert(b->buf_used < sizeof(b->buf));
112}
113
114static UInt vprintf_to_buf ( printf_buf_t* b,
115                             const HChar *format, va_list vargs )
116{
117   UInt ret = 0;
118   if (b->sink->fd >= 0 || b->sink->fd == -2) {
119      ret = VG_(debugLog_vprintf)
120               ( add_to__printf_buf, b, format, vargs );
121   }
122   return ret;
123}
124
125static UInt vprintf_WRK ( OutputSink* sink,
126                          const HChar *format, va_list vargs )
127{
128   printf_buf_t myprintf_buf
129      = { "", 0, sink };
130   UInt ret
131      = vprintf_to_buf(&myprintf_buf, format, vargs);
132   // Write out any chars left in the buffer.
133   if (myprintf_buf.buf_used > 0) {
134      send_bytes_to_logging_sink( myprintf_buf.sink,
135                                  myprintf_buf.buf,
136                                  myprintf_buf.buf_used );
137   }
138   return ret;
139}
140
141UInt VG_(vprintf) ( const HChar *format, va_list vargs )
142{
143   return vprintf_WRK( &VG_(log_output_sink), format, vargs );
144}
145
146UInt VG_(printf) ( const HChar *format, ... )
147{
148   UInt ret;
149   va_list vargs;
150   va_start(vargs, format);
151   ret = VG_(vprintf)(format, vargs);
152   va_end(vargs);
153   return ret;
154}
155
156UInt VG_(vprintf_xml) ( const HChar *format, va_list vargs )
157{
158   return vprintf_WRK( &VG_(xml_output_sink), format, vargs );
159}
160
161UInt VG_(printf_xml) ( const HChar *format, ... )
162{
163   UInt ret;
164   va_list vargs;
165   va_start(vargs, format);
166   ret = VG_(vprintf_xml)(format, vargs);
167   va_end(vargs);
168   return ret;
169}
170
171static UInt emit_WRK ( const HChar* format, va_list vargs )
172{
173   if (VG_(clo_xml)) {
174      return VG_(vprintf_xml)(format, vargs);
175   } else if (VG_(log_output_sink).fd == -2) {
176      return VG_(vprintf) (format, vargs);
177   } else {
178      return VG_(vmessage)(Vg_UserMsg, format, vargs);
179   }
180}
181UInt VG_(emit) ( const HChar* format, ... )
182{
183   UInt ret;
184   va_list vargs;
185   va_start(vargs, format);
186   ret = emit_WRK(format, vargs);
187   va_end(vargs);
188   return ret;
189}
190
191/* --------- sprintf --------- */
192
193/* If we had an explicit buf structure here, it would contain only one
194   field, indicating where the next char is to go.  So use p directly
195   for that, rather than having it be a pointer to a structure. */
196
197static void add_to__sprintf_buf ( HChar c, void *p )
198{
199   HChar** b = p;
200   *(*b)++ = c;
201}
202
203UInt VG_(vsprintf) ( HChar* buf, const HChar *format, va_list vargs )
204{
205   Int ret;
206   HChar* sprintf_ptr = buf;
207
208   ret = VG_(debugLog_vprintf)
209            ( add_to__sprintf_buf, &sprintf_ptr, format, vargs );
210   add_to__sprintf_buf('\0', &sprintf_ptr);
211
212   vg_assert(VG_(strlen)(buf) == ret);
213
214   return ret;
215}
216
217UInt VG_(sprintf) ( HChar* buf, const HChar *format, ... )
218{
219   UInt ret;
220   va_list vargs;
221   va_start(vargs,format);
222   ret = VG_(vsprintf)(buf, format, vargs);
223   va_end(vargs);
224   return ret;
225}
226
227
228/* --------- snprintf --------- */
229
230typedef
231   struct {
232      HChar* buf;
233      Int    buf_size;
234      Int    buf_used;
235   }
236   snprintf_buf_t;
237
238static void add_to__snprintf_buf ( HChar c, void* p )
239{
240   snprintf_buf_t* b = p;
241   if (b->buf_size > 0 && b->buf_used < b->buf_size) {
242      b->buf[b->buf_used++] = c;
243      if (b->buf_used < b->buf_size)
244         b->buf[b->buf_used] = 0;
245      else
246         b->buf[b->buf_size-1] = 0; /* pre: b->buf_size > 0 */
247   }
248}
249
250UInt VG_(vsnprintf) ( HChar* buf, Int size, const HChar *format, va_list vargs )
251{
252   snprintf_buf_t b;
253   b.buf      = buf;
254   b.buf_size = size < 0 ? 0 : size;
255   b.buf_used = 0;
256   if (b.buf_size > 0)
257      b.buf[0] = 0; // ensure to null terminate buf if empty format
258   (void) VG_(debugLog_vprintf)
259             ( add_to__snprintf_buf, &b, format, vargs );
260
261   return b.buf_used;
262}
263
264UInt VG_(snprintf) ( HChar* buf, Int size, const HChar *format, ... )
265{
266   UInt ret;
267   va_list vargs;
268   va_start(vargs,format);
269   ret = VG_(vsnprintf)(buf, size, format, vargs);
270   va_end(vargs);
271   return ret;
272}
273
274
275/* --------- vcbprintf --------- */
276
277void VG_(vcbprintf)( void(*char_sink)(HChar, void* opaque),
278                     void* opaque,
279                     const HChar* format, va_list vargs )
280{
281   (void) VG_(debugLog_vprintf)
282             ( char_sink, opaque, format, vargs );
283}
284
285
286/* ---------------------------------------------------------------------
287   percentify()
288   ------------------------------------------------------------------ */
289
290// Percentify n/m with d decimal places.  Includes the '%' symbol at the end.
291// Right justifies in 'buf'.
292void VG_(percentify)(ULong n, ULong m, UInt d, Int n_buf, HChar buf[])
293{
294   Int i, len, space;
295   ULong p1;
296   HChar fmt[32];
297
298   if (m == 0) {
299      // Have to generate the format string in order to be flexible about
300      // the width of the field.
301      VG_(sprintf)(fmt, "%%-%ds", n_buf);
302      // fmt is now "%<n_buf>s" where <d> is 1,2,3...
303      VG_(sprintf)(buf, fmt, "--%");
304      return;
305   }
306
307   p1 = (100*n) / m;
308
309   if (d == 0) {
310      VG_(sprintf)(buf, "%lld%%", p1);
311   } else {
312      ULong p2;
313      UInt  ex;
314      switch (d) {
315      case 1: ex = 10;    break;
316      case 2: ex = 100;   break;
317      case 3: ex = 1000;  break;
318      default: VG_(tool_panic)("Currently can only handle 3 decimal places");
319      }
320      p2 = ((100*n*ex) / m) % ex;
321      // Have to generate the format string in order to be flexible about
322      // the width of the post-decimal-point part.
323      VG_(sprintf)(fmt, "%%lld.%%0%dlld%%%%", d);
324      // fmt is now "%lld.%0<d>lld%%" where <d> is 1,2,3...
325      VG_(sprintf)(buf, fmt, p1, p2);
326   }
327
328   len = VG_(strlen)(buf);
329   space = n_buf - len;
330   if (space < 0) space = 0;     /* Allow for v. small field_width */
331   i = len;
332
333   /* Right justify in field */
334   for (     ; i >= 0;    i--)  buf[i + space] = buf[i];
335   for (i = 0; i < space; i++)  buf[i] = ' ';
336}
337
338
339/* ---------------------------------------------------------------------
340   elapsed_wallclock_time()
341   ------------------------------------------------------------------ */
342
343/* Get the elapsed wallclock time since startup into buf, which must
344   16 chars long.  This is unchecked.  It also relies on the
345   millisecond timer having been set to zero by an initial read in
346   m_main during startup. */
347
348void VG_(elapsed_wallclock_time) ( /*OUT*/HChar* buf )
349{
350   UInt t, ms, s, mins, hours, days;
351
352   t  = VG_(read_millisecond_timer)(); /* milliseconds */
353
354   ms = t % 1000;
355   t /= 1000; /* now in seconds */
356
357   s = t % 60;
358   t /= 60; /* now in minutes */
359
360   mins = t % 60;
361   t /= 60; /* now in hours */
362
363   hours = t % 24;
364   t /= 24; /* now in days */
365
366   days = t;
367
368   VG_(sprintf)(buf, "%02u:%02u:%02u:%02u.%03u ", days, hours, mins, s, ms);
369}
370
371
372/* ---------------------------------------------------------------------
373   message()
374   ------------------------------------------------------------------ */
375
376/* A buffer for accumulating VG_(message) style output.  This is
377   pretty much the same as VG_(printf)'s scheme, with two differences:
378
379   * The message buffer persists between calls, so that multiple
380     calls to VG_(message) can build up output.
381
382   * Whenever the first character on a line is emitted, the
383     ==PID== style preamble is stuffed in before it.
384*/
385typedef
386   struct {
387      HChar buf[512+128];
388      Int   buf_used;
389      Bool  atLeft; /* notionally, is the next char position at the
390                       leftmost column? */
391      /* Current message kind - changes from call to call */
392      VgMsgKind kind;
393      /* destination */
394      OutputSink* sink;
395   }
396   vmessage_buf_t;
397
398static vmessage_buf_t vmessage_buf
399   = { "", 0, True, Vg_UserMsg, &VG_(log_output_sink) };
400
401
402// Adds a single char to the buffer.  We aim to have at least 128
403// bytes free in the buffer, so that it's always possible to emit
404// the preamble into the buffer if c happens to be the character
405// following a \n.  When the buffer gets too full, we write its
406// contents to the logging sink.
407static void add_to__vmessage_buf ( HChar c, void *p )
408{
409   HChar tmp[64];
410   vmessage_buf_t* b = (vmessage_buf_t*)p;
411
412   vg_assert(b->buf_used >= 0 && b->buf_used < sizeof(b->buf)-128);
413
414   if (UNLIKELY(b->atLeft)) {
415      // insert preamble
416      HChar ch;
417      Int   i, depth;
418
419      // Print one '>' in front of the messages for each level of
420      // self-hosting being performed.
421      // Do not print such '>' if sim hint "no-inner-prefix" given
422      // (useful to run regression tests in an outer/inner setup
423      // and avoid the diff failing due to these unexpected '>').
424      depth = RUNNING_ON_VALGRIND;
425      if (depth > 0 && !VG_(strstr)(VG_(clo_sim_hints), "no-inner-prefix")) {
426         if (depth > 10)
427            depth = 10; // ?!?!
428         for (i = 0; i < depth; i++) {
429            b->buf[b->buf_used++] = '>';
430         }
431      }
432
433      if (Vg_FailMsg == b->kind) {
434         // "valgrind: " prefix.
435         b->buf[b->buf_used++] = 'v';
436         b->buf[b->buf_used++] = 'a';
437         b->buf[b->buf_used++] = 'l';
438         b->buf[b->buf_used++] = 'g';
439         b->buf[b->buf_used++] = 'r';
440         b->buf[b->buf_used++] = 'i';
441         b->buf[b->buf_used++] = 'n';
442         b->buf[b->buf_used++] = 'd';
443         b->buf[b->buf_used++] = ':';
444         b->buf[b->buf_used++] = ' ';
445      } else {
446         switch (b->kind) {
447            case Vg_UserMsg:       ch = '='; break;
448            case Vg_DebugMsg:      ch = '-'; break;
449            case Vg_ClientMsg:     ch = '*'; break;
450            default:               ch = '?'; break;
451         }
452
453         b->buf[b->buf_used++] = ch;
454         b->buf[b->buf_used++] = ch;
455
456         if (VG_(clo_time_stamp)) {
457            VG_(memset)(tmp, 0, sizeof(tmp));
458            VG_(elapsed_wallclock_time)(tmp);
459            tmp[sizeof(tmp)-1] = 0;
460            for (i = 0; tmp[i]; i++)
461               b->buf[b->buf_used++] = tmp[i];
462         }
463
464         VG_(sprintf)(tmp, "%d", VG_(getpid)());
465         tmp[sizeof(tmp)-1] = 0;
466         for (i = 0; tmp[i]; i++)
467            b->buf[b->buf_used++] = tmp[i];
468
469         b->buf[b->buf_used++] = ch;
470         b->buf[b->buf_used++] = ch;
471         b->buf[b->buf_used++] = ' ';
472      }
473
474      /* We can't possibly have stuffed 96 chars in merely as a result
475         of making the preamble (can we?) */
476      vg_assert(b->buf_used < sizeof(b->buf)-32);
477   }
478
479   b->buf[b->buf_used++] = c;
480   b->buf[b->buf_used]   = 0;
481
482   if (b->buf_used >= sizeof(b->buf) - 128) {
483      send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
484      b->buf_used = 0;
485   }
486
487   b->atLeft = c == '\n';
488}
489
490
491UInt VG_(vmessage) ( VgMsgKind kind, const HChar* format, va_list vargs )
492{
493   UInt ret;
494
495   /* Note (carefully) that the buf persists from call to call, unlike
496      with the other printf variants in earlier parts of this file. */
497   vmessage_buf_t* b = &vmessage_buf; /* shorthand for convenience */
498
499   /* We have to set this each call, so that the correct flavour
500      of preamble is emitted at each \n. */
501   b->kind = kind;
502
503   ret = VG_(debugLog_vprintf) ( add_to__vmessage_buf,
504                                 b, format, vargs );
505
506   /* If the message finished exactly with a \n, then flush it at this
507      point.  If not, assume more bits of the same line will turn up
508      in later messages, so don't bother to flush it right now. */
509
510   if (b->atLeft && b->buf_used > 0) {
511      send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
512      b->buf_used = 0;
513   }
514
515   return ret;
516}
517
518/* Send a simple single-part message. */
519UInt VG_(message) ( VgMsgKind kind, const HChar* format, ... )
520{
521   UInt count;
522   va_list vargs;
523   va_start(vargs,format);
524   count = VG_(vmessage) ( kind, format, vargs );
525   va_end(vargs);
526   return count;
527}
528
529static void revert_to_stderr ( void )
530{
531   VG_(log_output_sink).fd = 2; /* stderr */
532   VG_(log_output_sink).is_socket = False;
533}
534
535/* VG_(message) variants with hardwired first argument. */
536
537UInt VG_(fmsg) ( const HChar* format, ... )
538{
539   UInt count;
540   va_list vargs;
541   va_start(vargs,format);
542   count = VG_(vmessage) ( Vg_FailMsg, format, vargs );
543   va_end(vargs);
544   return count;
545}
546
547void VG_(fmsg_bad_option) ( const HChar* opt, const HChar* format, ... )
548{
549   va_list vargs;
550   va_start(vargs,format);
551   revert_to_stderr();
552   VG_(message) (Vg_FailMsg, "Bad option: %s\n", opt);
553   VG_(vmessage)(Vg_FailMsg, format, vargs );
554   VG_(message) (Vg_FailMsg, "Use --help for more information or consult the user manual.\n");
555   VG_(exit)(1);
556   va_end(vargs);
557}
558
559UInt VG_(umsg) ( const HChar* format, ... )
560{
561   UInt count;
562   va_list vargs;
563   va_start(vargs,format);
564   count = VG_(vmessage) ( Vg_UserMsg, format, vargs );
565   va_end(vargs);
566   return count;
567}
568
569UInt VG_(dmsg) ( const HChar* format, ... )
570{
571   UInt count;
572   va_list vargs;
573   va_start(vargs,format);
574   count = VG_(vmessage) ( Vg_DebugMsg, format, vargs );
575   va_end(vargs);
576   return count;
577}
578
579/* Flush any output that has accumulated in vmessage_buf as a
580   result of previous calls to VG_(message) et al. */
581void VG_(message_flush) ( void )
582{
583   vmessage_buf_t* b = &vmessage_buf;
584   send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used );
585   b->buf_used = 0;
586}
587
588__attribute__((noreturn))
589void VG_(err_missing_prog) ( void  )
590{
591   revert_to_stderr();
592   VG_(fmsg)("no program specified\n");
593   VG_(fmsg)("Use --help for more information.\n");
594   VG_(exit)(1);
595}
596
597__attribute__((noreturn))
598void VG_(err_config_error) ( const HChar* format, ... )
599{
600   va_list vargs;
601   va_start(vargs,format);
602   revert_to_stderr();
603   VG_(message) (Vg_FailMsg, "Startup or configuration error:\n   ");
604   VG_(vmessage)(Vg_FailMsg, format, vargs );
605   VG_(message) (Vg_FailMsg, "Unable to start up properly.  Giving up.\n");
606   VG_(exit)(1);
607   va_end(vargs);
608}
609
610
611/*--------------------------------------------------------------------*/
612/*--- end                                                          ---*/
613/*--------------------------------------------------------------------*/
614
615