1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* This demonstrates a stack overrun bug that exp-ptrcheck found while 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov running Valgrind itself (self hosting). As at 12 Sept 08 this bug 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov is still in Valgrind. */ 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h> 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <assert.h> 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdarg.h> 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned long long int ULong; 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef signed long long int Long; 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned int UInt; 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef signed int Int; 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef signed char Char; 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef char HChar; 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned long UWord; 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef signed long Word; 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned char Bool; 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define True ((Bool)1) 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define False ((Bool)0) 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_(_str) VG_##_str 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --------------------------------------------------------------------- 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vg_sprintf, copied from m_libcprint.c 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ------------------------------------------------------------------ */ 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVG_(debugLog_vprintf) ( 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void(*send)(HChar,void*), 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* send_arg2, 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar* format, 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_list vargs 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ); 38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --------------------------------------------------------------------- 40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf() and friends 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ------------------------------------------------------------------ */ 42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { Int fd; Bool is_socket; } 44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov OutputSink; 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovOutputSink VG_(log_output_sink) = { 2, False }; /* 2 = stderr */ 48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Do the low-level send of a message to the logging sink. */ 50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid send_bytes_to_logging_sink ( OutputSink* sink, HChar* msg, Int nbytes ) 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fwrite(msg, 1, nbytes, stdout); 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fflush(stdout); 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --------- printf --------- */ 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar buf[512]; 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int buf_used; 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov OutputSink* sink; 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf_buf_t; 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Adds a single char to the buffer. When the buffer gets sufficiently 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// full, we write its contents to the logging sink. 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void add_to__printf_buf ( HChar c, void *p ) 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf_buf_t *b = (printf_buf_t *)p; 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (b->buf_used > sizeof(b->buf) - 2 ) { 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send_bytes_to_logging_sink( b->sink, b->buf, b->buf_used ); 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b->buf_used = 0; 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b->buf[b->buf_used++] = c; 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b->buf[b->buf_used] = 0; 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(b->buf_used < sizeof(b->buf)); 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt vprintf_to_buf ( printf_buf_t* b, 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar *format, va_list vargs ) 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret = 0; 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (b->sink->fd >= 0 || b->sink->fd == -2) { 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret = VG_(debugLog_vprintf) 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( add_to__printf_buf, b, format, vargs ); 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt vprintf_WRK ( OutputSink* sink, 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar *format, va_list vargs ) 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf_buf_t myprintf_buf 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov = { "", 0, sink }; 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret; 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret = vprintf_to_buf(&myprintf_buf, format, vargs); 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // Write out any chars left in the buffer. 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (myprintf_buf.buf_used > 0) { 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send_bytes_to_logging_sink( myprintf_buf.sink, 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov myprintf_buf.buf, 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov myprintf_buf.buf_used ); 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt VG_(vprintf) ( const HChar *format, va_list vargs ) 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return vprintf_WRK( &VG_(log_output_sink), format, vargs ); 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt VG_(printf) ( const HChar *format, ... ) 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret; 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_list vargs; 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_start(vargs, format); 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret = VG_(vprintf)(format, vargs); 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_end(vargs); 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool toBool ( Int x ) { 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int r = (x == 0) ? False : True; 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (Bool)r; 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Int local_strlen ( const HChar* str ) 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i = 0; 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (str[i] != 0) i++; 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return i; 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HChar local_toupper ( HChar c ) 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (c >= 'a' && c <= 'z') 146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return c + ('A' - 'a'); 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return c; 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/ 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- A simple, generic, vprintf implementation. ---*/ 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/ 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ----------------------------------------------- 157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Distantly derived from: 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vprintf replacement for Checker. 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright 1993, 1994, 1995 Tristan Gingold 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Written September 1993 Tristan Gingold 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (Checker itself was GPL'd.) 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ----------------------------------------------- */ 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Some flags. */ 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_MSG_SIGNED 1 /* The value is signed. */ 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */ 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */ 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */ 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */ 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VG_MSG_ALTFORMAT 32 /* Convert the value to alternate format */ 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Copy a string into the buffer. */ 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic __attribute__((noinline)) 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt myvprintf_str ( void(*send)(HChar,void*), 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* send_arg2, 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int flags, 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int width, 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* str, 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Bool capitalise ) 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define MAYBE_TOUPPER(ch) (capitalise ? local_toupper(ch) : (ch)) 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret = 0; 186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i, extra; 187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int len = local_strlen(str); 188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (width == 0) { 190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += len; 191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < len; i++) 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(MAYBE_TOUPPER(str[i]), send_arg2); 193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (len > width) { 197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += width; 198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < width; i++) 199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(MAYBE_TOUPPER(str[i]), send_arg2); 200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov extra = width - len; 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (flags & VG_MSG_LJUSTIFY) { 205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += extra; 206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < extra; i++) 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(' ', send_arg2); 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += len; 210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < len; i++) 211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(MAYBE_TOUPPER(str[i]), send_arg2); 212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!(flags & VG_MSG_LJUSTIFY)) { 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += extra; 214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < extra; i++) 215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(' ', send_arg2); 216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# undef MAYBE_TOUPPER 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Copy a string into the buffer, escaping bad XML chars. */ 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt myvprintf_str_XML_simplistic ( void(*send)(HChar,void*), 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* send_arg2, 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* str ) 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret = 0; 230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i; 231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int len = local_strlen(str); 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* alt; 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < len; i++) { 235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (str[i]) { 236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '&': alt = "&"; break; 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '<': alt = "<"; break; 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '>': alt = ">"; break; 239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: alt = NULL; 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (alt) { 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (*alt) { 244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(*alt, send_arg2); 245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret++; 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov alt++; 247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(str[i], send_arg2); 250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret++; 251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Write P into the buffer according to these args: 259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * If SIGN is true, p is a signed. 260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * BASE is the base. 261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * If WITH_ZERO is true, '0' must be added. 262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * WIDTH is the width of the field. 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt myvprintf_int64 ( void(*send)(HChar,void*), 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* send_arg2, 267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int flags, 268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int base, 269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int width, 270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Bool capitalised, 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong p ) 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar buf[40]; 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int ind = 0; 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i, nc = 0; 276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Bool neg = False; 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* digits = capitalised ? "0123456789ABCDEF" : "0123456789abcdef"; 278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret = 0; 279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (base < 2 || base > 16) 281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ((flags & VG_MSG_SIGNED) && (Long)p < 0) { 284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = - (Long)p; 285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov neg = True; 286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (p == 0) 289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf[ind++] = '0'; 290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else { 291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (p > 0) { 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (flags & VG_MSG_COMMA && 10 == base && 293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 0 == (ind-nc) % 3 && 0 != ind) 294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf[ind++] = ','; 296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nc++; 297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf[ind++] = digits[p % base]; 299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p /= base; 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (neg) 304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf[ind++] = '-'; 305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) { 307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(; ind < width; ind++) { 308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* assert(ind < 39); */ 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (ind > 39) { 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf[39] = 0; 311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov buf[ind] = (flags & VG_MSG_ZJUSTIFY) ? '0': ' '; 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Reverse copy to buffer. */ 318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += ind; 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = ind -1; i >= 0; i--) { 320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(buf[i], send_arg2); 321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (width > 0 && (flags & VG_MSG_LJUSTIFY)) { 323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(; ind < width; ind++) { 324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret++; 325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Never pad with zeroes on RHS -- changes the value! */ 326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(' ', send_arg2); 327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* A simple vprintf(). */ 334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* EXPORTED */ 335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVG_(debugLog_vprintf) ( 338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void(*send)(HChar,void*), 339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void* send_arg2, 340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar* format, 341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_list vargs 342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov) 343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret = 0; 345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i; 346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int flags; 347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int width; 348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int n_ls = 0; 349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Bool is_long, caps; 350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* We assume that vargs has already been initialised by the 352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov caller, using va_start, and that the caller will similarly 353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov clean up with va_end. 354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; format[i] != 0; i++) { 357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (format[i] != '%') { 358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(format[i], send_arg2); 359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret++; 360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov continue; 361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov i++; 363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* A '%' has been found. Ignore a trailing %. */ 364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (format[i] == 0) 365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (format[i] == '%') { 367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* '%%' is replaced by '%'. */ 368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send('%', send_arg2); 369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret++; 370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov continue; 371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags = 0; 373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_ls = 0; 374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov width = 0; /* length of the field. */ 375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (1) { 376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (format[i]) { 377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '(': 378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags |= VG_MSG_PAREN; 379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case ',': 381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '\'': 382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* If ',' or '\'' follows '%', commas will be inserted. */ 383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags |= VG_MSG_COMMA; 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '-': 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* If '-' follows '%', justify on the left. */ 387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags |= VG_MSG_LJUSTIFY; 388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '0': 390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* If '0' follows '%', pads will be inserted. */ 391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags |= VG_MSG_ZJUSTIFY; 392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case '#': 394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* If '#' follows '%', alternative format will be used. */ 395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags |= VG_MSG_ALTFORMAT; 396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov goto parse_fieldwidth; 399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov i++; 401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov parse_fieldwidth: 403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Compute the field length. */ 404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (format[i] >= '0' && format[i] <= '9') { 405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov width *= 10; 406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov width += format[i++] - '0'; 407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (format[i] == 'l') { 409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov i++; 410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_ls++; 411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // %d means print a 32-bit integer. 414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // %ld means print a word-size integer. 415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // %lld means print a 64-bit integer. 416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0 == n_ls) { is_long = False; } 417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if (1 == n_ls) { is_long = ( sizeof(void*) == sizeof(Long) ); } 418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else { is_long = True; } 419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (format[i]) { 421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 'o': /* %o */ 422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (flags & VG_MSG_ALTFORMAT) { 423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += 2; 424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send('0',send_arg2); 425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_long) 427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, ULong))); 429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 8, width, False, 431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, UInt))); 432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 'd': /* %d */ 434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags |= VG_MSG_SIGNED; 435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_long) 436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, Long))); 438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, Int))); 441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 'u': /* %u */ 443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_long) 444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, ULong))); 446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 10, width, False, 448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, UInt))); 449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 'p': 451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (format[i+1] == 'S') { 452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov i++; 453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* %pS, like %s but escaping chars for XML safety */ 454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Note: simplistic; ignores field width and flags */ 455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char *str = va_arg (vargs, char *); 456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (str == (char*) 0) 457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov str = "(null)"; 458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_str_XML_simplistic(send, send_arg2, str); 459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* %p */ 461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += 2; 462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send('0',send_arg2); 463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send('x',send_arg2); 464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 16, width, True, 465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)((UWord)va_arg (vargs, void *))); 466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 'x': /* %x */ 469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 'X': /* %X */ 470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov caps = toBool(format[i] == 'X'); 471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (flags & VG_MSG_ALTFORMAT) { 472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += 2; 473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send('0',send_arg2); 474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send('x',send_arg2); 475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_long) 477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps, 478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, ULong))); 479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_int64(send, send_arg2, flags, 16, width, caps, 481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (ULong)(va_arg (vargs, UInt))); 482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 'c': /* %c */ 484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret++; 485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov send(va_arg (vargs, int), send_arg2); 486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 's': case 'S': { /* %s */ 488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char *str = va_arg (vargs, char *); 489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (str == (char*) 0) str = "(null)"; 490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret += myvprintf_str(send, send_arg2, 491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags, width, str, format[i]=='S'); 492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// case 'y': { /* %y - print symbol */ 496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Char buf[100]; 497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Char *cp = buf; 498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Addr a = va_arg(vargs, Addr); 499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// 500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// if (flags & VG_MSG_PAREN) 501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// *cp++ = '('; 502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) { 503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// if (flags & VG_MSG_PAREN) { 504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// cp += local_strlen(cp); 505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// *cp++ = ')'; 506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// *cp = '\0'; 507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// } 508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// ret += myvprintf_str(send, send_arg2, flags, width, buf, 0); 509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// } 510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// break; 511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// } 512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void add_to__sprintf_buf ( HChar c, void *p ) 521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar** b = p; 523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *(*b)++ = c; 524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt VG_(vsprintf) ( HChar* buf, const HChar *format, va_list vargs ) 527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int ret; 529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* sprintf_ptr = buf; 530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret = VG_(debugLog_vprintf) 532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( add_to__sprintf_buf, &sprintf_ptr, format, vargs ); 533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov add_to__sprintf_buf('\0', &sprintf_ptr); 534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(local_strlen(buf) == ret); 536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt VG_(sprintf) ( HChar* buf, const HChar *format, ... ) 541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ret; 543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_list vargs; 544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_start(vargs,format); 545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret = VG_(vsprintf)(buf, format, vargs); 546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov va_end(vargs); 547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return ret; 548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --------------------------------------------------------------------- 553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov percentify() 554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ------------------------------------------------------------------ */ 555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* This part excerpted from coregrind/m_libcbase.c */ 557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Percentify n/m with d decimal places. Includes the '%' symbol at the end. 559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Right justifies in 'buf'. 560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid VG_percentify(ULong n, ULong m, UInt d, Int n_buf, HChar buf[]) 562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i, len, space; 564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong p1; 565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar fmt[32]; 566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (m == 0) { 568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // Have to generate the format string in order to be flexible about 569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // the width of the field. 570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(sprintf)(fmt, "%%-%ds", n_buf); 571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // fmt is now "%<n_buf>s" where <d> is 1,2,3... 572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(sprintf)(buf, fmt, "--%"); 573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return; 574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p1 = (100*n) / m; 577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (d == 0) { 579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(sprintf)(buf, "%lld%%", p1); 580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong p2; 582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt ex; 583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (d) { 584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 1: ex = 10; break; 585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 2: ex = 100; break; 586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 3: ex = 1000; break; 587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: assert(0); 588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* was: VG_(tool_panic)("Currently can only handle 3 decimal places"); */ 589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p2 = ((100*n*ex) / m) % ex; 591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // Have to generate the format string in order to be flexible about 592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // the width of the post-decimal-point part. 593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(sprintf)(fmt, "%%lld.%%0%dlld%%%%", d); 594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // fmt is now "%lld.%0<d>lld%%" where <d> is 1,2,3... 595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(sprintf)(buf, fmt, p1, p2); 596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov len = local_strlen(buf); 599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov space = n_buf - len; 600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (space < 0) space = 0; /* Allow for v. small field_width */ 601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov i = len; 602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Right justify in field */ 604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for ( ; i >= 0; i--) buf[i + space] = buf[i]; 605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < space; i++) buf[i] = ' '; 606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/ 610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- Stats ---*/ 611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/ 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* This part excerpted from coregrind/m_translate.c */ 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt n_SP_updates_fast = 0; 616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt n_SP_updates_generic_known = 0; 617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt n_SP_updates_generic_unknown = 0; 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__((noinline)) 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid VG_print_translation_stats ( void ) 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar buf[6]; 623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt n_SP_updates = n_SP_updates_fast + n_SP_updates_generic_known 624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov + n_SP_updates_generic_unknown; 625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_percentify(n_SP_updates_fast, n_SP_updates, 1, 6, buf); 626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(printf)( 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "translate: fast SP updates identified: %'u (%s)\n", 628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_SP_updates_fast, buf ); 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_percentify(n_SP_updates_generic_known, n_SP_updates, 1, 6, buf); 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(printf)( 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "translate: generic_known SP updates identified: %'u (%s)\n", 633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_SP_updates_generic_known, buf ); 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_percentify(n_SP_updates_generic_unknown, n_SP_updates, 1, 6, buf); 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(printf)( 637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "translate: generic_unknown SP updates identified: %'u (%s)\n", 638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_SP_updates_generic_unknown, buf ); 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main ( void ) 644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_print_translation_stats(); 646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 648