1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- begin main_util.c ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2004-2013 OpenWorks LLP 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info@open-works.net 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02110-1301, USA. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Neither the names of the U.S. Department of Energy nor the 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown University of California nor the names of its contributors may be 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown used to endorse or promote products derived from this software 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without prior written permission. 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_basictypes.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_globals.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_util.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------*/ 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Storage ---*/ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------*/ 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Try to keep this as low as possible -- in particular, less than the 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size of the smallest L2 cache we might encounter. At 50000, my VIA 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Nehemiah 1 GHz (a weedy machine) can satisfy 27 million calls/ 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown second to LibVEX_Alloc(16) -- that is, allocate memory at over 400 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MByte/sec. Once the size increases enough to fall out of the cache 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown into memory, the rate falls by about a factor of 3. 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_TEMPORARY_BYTES 5000000 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar temporary[N_TEMPORARY_BYTES] __attribute__((aligned(8))); 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar* temporary_first = &temporary[0]; 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar* temporary_curr = &temporary[0]; 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar* temporary_last = &temporary[N_TEMPORARY_BYTES-1]; 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong temporary_bytes_allocd_TOT = 0; 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_PERMANENT_BYTES 10000 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar permanent[N_PERMANENT_BYTES] __attribute__((aligned(8))); 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar* permanent_first = &permanent[0]; 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar* permanent_curr = &permanent[0]; 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar* permanent_last = &permanent[N_PERMANENT_BYTES-1]; 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VexAllocMode mode = VexAllocModeTEMP; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid vexAllocSanityCheck ( void ) 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(temporary_first == &temporary[0]); 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(temporary_last == &temporary[N_TEMPORARY_BYTES-1]); 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(permanent_first == &permanent[0]); 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(permanent_last == &permanent[N_PERMANENT_BYTES-1]); 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(temporary_first <= temporary_curr); 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(temporary_curr <= temporary_last); 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(permanent_first <= permanent_curr); 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(permanent_curr <= permanent_last); 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(private_LibVEX_alloc_first <= private_LibVEX_alloc_curr); 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(private_LibVEX_alloc_curr <= private_LibVEX_alloc_last); 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mode == VexAllocModeTEMP){ 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(private_LibVEX_alloc_first == temporary_first); 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(private_LibVEX_alloc_last == temporary_last); 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mode == VexAllocModePERM) { 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(private_LibVEX_alloc_first == permanent_first); 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(private_LibVEX_alloc_last == permanent_last); 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(0); 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define IS_WORD_ALIGNED(p) (0 == (((HWord)p) & (sizeof(HWord)-1))) 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(sizeof(HWord) == 4 || sizeof(HWord) == 8); 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(temporary_first)); 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(temporary_curr)); 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(temporary_last+1)); 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(permanent_first)); 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(permanent_curr)); 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(permanent_last+1)); 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_first)); 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_curr)); 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_last+1)); 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef IS_WORD_ALIGNED 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The current allocation mode. */ 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid vexSetAllocMode ( VexAllocMode m ) 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vexAllocSanityCheck(); 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Save away the current allocation point .. */ 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mode == VexAllocModeTEMP){ 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown temporary_curr = private_LibVEX_alloc_curr; 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (mode == VexAllocModePERM) { 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown permanent_curr = private_LibVEX_alloc_curr; 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(0); 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Did that screw anything up? */ 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vexAllocSanityCheck(); 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (m == VexAllocModeTEMP){ 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_first = temporary_first; 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_curr = temporary_curr; 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_last = temporary_last; 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (m == VexAllocModePERM) { 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_first = permanent_first; 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_curr = permanent_curr; 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_last = permanent_last; 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(0); 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mode = m; 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVexAllocMode vexGetAllocMode ( void ) 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return mode; 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Visible to library client, unfortunately. */ 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHChar* private_LibVEX_alloc_first = &temporary[0]; 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHChar* private_LibVEX_alloc_curr = &temporary[0]; 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHChar* private_LibVEX_alloc_last = &temporary[N_TEMPORARY_BYTES-1]; 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noreturn)) 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid private_LibVEX_alloc_OOM(void) 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* pool = "???"; 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (private_LibVEX_alloc_first == &temporary[0]) pool = "TEMP"; 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (private_LibVEX_alloc_first == &permanent[0]) pool = "PERM"; 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("VEX temporary storage exhausted.\n"); 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("Pool = %s, start %p curr %p end %p (size %lld)\n", 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pool, 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_first, 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_curr, 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_last, 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Long)(private_LibVEX_alloc_last + 1 - private_LibVEX_alloc_first)); 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("VEX temporary storage exhausted.\n" 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Increase N_{TEMPORARY,PERMANENT}_BYTES and recompile."); 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid vexSetAllocModeTEMP_and_clear ( void ) 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vassert(vex_initdone); */ /* causes infinite assert loops */ 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown temporary_bytes_allocd_TOT 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown += (ULong)(private_LibVEX_alloc_curr - private_LibVEX_alloc_first); 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mode = VexAllocModeTEMP; 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown temporary_curr = &temporary[0]; 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown private_LibVEX_alloc_curr = &temporary[0]; 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Set to (1) and change the fill byte to 0x00 or 0xFF to test for 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any potential bugs due to using uninitialised memory in the main 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VEX storage area. */ 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) { 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < N_TEMPORARY_BYTES; i++) 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown temporary[i] = 0x00; 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vexAllocSanityCheck(); 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Exported to library client. */ 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid LibVEX_ShowAllocStats ( void ) 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("vex storage: T total %lld bytes allocated\n", 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Long)temporary_bytes_allocd_TOT ); 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("vex storage: P total %lld bytes allocated\n", 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Long)(permanent_curr - permanent_first) ); 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------*/ 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Bombing out ---*/ 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------*/ 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__ ((noreturn)) 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid vex_assert_fail ( const HChar* expr, 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const HChar* file, Int line, const HChar* fn ) 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf( "\nvex: %s:%d (%s): Assertion `%s' failed.\n", 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown file, line, fn, expr ); 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*vex_failure_exit)(); 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__ ((noreturn)) 223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid vpanic ( const HChar* str ) 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\nvex: the `impossible' happened:\n %s\n", str); 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*vex_failure_exit)(); 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------*/ 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- vex_printf ---*/ 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------*/ 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This should be the only <...> include in the entire VEX library. 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown New code for vex_util.c should go above this point. */ 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdarg.h> 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt vex_strlen ( const HChar* str ) 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i = 0; 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (str[i] != 0) i++; 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return i; 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool vex_streq ( const HChar* s1, const HChar* s2 ) 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*s1 == 0 && *s2 == 0) 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*s1 != *s2) 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s1++; 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2++; 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid vex_bzero ( void* sV, UInt n ) 258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt i; 260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar* s = (UChar*)sV; 261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* No laughing, please. Just don't call this too often. Thank you 262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for your attention. */ 263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n; i++) s[i] = 0; 264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Convert N0 into ascii in BUF, which is assumed to be big enough (at 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown least 67 bytes long). Observe BASE, SYNED and HEXCAPS. */ 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid convert_int ( /*OUT*/HChar* buf, Long n0, 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int base, Bool syned, Bool hexcaps ) 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong u0; 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar c; 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool minus = False; 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j, bufi = 0; 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[bufi] = 0; 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (syned) { 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n0 < 0) { 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown minus = True; 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u0 = (ULong)(-n0); 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u0 = (ULong)(n0); 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u0 = (ULong)n0; 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (1) { 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[bufi++] = toHChar('0' + toUInt(u0 % base)); 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u0 /= base; 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (u0 == 0) break; 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (minus) 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[bufi++] = '-'; 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[bufi] = 0; 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bufi; i++) 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (buf[i] > '9') 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[i] = toHChar(buf[i] + (hexcaps ? 'A' : 'a') - '9' - 1); 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i = 0; 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j = bufi-1; 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (i <= j) { 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = buf[i]; 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[i] = buf[j]; 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[j] = c; 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i++; 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j--; 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A half-arsed and buggy, but good-enough, implementation of 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf. */ 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUInt vprintf_wrk ( void(*sink)(HChar), 319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* format, 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list ap ) 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PUT(_ch) \ 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { sink(_ch); nout++; } \ 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (0) 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PAD(_n) \ 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { Int _qq = (_n); for (; _qq > 0; _qq--) PUT(padchar); } \ 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (0) 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PUTSTR(_str) \ 331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov do { const HChar* _qq = _str; for (; *_qq; _qq++) PUT(*_qq); } \ 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (0) 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* saved_format; 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool longlong, ljustify; 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar padchar; 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int fwidth, nout, len1, len2, len3; 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar intbuf[100]; /* big enough for a 64-bit # in base 2 */ 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nout = 0; 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (1) { 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!format) 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*format == 0) 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*format != '%') { 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PUT(*format); 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown saved_format = format; 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown longlong = False; 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ljustify = False; 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown padchar = ' '; 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fwidth = 0; 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*format == '-') { 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ljustify = True; 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*format == '0') { 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown padchar = '0'; 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (*format == '*') { 370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fwidth = va_arg(ap, Int); 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov while (*format >= '0' && *format <= '9') { 374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fwidth = fwidth * 10 + (*format - '0'); 375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov format++; 376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*format == 'l') { 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*format == 'l') { 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown longlong = True; 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (*format) { 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 's': { 388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* str = va_arg(ap, HChar*); 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (str == NULL) 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str = "(null)"; 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len1 = len3 = 0; 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len2 = vex_strlen(str); 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len3 = ljustify ? fwidth-len2 : 0; } 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PAD(len1); PUTSTR(str); PAD(len3); 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'c': { 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar c = (HChar)va_arg(ap, int); 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar str[2]; 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str[0] = c; 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str[1] = 0; 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len1 = len3 = 0; 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len2 = vex_strlen(str); 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len3 = ljustify ? fwidth-len2 : 0; } 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PAD(len1); PUTSTR(str); PAD(len3); 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'd': { 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long l; 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (longlong) { 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown l = va_arg(ap, Long); 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown l = (Long)va_arg(ap, Int); 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert_int(intbuf, l, 10/*base*/, True/*signed*/, 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False/*irrelevant*/); 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len1 = len3 = 0; 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len2 = vex_strlen(intbuf); 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len3 = ljustify ? fwidth-len2 : 0; } 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PAD(len1); PUTSTR(intbuf); PAD(len3); 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'u': 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'x': 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'X': { 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int base = *format == 'u' ? 10 : 16; 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool hexcaps = True; /* *format == 'X'; */ 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong l; 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (longlong) { 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown l = va_arg(ap, ULong); 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown l = (ULong)va_arg(ap, UInt); 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert_int(intbuf, l, base, False/*unsigned*/, hexcaps); 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len1 = len3 = 0; 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len2 = vex_strlen(intbuf); 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len3 = ljustify ? fwidth-len2 : 0; } 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PAD(len1); PUTSTR(intbuf); PAD(len3); 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'p': 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'P': { 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool hexcaps = toBool(*format == 'P'); 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong l = Ptr_to_ULong( va_arg(ap, void*) ); 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert_int(intbuf, l, 16/*base*/, False/*unsigned*/, hexcaps); 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len1 = len3 = 0; 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len2 = vex_strlen(intbuf)+2; 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len3 = ljustify ? fwidth-len2 : 0; } 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PAD(len1); PUT('0'); PUT('x'); PUTSTR(intbuf); PAD(len3); 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case '%': { 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PUT('%'); 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no idea what it is. Print the format literally and 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown move on. */ 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (saved_format <= format) { 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PUT(*saved_format); 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown saved_format++; 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown format++; 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return nout; 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef PUT 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef PAD 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef PUTSTR 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A general replacement for printf(). Note that only low-level 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown debugging info should be sent via here. The official route is to 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to use vg_message(). This interface is deprecated. 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar myprintf_buf[1000]; 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int n_myprintf_buf; 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void add_to_myprintf_buf ( HChar c ) 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool emit = toBool(c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/); 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown myprintf_buf[n_myprintf_buf++] = c; 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown myprintf_buf[n_myprintf_buf] = 0; 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (emit) { 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) ); 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_myprintf_buf = 0; 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown myprintf_buf[n_myprintf_buf] = 0; 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovUInt vex_printf ( const HChar* format, ... ) 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt ret; 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs,format); 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_myprintf_buf = 0; 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown myprintf_buf[n_myprintf_buf] = 0; 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs ); 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n_myprintf_buf > 0) { 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*vex_log_bytes)( myprintf_buf, n_myprintf_buf ); 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ret; 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A general replacement for sprintf(). */ 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar *vg_sprintf_ptr; 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void add_to_vg_sprintf_buf ( HChar c ) 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *vg_sprintf_ptr++ = c; 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovUInt vex_sprintf ( HChar* buf, const HChar *format, ... ) 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int ret; 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_sprintf_ptr = buf; 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs,format); 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ret = vprintf_wrk ( add_to_vg_sprintf_buf, format, vargs ); 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_to_vg_sprintf_buf(0); 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(vex_strlen(buf) == ret); 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ret; 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end main_util.c ---*/ 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 553