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