blob: 2031b8869e221c8531503e36db17e4b43e09d6a0 [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin main_util.c ---*/
sewardj35421a32004-07-05 13:12:34 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
sewardj89ae8472013-10-18 14:12:58 +000010 Copyright (C) 2004-2013 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +000012
sewardj752f9062010-05-03 21:38:49 +000013 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.
sewardjf8ed9d82004-11-12 17:40:23 +000017
sewardj752f9062010-05-03 21:38:49 +000018 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., 51 Franklin Street, Fifth Floor, Boston, MA
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardjf8ed9d82004-11-12 17:40:23 +000029
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#include "libvex_basictypes.h"
sewardj41f43bc2004-07-08 14:23:22 +000037#include "libvex.h"
38
sewardjcef7d3e2009-07-02 12:21:59 +000039#include "main_globals.h"
40#include "main_util.h"
sewardj35421a32004-07-05 13:12:34 +000041
42
43/*---------------------------------------------------------*/
44/*--- Storage ---*/
45/*---------------------------------------------------------*/
46
sewardjce605f92004-07-05 14:39:15 +000047/* Try to keep this as low as possible -- in particular, less than the
48 size of the smallest L2 cache we might encounter. At 50000, my VIA
49 Nehemiah 1 GHz (a weedy machine) can satisfy 27 million calls/
50 second to LibVEX_Alloc(16) -- that is, allocate memory at over 400
51 MByte/sec. Once the size increases enough to fall out of the cache
52 into memory, the rate falls by about a factor of 3.
53*/
sewardje165a8a2010-09-29 21:39:12 +000054#define N_TEMPORARY_BYTES 5000000
sewardj35421a32004-07-05 13:12:34 +000055
sewardj4eeda9c2005-11-25 02:47:00 +000056static HChar temporary[N_TEMPORARY_BYTES] __attribute__((aligned(8)));
sewardj2d6b14a2005-11-23 04:25:07 +000057static HChar* temporary_first = &temporary[0];
58static HChar* temporary_curr = &temporary[0];
59static HChar* temporary_last = &temporary[N_TEMPORARY_BYTES-1];
60
61static ULong temporary_bytes_allocd_TOT = 0;
sewardj443cd9d2004-07-18 23:06:45 +000062
sewardje29a31d2007-05-05 12:26:23 +000063#define N_PERMANENT_BYTES 10000
sewardj443cd9d2004-07-18 23:06:45 +000064
sewardje29a31d2007-05-05 12:26:23 +000065static HChar permanent[N_PERMANENT_BYTES] __attribute__((aligned(8)));
sewardj2d6b14a2005-11-23 04:25:07 +000066static HChar* permanent_first = &permanent[0];
67static HChar* permanent_curr = &permanent[0];
sewardje29a31d2007-05-05 12:26:23 +000068static HChar* permanent_last = &permanent[N_PERMANENT_BYTES-1];
sewardj443cd9d2004-07-18 23:06:45 +000069
florianbde34062014-10-11 14:48:38 +000070static HChar* private_LibVEX_alloc_first = &temporary[0];
71static HChar* private_LibVEX_alloc_curr = &temporary[0];
72static HChar* private_LibVEX_alloc_last = &temporary[N_TEMPORARY_BYTES-1];
73
74
sewardjd887b862005-01-17 18:34:34 +000075static VexAllocMode mode = VexAllocModeTEMP;
sewardjce605f92004-07-05 14:39:15 +000076
sewardj2d6b14a2005-11-23 04:25:07 +000077void vexAllocSanityCheck ( void )
78{
79 vassert(temporary_first == &temporary[0]);
80 vassert(temporary_last == &temporary[N_TEMPORARY_BYTES-1]);
81 vassert(permanent_first == &permanent[0]);
sewardje29a31d2007-05-05 12:26:23 +000082 vassert(permanent_last == &permanent[N_PERMANENT_BYTES-1]);
sewardj2d6b14a2005-11-23 04:25:07 +000083 vassert(temporary_first <= temporary_curr);
84 vassert(temporary_curr <= temporary_last);
85 vassert(permanent_first <= permanent_curr);
86 vassert(permanent_curr <= permanent_last);
87 vassert(private_LibVEX_alloc_first <= private_LibVEX_alloc_curr);
88 vassert(private_LibVEX_alloc_curr <= private_LibVEX_alloc_last);
89 if (mode == VexAllocModeTEMP){
90 vassert(private_LibVEX_alloc_first == temporary_first);
91 vassert(private_LibVEX_alloc_last == temporary_last);
92 }
93 else
94 if (mode == VexAllocModePERM) {
95 vassert(private_LibVEX_alloc_first == permanent_first);
96 vassert(private_LibVEX_alloc_last == permanent_last);
97 }
98 else
99 vassert(0);
100
101# define IS_WORD_ALIGNED(p) (0 == (((HWord)p) & (sizeof(HWord)-1)))
102 vassert(sizeof(HWord) == 4 || sizeof(HWord) == 8);
103 vassert(IS_WORD_ALIGNED(temporary_first));
104 vassert(IS_WORD_ALIGNED(temporary_curr));
105 vassert(IS_WORD_ALIGNED(temporary_last+1));
106 vassert(IS_WORD_ALIGNED(permanent_first));
107 vassert(IS_WORD_ALIGNED(permanent_curr));
108 vassert(IS_WORD_ALIGNED(permanent_last+1));
109 vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_first));
110 vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_curr));
111 vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_last+1));
112# undef IS_WORD_ALIGNED
113}
114
115/* The current allocation mode. */
sewardjce605f92004-07-05 14:39:15 +0000116
sewardjd887b862005-01-17 18:34:34 +0000117void vexSetAllocMode ( VexAllocMode m )
sewardj443cd9d2004-07-18 23:06:45 +0000118{
sewardj2d6b14a2005-11-23 04:25:07 +0000119 vexAllocSanityCheck();
120
121 /* Save away the current allocation point .. */
122 if (mode == VexAllocModeTEMP){
123 temporary_curr = private_LibVEX_alloc_curr;
124 }
125 else
126 if (mode == VexAllocModePERM) {
127 permanent_curr = private_LibVEX_alloc_curr;
128 }
129 else
130 vassert(0);
131
132 /* Did that screw anything up? */
133 vexAllocSanityCheck();
134
135 if (m == VexAllocModeTEMP){
136 private_LibVEX_alloc_first = temporary_first;
137 private_LibVEX_alloc_curr = temporary_curr;
138 private_LibVEX_alloc_last = temporary_last;
139 }
140 else
141 if (m == VexAllocModePERM) {
142 private_LibVEX_alloc_first = permanent_first;
143 private_LibVEX_alloc_curr = permanent_curr;
144 private_LibVEX_alloc_last = permanent_last;
145 }
146 else
147 vassert(0);
148
sewardj443cd9d2004-07-18 23:06:45 +0000149 mode = m;
150}
151
sewardjd887b862005-01-17 18:34:34 +0000152VexAllocMode vexGetAllocMode ( void )
sewardj443cd9d2004-07-18 23:06:45 +0000153{
154 return mode;
155}
sewardjce605f92004-07-05 14:39:15 +0000156
sewardj2d6b14a2005-11-23 04:25:07 +0000157__attribute__((noreturn))
florianbde34062014-10-11 14:48:38 +0000158static void private_LibVEX_alloc_OOM(void)
sewardj35421a32004-07-05 13:12:34 +0000159{
florian55085f82012-11-21 00:36:55 +0000160 const HChar* pool = "???";
sewardj2d6b14a2005-11-23 04:25:07 +0000161 if (private_LibVEX_alloc_first == &temporary[0]) pool = "TEMP";
162 if (private_LibVEX_alloc_first == &permanent[0]) pool = "PERM";
163 vex_printf("VEX temporary storage exhausted.\n");
sewardj66afb9f2005-11-25 04:28:46 +0000164 vex_printf("Pool = %s, start %p curr %p end %p (size %lld)\n",
sewardj2d6b14a2005-11-23 04:25:07 +0000165 pool,
166 private_LibVEX_alloc_first,
167 private_LibVEX_alloc_curr,
168 private_LibVEX_alloc_last,
sewardje29a31d2007-05-05 12:26:23 +0000169 (Long)(private_LibVEX_alloc_last + 1 - private_LibVEX_alloc_first));
sewardj2d6b14a2005-11-23 04:25:07 +0000170 vpanic("VEX temporary storage exhausted.\n"
171 "Increase N_{TEMPORARY,PERMANENT}_BYTES and recompile.");
sewardj35421a32004-07-05 13:12:34 +0000172}
173
sewardj2d6b14a2005-11-23 04:25:07 +0000174void vexSetAllocModeTEMP_and_clear ( void )
sewardj35421a32004-07-05 13:12:34 +0000175{
sewardj7df596b2004-12-06 14:29:12 +0000176 /* vassert(vex_initdone); */ /* causes infinite assert loops */
sewardj2d6b14a2005-11-23 04:25:07 +0000177 temporary_bytes_allocd_TOT
sewardj66afb9f2005-11-25 04:28:46 +0000178 += (ULong)(private_LibVEX_alloc_curr - private_LibVEX_alloc_first);
sewardj2d6b14a2005-11-23 04:25:07 +0000179
180 mode = VexAllocModeTEMP;
181 temporary_curr = &temporary[0];
182 private_LibVEX_alloc_curr = &temporary[0];
sewardj8688a722009-12-03 09:50:38 +0000183
184 /* Set to (1) and change the fill byte to 0x00 or 0xFF to test for
185 any potential bugs due to using uninitialised memory in the main
186 VEX storage area. */
187 if (0) {
188 Int i;
189 for (i = 0; i < N_TEMPORARY_BYTES; i++)
190 temporary[i] = 0x00;
191 }
192
sewardj2d6b14a2005-11-23 04:25:07 +0000193 vexAllocSanityCheck();
sewardj35421a32004-07-05 13:12:34 +0000194}
195
196
sewardjd887b862005-01-17 18:34:34 +0000197/* Exported to library client. */
198
florianbde34062014-10-11 14:48:38 +0000199/* Allocate in Vex's temporary allocation area. Be careful with this.
200 You can only call it inside an instrumentation or optimisation
201 callback that you have previously specified in a call to
202 LibVEX_Translate. The storage allocated will only stay alive until
203 translation of the current basic block is complete.
204 */
205
206void* LibVEX_Alloc ( Int nbytes )
207{
208 struct align {
209 char c;
210 union {
211 char c;
212 short s;
213 int i;
214 long l;
215 long long ll;
216 float f;
217 double d;
218 /* long double is currently not used and would increase alignment
219 unnecessarily. */
220 /* long double ld; */
221 void *pto;
222 void (*ptf)(void);
223 } x;
224 };
225
226#if 0
227 /* Nasty debugging hack, do not use. */
228 return malloc(nbytes);
229#else
230 HChar* curr;
231 HChar* next;
232 Int ALIGN;
233 ALIGN = offsetof(struct align,x) - 1;
234 nbytes = (nbytes + ALIGN) & ~ALIGN;
235 curr = private_LibVEX_alloc_curr;
236 next = curr + nbytes;
237 if (next >= private_LibVEX_alloc_last)
238 private_LibVEX_alloc_OOM();
239 private_LibVEX_alloc_curr = next;
240 return curr;
241#endif
242}
243
sewardjd887b862005-01-17 18:34:34 +0000244void LibVEX_ShowAllocStats ( void )
245{
sewardj2d6b14a2005-11-23 04:25:07 +0000246 vex_printf("vex storage: T total %lld bytes allocated\n",
247 (Long)temporary_bytes_allocd_TOT );
sewardje29a31d2007-05-05 12:26:23 +0000248 vex_printf("vex storage: P total %lld bytes allocated\n",
249 (Long)(permanent_curr - permanent_first) );
sewardjd887b862005-01-17 18:34:34 +0000250}
251
sewardj35421a32004-07-05 13:12:34 +0000252
253/*---------------------------------------------------------*/
254/*--- Bombing out ---*/
255/*---------------------------------------------------------*/
256
257__attribute__ ((noreturn))
sewardj58277842005-02-07 03:11:17 +0000258void vex_assert_fail ( const HChar* expr,
259 const HChar* file, Int line, const HChar* fn )
sewardj35421a32004-07-05 13:12:34 +0000260{
261 vex_printf( "\nvex: %s:%d (%s): Assertion `%s' failed.\n",
262 file, line, fn, expr );
263 (*vex_failure_exit)();
264}
265
266__attribute__ ((noreturn))
florian76714fd2012-09-13 20:21:42 +0000267void vpanic ( const HChar* str )
sewardj35421a32004-07-05 13:12:34 +0000268{
269 vex_printf("\nvex: the `impossible' happened:\n %s\n", str);
270 (*vex_failure_exit)();
271}
272
273
274/*---------------------------------------------------------*/
275/*--- vex_printf ---*/
276/*---------------------------------------------------------*/
277
278/* This should be the only <...> include in the entire VEX library.
279 New code for vex_util.c should go above this point. */
280#include <stdarg.h>
281
sewardjd7bde722011-04-05 13:19:33 +0000282Int vex_strlen ( const HChar* str )
sewardj35421a32004-07-05 13:12:34 +0000283{
284 Int i = 0;
285 while (str[i] != 0) i++;
286 return i;
287}
288
sewardj58277842005-02-07 03:11:17 +0000289Bool vex_streq ( const HChar* s1, const HChar* s2 )
sewardj36ca5132004-07-24 13:12:23 +0000290{
291 while (True) {
292 if (*s1 == 0 && *s2 == 0)
293 return True;
294 if (*s1 != *s2)
295 return False;
296 s1++;
297 s2++;
298 }
299}
sewardj35421a32004-07-05 13:12:34 +0000300
sewardjc9069f22012-06-01 16:09:50 +0000301void vex_bzero ( void* sV, UInt n )
302{
303 UInt i;
304 UChar* s = (UChar*)sV;
305 /* No laughing, please. Just don't call this too often. Thank you
306 for your attention. */
307 for (i = 0; i < n; i++) s[i] = 0;
308}
309
sewardj35421a32004-07-05 13:12:34 +0000310
sewardjda46fdd2005-08-25 21:20:18 +0000311/* Convert N0 into ascii in BUF, which is assumed to be big enough (at
312 least 67 bytes long). Observe BASE, SYNED and HEXCAPS. */
313static
314void convert_int ( /*OUT*/HChar* buf, Long n0,
315 Int base, Bool syned, Bool hexcaps )
sewardj35421a32004-07-05 13:12:34 +0000316{
sewardjda46fdd2005-08-25 21:20:18 +0000317 ULong u0;
318 HChar c;
319 Bool minus = False;
320 Int i, j, bufi = 0;
321 buf[bufi] = 0;
sewardj35421a32004-07-05 13:12:34 +0000322
sewardjda46fdd2005-08-25 21:20:18 +0000323 if (syned) {
324 if (n0 < 0) {
325 minus = True;
326 u0 = (ULong)(-n0);
327 } else {
328 u0 = (ULong)(n0);
sewardj35421a32004-07-05 13:12:34 +0000329 }
sewardjda46fdd2005-08-25 21:20:18 +0000330 } else {
331 u0 = (ULong)n0;
sewardj35421a32004-07-05 13:12:34 +0000332 }
333
sewardjda46fdd2005-08-25 21:20:18 +0000334 while (1) {
sewardjc7cd2142005-09-09 22:31:49 +0000335 buf[bufi++] = toHChar('0' + toUInt(u0 % base));
sewardjda46fdd2005-08-25 21:20:18 +0000336 u0 /= base;
337 if (u0 == 0) break;
sewardj35421a32004-07-05 13:12:34 +0000338 }
sewardjda46fdd2005-08-25 21:20:18 +0000339 if (minus)
340 buf[bufi++] = '-';
sewardj35421a32004-07-05 13:12:34 +0000341
sewardjda46fdd2005-08-25 21:20:18 +0000342 buf[bufi] = 0;
343 for (i = 0; i < bufi; i++)
344 if (buf[i] > '9')
sewardjc7cd2142005-09-09 22:31:49 +0000345 buf[i] = toHChar(buf[i] + (hexcaps ? 'A' : 'a') - '9' - 1);
sewardj35421a32004-07-05 13:12:34 +0000346
sewardjda46fdd2005-08-25 21:20:18 +0000347 i = 0;
348 j = bufi-1;
349 while (i <= j) {
350 c = buf[i];
351 buf[i] = buf[j];
352 buf[j] = c;
sewardj35421a32004-07-05 13:12:34 +0000353 i++;
sewardjda46fdd2005-08-25 21:20:18 +0000354 j--;
355 }
356}
357
358
359/* A half-arsed and buggy, but good-enough, implementation of
360 printf. */
361static
362UInt vprintf_wrk ( void(*sink)(HChar),
florian76714fd2012-09-13 20:21:42 +0000363 const HChar* format,
sewardjda46fdd2005-08-25 21:20:18 +0000364 va_list ap )
365{
366# define PUT(_ch) \
367 do { sink(_ch); nout++; } \
368 while (0)
369
370# define PAD(_n) \
371 do { Int _qq = (_n); for (; _qq > 0; _qq--) PUT(padchar); } \
372 while (0)
373
374# define PUTSTR(_str) \
florian55085f82012-11-21 00:36:55 +0000375 do { const HChar* _qq = _str; for (; *_qq; _qq++) PUT(*_qq); } \
sewardjda46fdd2005-08-25 21:20:18 +0000376 while (0)
377
florian76714fd2012-09-13 20:21:42 +0000378 const HChar* saved_format;
sewardjda46fdd2005-08-25 21:20:18 +0000379 Bool longlong, ljustify;
380 HChar padchar;
381 Int fwidth, nout, len1, len2, len3;
382 HChar intbuf[100]; /* big enough for a 64-bit # in base 2 */
383
384 nout = 0;
385 while (1) {
386
387 if (!format)
sewardj35421a32004-07-05 13:12:34 +0000388 break;
sewardjda46fdd2005-08-25 21:20:18 +0000389 if (*format == 0)
390 break;
391
392 if (*format != '%') {
393 PUT(*format);
394 format++;
sewardj35421a32004-07-05 13:12:34 +0000395 continue;
396 }
sewardjda46fdd2005-08-25 21:20:18 +0000397
398 saved_format = format;
399 longlong = False;
400 ljustify = False;
401 padchar = ' ';
402 fwidth = 0;
403 format++;
404
405 if (*format == '-') {
406 format++;
407 ljustify = True;
sewardj35421a32004-07-05 13:12:34 +0000408 }
sewardjda46fdd2005-08-25 21:20:18 +0000409 if (*format == '0') {
410 format++;
411 padchar = '0';
sewardj35421a32004-07-05 13:12:34 +0000412 }
florian473dc162012-12-16 22:44:32 +0000413 if (*format == '*') {
414 fwidth = va_arg(ap, Int);
sewardjda46fdd2005-08-25 21:20:18 +0000415 format++;
florian473dc162012-12-16 22:44:32 +0000416 } else {
417 while (*format >= '0' && *format <= '9') {
418 fwidth = fwidth * 10 + (*format - '0');
419 format++;
420 }
sewardj35421a32004-07-05 13:12:34 +0000421 }
sewardjda46fdd2005-08-25 21:20:18 +0000422 if (*format == 'l') {
423 format++;
424 if (*format == 'l') {
425 format++;
426 longlong = True;
427 }
sewardj35421a32004-07-05 13:12:34 +0000428 }
429
sewardjda46fdd2005-08-25 21:20:18 +0000430 switch (*format) {
431 case 's': {
florian55085f82012-11-21 00:36:55 +0000432 const HChar* str = va_arg(ap, HChar*);
sewardjda46fdd2005-08-25 21:20:18 +0000433 if (str == NULL)
434 str = "(null)";
435 len1 = len3 = 0;
436 len2 = vex_strlen(str);
cerion7d730cf2005-12-13 20:23:36 +0000437 if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2;
438 len3 = ljustify ? fwidth-len2 : 0; }
sewardjda46fdd2005-08-25 21:20:18 +0000439 PAD(len1); PUTSTR(str); PAD(len3);
sewardj35421a32004-07-05 13:12:34 +0000440 break;
cerionb85e8bb2005-02-16 08:54:33 +0000441 }
sewardjda46fdd2005-08-25 21:20:18 +0000442 case 'c': {
443 HChar c = (HChar)va_arg(ap, int);
444 HChar str[2];
445 str[0] = c;
446 str[1] = 0;
447 len1 = len3 = 0;
448 len2 = vex_strlen(str);
cerion7d730cf2005-12-13 20:23:36 +0000449 if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2;
450 len3 = ljustify ? fwidth-len2 : 0; }
sewardjda46fdd2005-08-25 21:20:18 +0000451 PAD(len1); PUTSTR(str); PAD(len3);
452 break;
453 }
454 case 'd': {
455 Long l;
456 if (longlong) {
457 l = va_arg(ap, Long);
458 } else {
459 l = (Long)va_arg(ap, Int);
460 }
461 convert_int(intbuf, l, 10/*base*/, True/*signed*/,
462 False/*irrelevant*/);
463 len1 = len3 = 0;
464 len2 = vex_strlen(intbuf);
cerion7d730cf2005-12-13 20:23:36 +0000465 if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2;
466 len3 = ljustify ? fwidth-len2 : 0; }
sewardjda46fdd2005-08-25 21:20:18 +0000467 PAD(len1); PUTSTR(intbuf); PAD(len3);
468 break;
469 }
470 case 'u':
471 case 'x':
472 case 'X': {
473 Int base = *format == 'u' ? 10 : 16;
474 Bool hexcaps = True; /* *format == 'X'; */
475 ULong l;
476 if (longlong) {
477 l = va_arg(ap, ULong);
478 } else {
479 l = (ULong)va_arg(ap, UInt);
480 }
481 convert_int(intbuf, l, base, False/*unsigned*/, hexcaps);
482 len1 = len3 = 0;
483 len2 = vex_strlen(intbuf);
cerion7d730cf2005-12-13 20:23:36 +0000484 if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2;
485 len3 = ljustify ? fwidth-len2 : 0; }
sewardjda46fdd2005-08-25 21:20:18 +0000486 PAD(len1); PUTSTR(intbuf); PAD(len3);
487 break;
488 }
489 case 'p':
490 case 'P': {
sewardjc7cd2142005-09-09 22:31:49 +0000491 Bool hexcaps = toBool(*format == 'P');
sewardjda46fdd2005-08-25 21:20:18 +0000492 ULong l = Ptr_to_ULong( va_arg(ap, void*) );
493 convert_int(intbuf, l, 16/*base*/, False/*unsigned*/, hexcaps);
494 len1 = len3 = 0;
495 len2 = vex_strlen(intbuf)+2;
cerion7d730cf2005-12-13 20:23:36 +0000496 if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2;
497 len3 = ljustify ? fwidth-len2 : 0; }
sewardjda46fdd2005-08-25 21:20:18 +0000498 PAD(len1); PUT('0'); PUT('x'); PUTSTR(intbuf); PAD(len3);
499 break;
500 }
sewardjeb17e492007-08-25 23:07:44 +0000501 case '%': {
502 PUT('%');
503 break;
504 }
sewardjda46fdd2005-08-25 21:20:18 +0000505 default:
506 /* no idea what it is. Print the format literally and
507 move on. */
508 while (saved_format <= format) {
509 PUT(*saved_format);
510 saved_format++;
cerionb85e8bb2005-02-16 08:54:33 +0000511 }
512 break;
sewardj35421a32004-07-05 13:12:34 +0000513 }
sewardjda46fdd2005-08-25 21:20:18 +0000514
515 format++;
516
sewardj35421a32004-07-05 13:12:34 +0000517 }
sewardjda46fdd2005-08-25 21:20:18 +0000518
519 return nout;
520
521# undef PUT
522# undef PAD
523# undef PUTSTR
sewardj35421a32004-07-05 13:12:34 +0000524}
525
526
527/* A general replacement for printf(). Note that only low-level
528 debugging info should be sent via here. The official route is to
529 to use vg_message(). This interface is deprecated.
530*/
sewardj58277842005-02-07 03:11:17 +0000531static HChar myprintf_buf[1000];
532static Int n_myprintf_buf;
sewardj35421a32004-07-05 13:12:34 +0000533
sewardj58277842005-02-07 03:11:17 +0000534static void add_to_myprintf_buf ( HChar c )
sewardj35421a32004-07-05 13:12:34 +0000535{
sewardjc7cd2142005-09-09 22:31:49 +0000536 Bool emit = toBool(c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/);
sewardj35421a32004-07-05 13:12:34 +0000537 myprintf_buf[n_myprintf_buf++] = c;
538 myprintf_buf[n_myprintf_buf] = 0;
sewardjda46fdd2005-08-25 21:20:18 +0000539 if (emit) {
540 (*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) );
541 n_myprintf_buf = 0;
542 myprintf_buf[n_myprintf_buf] = 0;
543 }
sewardj35421a32004-07-05 13:12:34 +0000544}
545
florian76714fd2012-09-13 20:21:42 +0000546UInt vex_printf ( const HChar* format, ... )
sewardj35421a32004-07-05 13:12:34 +0000547{
548 UInt ret;
549 va_list vargs;
550 va_start(vargs,format);
551
552 n_myprintf_buf = 0;
553 myprintf_buf[n_myprintf_buf] = 0;
554 ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
555
556 if (n_myprintf_buf > 0) {
557 (*vex_log_bytes)( myprintf_buf, n_myprintf_buf );
558 }
559
560 va_end(vargs);
561
562 return ret;
563}
564
565
sewardj41f43bc2004-07-08 14:23:22 +0000566/* A general replacement for sprintf(). */
567
sewardj58277842005-02-07 03:11:17 +0000568static HChar *vg_sprintf_ptr;
sewardj41f43bc2004-07-08 14:23:22 +0000569
sewardj58277842005-02-07 03:11:17 +0000570static void add_to_vg_sprintf_buf ( HChar c )
sewardj41f43bc2004-07-08 14:23:22 +0000571{
572 *vg_sprintf_ptr++ = c;
573}
574
florian76714fd2012-09-13 20:21:42 +0000575UInt vex_sprintf ( HChar* buf, const HChar *format, ... )
sewardj41f43bc2004-07-08 14:23:22 +0000576{
577 Int ret;
578 va_list vargs;
579
580 vg_sprintf_ptr = buf;
581
582 va_start(vargs,format);
583
584 ret = vprintf_wrk ( add_to_vg_sprintf_buf, format, vargs );
585 add_to_vg_sprintf_buf(0);
586
587 va_end(vargs);
588
589 vassert(vex_strlen(buf) == ret);
590 return ret;
591}
592
593
sewardj35421a32004-07-05 13:12:34 +0000594/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000595/*--- end main_util.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000596/*---------------------------------------------------------------*/