135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/ 3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin main_util.c ---*/ 435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/ 535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 6f8ed9d874a7b8651654591c68c6d431c758d787csewardj/* 7752f90673ebbb6b2f55fc5e46606dea371313713sewardj This file is part of Valgrind, a dynamic binary instrumentation 8752f90673ebbb6b2f55fc5e46606dea371313713sewardj framework. 9f8ed9d874a7b8651654591c68c6d431c758d787csewardj 10ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2004-2017 OpenWorks LLP 11752f90673ebbb6b2f55fc5e46606dea371313713sewardj info@open-works.net 127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 13752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is free software; you can redistribute it and/or 14752f90673ebbb6b2f55fc5e46606dea371313713sewardj modify it under the terms of the GNU General Public License as 15752f90673ebbb6b2f55fc5e46606dea371313713sewardj published by the Free Software Foundation; either version 2 of the 16752f90673ebbb6b2f55fc5e46606dea371313713sewardj License, or (at your option) any later version. 177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 18752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is distributed in the hope that it will be useful, but 19752f90673ebbb6b2f55fc5e46606dea371313713sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 20752f90673ebbb6b2f55fc5e46606dea371313713sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21752f90673ebbb6b2f55fc5e46606dea371313713sewardj General Public License for more details. 22752f90673ebbb6b2f55fc5e46606dea371313713sewardj 23752f90673ebbb6b2f55fc5e46606dea371313713sewardj You should have received a copy of the GNU General Public License 24752f90673ebbb6b2f55fc5e46606dea371313713sewardj along with this program; if not, write to the Free Software 25752f90673ebbb6b2f55fc5e46606dea371313713sewardj Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 02110-1301, USA. 277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 28752f90673ebbb6b2f55fc5e46606dea371313713sewardj The GNU General Public License is contained in the file COPYING. 29f8ed9d874a7b8651654591c68c6d431c758d787csewardj 30f8ed9d874a7b8651654591c68c6d431c758d787csewardj Neither the names of the U.S. Department of Energy nor the 31f8ed9d874a7b8651654591c68c6d431c758d787csewardj University of California nor the names of its contributors may be 32f8ed9d874a7b8651654591c68c6d431c758d787csewardj used to endorse or promote products derived from this software 33f8ed9d874a7b8651654591c68c6d431c758d787csewardj without prior written permission. 34f8ed9d874a7b8651654591c68c6d431c758d787csewardj*/ 35f8ed9d874a7b8651654591c68c6d431c758d787csewardj 36887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include "libvex_basictypes.h" 3741f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj#include "libvex.h" 3841f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 39cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_globals.h" 40cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h" 4135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 4235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 4335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------*/ 4435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*--- Storage ---*/ 4535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------*/ 4635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 47ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj/* Try to keep this as low as possible -- in particular, less than the 48ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj size of the smallest L2 cache we might encounter. At 50000, my VIA 49ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj Nehemiah 1 GHz (a weedy machine) can satisfy 27 million calls/ 50ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj second to LibVEX_Alloc(16) -- that is, allocate memory at over 400 51ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj MByte/sec. Once the size increases enough to fall out of the cache 52ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj into memory, the rate falls by about a factor of 3. 53ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj*/ 54d749c7a34da29d8a475d7ff4c4eeb333b9c9d263florian 55e165a8ac12b8eb79c6a414258d0c21faa76ce459sewardj#define N_TEMPORARY_BYTES 5000000 56443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj 57d749c7a34da29d8a475d7ff4c4eeb333b9c9d263florianstatic HChar temporary[N_TEMPORARY_BYTES] __attribute__((aligned(REQ_ALIGN))); 582d6b14aa64df2ff85f8da143516779d5d43574cbsewardjstatic HChar* temporary_first = &temporary[0]; 592d6b14aa64df2ff85f8da143516779d5d43574cbsewardjstatic HChar* temporary_curr = &temporary[0]; 602d6b14aa64df2ff85f8da143516779d5d43574cbsewardjstatic HChar* temporary_last = &temporary[N_TEMPORARY_BYTES-1]; 61443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj 622d6b14aa64df2ff85f8da143516779d5d43574cbsewardjstatic ULong temporary_bytes_allocd_TOT = 0; 63443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj 64e29a31da9dcd4665c612a3d07cccf2c9a83f7ff5sewardj#define N_PERMANENT_BYTES 10000 6535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 66d749c7a34da29d8a475d7ff4c4eeb333b9c9d263florianstatic HChar permanent[N_PERMANENT_BYTES] __attribute__((aligned(REQ_ALIGN))); 672d6b14aa64df2ff85f8da143516779d5d43574cbsewardjstatic HChar* permanent_first = &permanent[0]; 682d6b14aa64df2ff85f8da143516779d5d43574cbsewardjstatic HChar* permanent_curr = &permanent[0]; 69e29a31da9dcd4665c612a3d07cccf2c9a83f7ff5sewardjstatic HChar* permanent_last = &permanent[N_PERMANENT_BYTES-1]; 7035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 71d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florianHChar* private_LibVEX_alloc_first = &temporary[0]; 72d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florianHChar* private_LibVEX_alloc_curr = &temporary[0]; 73d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florianHChar* private_LibVEX_alloc_last = &temporary[N_TEMPORARY_BYTES-1]; 74bde340633ae5d586ad1e46b7d8989353f3870f10florian 75bde340633ae5d586ad1e46b7d8989353f3870f10florian 762d6b14aa64df2ff85f8da143516779d5d43574cbsewardjstatic VexAllocMode mode = VexAllocModeTEMP; 77443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj 782d6b14aa64df2ff85f8da143516779d5d43574cbsewardjvoid vexAllocSanityCheck ( void ) 792d6b14aa64df2ff85f8da143516779d5d43574cbsewardj{ 802d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(temporary_first == &temporary[0]); 812d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(temporary_last == &temporary[N_TEMPORARY_BYTES-1]); 822d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(permanent_first == &permanent[0]); 83e29a31da9dcd4665c612a3d07cccf2c9a83f7ff5sewardj vassert(permanent_last == &permanent[N_PERMANENT_BYTES-1]); 842d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(temporary_first <= temporary_curr); 852d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(temporary_curr <= temporary_last); 862d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(permanent_first <= permanent_curr); 872d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(permanent_curr <= permanent_last); 882d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(private_LibVEX_alloc_first <= private_LibVEX_alloc_curr); 892d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(private_LibVEX_alloc_curr <= private_LibVEX_alloc_last); 902d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (mode == VexAllocModeTEMP){ 912d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(private_LibVEX_alloc_first == temporary_first); 922d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(private_LibVEX_alloc_last == temporary_last); 932d6b14aa64df2ff85f8da143516779d5d43574cbsewardj } 942d6b14aa64df2ff85f8da143516779d5d43574cbsewardj else 952d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (mode == VexAllocModePERM) { 962d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(private_LibVEX_alloc_first == permanent_first); 972d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(private_LibVEX_alloc_last == permanent_last); 982d6b14aa64df2ff85f8da143516779d5d43574cbsewardj } 992d6b14aa64df2ff85f8da143516779d5d43574cbsewardj else 1002d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(0); 1012d6b14aa64df2ff85f8da143516779d5d43574cbsewardj 1022d6b14aa64df2ff85f8da143516779d5d43574cbsewardj# define IS_WORD_ALIGNED(p) (0 == (((HWord)p) & (sizeof(HWord)-1))) 1032d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(sizeof(HWord) == 4 || sizeof(HWord) == 8); 1042d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(temporary_first)); 1052d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(temporary_curr)); 1062d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(temporary_last+1)); 1072d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(permanent_first)); 1082d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(permanent_curr)); 1092d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(permanent_last+1)); 1102d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_first)); 1112d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_curr)); 1122d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(IS_WORD_ALIGNED(private_LibVEX_alloc_last+1)); 1132d6b14aa64df2ff85f8da143516779d5d43574cbsewardj# undef IS_WORD_ALIGNED 1142d6b14aa64df2ff85f8da143516779d5d43574cbsewardj} 115ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj 116443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj/* The current allocation mode. */ 117ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj 118d887b8634b2c2685f528bd968459c628e8f86a34sewardjvoid vexSetAllocMode ( VexAllocMode m ) 119443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj{ 1202d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vexAllocSanityCheck(); 1212d6b14aa64df2ff85f8da143516779d5d43574cbsewardj 1222d6b14aa64df2ff85f8da143516779d5d43574cbsewardj /* Save away the current allocation point .. */ 1232d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (mode == VexAllocModeTEMP){ 1242d6b14aa64df2ff85f8da143516779d5d43574cbsewardj temporary_curr = private_LibVEX_alloc_curr; 1252d6b14aa64df2ff85f8da143516779d5d43574cbsewardj } 1262d6b14aa64df2ff85f8da143516779d5d43574cbsewardj else 1272d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (mode == VexAllocModePERM) { 1282d6b14aa64df2ff85f8da143516779d5d43574cbsewardj permanent_curr = private_LibVEX_alloc_curr; 1292d6b14aa64df2ff85f8da143516779d5d43574cbsewardj } 1302d6b14aa64df2ff85f8da143516779d5d43574cbsewardj else 1312d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(0); 1322d6b14aa64df2ff85f8da143516779d5d43574cbsewardj 1332d6b14aa64df2ff85f8da143516779d5d43574cbsewardj /* Did that screw anything up? */ 1342d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vexAllocSanityCheck(); 1352d6b14aa64df2ff85f8da143516779d5d43574cbsewardj 1362d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (m == VexAllocModeTEMP){ 1372d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_first = temporary_first; 1382d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_curr = temporary_curr; 1392d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_last = temporary_last; 1402d6b14aa64df2ff85f8da143516779d5d43574cbsewardj } 1412d6b14aa64df2ff85f8da143516779d5d43574cbsewardj else 1422d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (m == VexAllocModePERM) { 1432d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_first = permanent_first; 1442d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_curr = permanent_curr; 1452d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_last = permanent_last; 1462d6b14aa64df2ff85f8da143516779d5d43574cbsewardj } 1472d6b14aa64df2ff85f8da143516779d5d43574cbsewardj else 1482d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vassert(0); 1492d6b14aa64df2ff85f8da143516779d5d43574cbsewardj 150443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj mode = m; 151443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj} 152443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj 153d887b8634b2c2685f528bd968459c628e8f86a34sewardjVexAllocMode vexGetAllocMode ( void ) 154443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj{ 155443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj return mode; 156443cd9d34617dd7608e5dd4b4b0b4674d4f433e7sewardj} 157ce605f986c5b7e54322c44d722a4e71f6b37a365sewardj 1582d6b14aa64df2ff85f8da143516779d5d43574cbsewardj__attribute__((noreturn)) 159d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florianvoid private_LibVEX_alloc_OOM(void) 16035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{ 16155085f8680acc89d727e321f3b34cae1a8c4093aflorian const HChar* pool = "???"; 1622d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (private_LibVEX_alloc_first == &temporary[0]) pool = "TEMP"; 1632d6b14aa64df2ff85f8da143516779d5d43574cbsewardj if (private_LibVEX_alloc_first == &permanent[0]) pool = "PERM"; 1642d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vex_printf("VEX temporary storage exhausted.\n"); 16566afb9fb536ec22d535d27063424f7e9672d75a0sewardj vex_printf("Pool = %s, start %p curr %p end %p (size %lld)\n", 1662d6b14aa64df2ff85f8da143516779d5d43574cbsewardj pool, 1672d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_first, 1682d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_curr, 1692d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_last, 170e29a31da9dcd4665c612a3d07cccf2c9a83f7ff5sewardj (Long)(private_LibVEX_alloc_last + 1 - private_LibVEX_alloc_first)); 1712d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vpanic("VEX temporary storage exhausted.\n" 1722d6b14aa64df2ff85f8da143516779d5d43574cbsewardj "Increase N_{TEMPORARY,PERMANENT}_BYTES and recompile."); 17335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 17435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 1752d6b14aa64df2ff85f8da143516779d5d43574cbsewardjvoid vexSetAllocModeTEMP_and_clear ( void ) 17635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{ 1777df596b1e36840e2d74c90aa55589934add61ccfsewardj /* vassert(vex_initdone); */ /* causes infinite assert loops */ 1782d6b14aa64df2ff85f8da143516779d5d43574cbsewardj temporary_bytes_allocd_TOT 17966afb9fb536ec22d535d27063424f7e9672d75a0sewardj += (ULong)(private_LibVEX_alloc_curr - private_LibVEX_alloc_first); 1802d6b14aa64df2ff85f8da143516779d5d43574cbsewardj 1812d6b14aa64df2ff85f8da143516779d5d43574cbsewardj mode = VexAllocModeTEMP; 1822d6b14aa64df2ff85f8da143516779d5d43574cbsewardj temporary_curr = &temporary[0]; 1832d6b14aa64df2ff85f8da143516779d5d43574cbsewardj private_LibVEX_alloc_curr = &temporary[0]; 1848688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj 1858688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj /* Set to (1) and change the fill byte to 0x00 or 0xFF to test for 1868688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj any potential bugs due to using uninitialised memory in the main 1878688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj VEX storage area. */ 1888688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj if (0) { 1898688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj Int i; 1908688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj for (i = 0; i < N_TEMPORARY_BYTES; i++) 1918688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj temporary[i] = 0x00; 1928688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj } 1938688a7278ae7a5dd1f777cc027824981f14b9ce3sewardj 1942d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vexAllocSanityCheck(); 19535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 19635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 19735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 198d887b8634b2c2685f528bd968459c628e8f86a34sewardj/* Exported to library client. */ 199d887b8634b2c2685f528bd968459c628e8f86a34sewardj 200d887b8634b2c2685f528bd968459c628e8f86a34sewardjvoid LibVEX_ShowAllocStats ( void ) 201d887b8634b2c2685f528bd968459c628e8f86a34sewardj{ 2022d6b14aa64df2ff85f8da143516779d5d43574cbsewardj vex_printf("vex storage: T total %lld bytes allocated\n", 2032d6b14aa64df2ff85f8da143516779d5d43574cbsewardj (Long)temporary_bytes_allocd_TOT ); 204e29a31da9dcd4665c612a3d07cccf2c9a83f7ff5sewardj vex_printf("vex storage: P total %lld bytes allocated\n", 205e29a31da9dcd4665c612a3d07cccf2c9a83f7ff5sewardj (Long)(permanent_curr - permanent_first) ); 206d887b8634b2c2685f528bd968459c628e8f86a34sewardj} 207d887b8634b2c2685f528bd968459c628e8f86a34sewardj 208d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florianvoid *LibVEX_Alloc ( SizeT nbytes ) 209d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian{ 210d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian return LibVEX_Alloc_inline(nbytes); 211d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian} 21235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 21335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------*/ 21435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*--- Bombing out ---*/ 21535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------*/ 21635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 21735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj__attribute__ ((noreturn)) 2185827784e6bb74e2a032b66ec310776c24fd88729sewardjvoid vex_assert_fail ( const HChar* expr, 2195827784e6bb74e2a032b66ec310776c24fd88729sewardj const HChar* file, Int line, const HChar* fn ) 22035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{ 22135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj vex_printf( "\nvex: %s:%d (%s): Assertion `%s' failed.\n", 22235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj file, line, fn, expr ); 22335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj (*vex_failure_exit)(); 22435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 22535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 226eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian/* To be used in assert-like (i.e. should never ever happen) situations */ 22735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj__attribute__ ((noreturn)) 22876714fdcf200b71609ab5b79aaef11c37c7b8912florianvoid vpanic ( const HChar* str ) 22935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{ 23035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj vex_printf("\nvex: the `impossible' happened:\n %s\n", str); 23135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj (*vex_failure_exit)(); 23235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 23335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 23435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 23535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------*/ 23635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*--- vex_printf ---*/ 23735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------*/ 23835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 23935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* This should be the only <...> include in the entire VEX library. 24035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj New code for vex_util.c should go above this point. */ 24135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj#include <stdarg.h> 24235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 24304fc6b1eab791c7387b81b9fd820f4ae6aaf90a2florianSizeT vex_strlen ( const HChar* str ) 24435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{ 24504fc6b1eab791c7387b81b9fd820f4ae6aaf90a2florian SizeT i = 0; 24635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj while (str[i] != 0) i++; 24735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj return i; 24835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 24935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 2505827784e6bb74e2a032b66ec310776c24fd88729sewardjBool vex_streq ( const HChar* s1, const HChar* s2 ) 25136ca51378f8851635df814230fa23f2c409b9eddsewardj{ 25236ca51378f8851635df814230fa23f2c409b9eddsewardj while (True) { 25336ca51378f8851635df814230fa23f2c409b9eddsewardj if (*s1 == 0 && *s2 == 0) 25436ca51378f8851635df814230fa23f2c409b9eddsewardj return True; 25536ca51378f8851635df814230fa23f2c409b9eddsewardj if (*s1 != *s2) 25636ca51378f8851635df814230fa23f2c409b9eddsewardj return False; 25736ca51378f8851635df814230fa23f2c409b9eddsewardj s1++; 25836ca51378f8851635df814230fa23f2c409b9eddsewardj s2++; 25936ca51378f8851635df814230fa23f2c409b9eddsewardj } 26036ca51378f8851635df814230fa23f2c409b9eddsewardj} 26135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 26204fc6b1eab791c7387b81b9fd820f4ae6aaf90a2florianvoid vex_bzero ( void* sV, SizeT n ) 263c9069f2908814843e9a4da00da9c8905440195a6sewardj{ 26404fc6b1eab791c7387b81b9fd820f4ae6aaf90a2florian SizeT i; 265c9069f2908814843e9a4da00da9c8905440195a6sewardj UChar* s = (UChar*)sV; 266c9069f2908814843e9a4da00da9c8905440195a6sewardj /* No laughing, please. Just don't call this too often. Thank you 267c9069f2908814843e9a4da00da9c8905440195a6sewardj for your attention. */ 268c9069f2908814843e9a4da00da9c8905440195a6sewardj for (i = 0; i < n; i++) s[i] = 0; 269c9069f2908814843e9a4da00da9c8905440195a6sewardj} 270c9069f2908814843e9a4da00da9c8905440195a6sewardj 27135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 272da46fdd3b076e02b0171b2371685bad99869dc66sewardj/* Convert N0 into ascii in BUF, which is assumed to be big enough (at 273da46fdd3b076e02b0171b2371685bad99869dc66sewardj least 67 bytes long). Observe BASE, SYNED and HEXCAPS. */ 274da46fdd3b076e02b0171b2371685bad99869dc66sewardjstatic 275da46fdd3b076e02b0171b2371685bad99869dc66sewardjvoid convert_int ( /*OUT*/HChar* buf, Long n0, 276da46fdd3b076e02b0171b2371685bad99869dc66sewardj Int base, Bool syned, Bool hexcaps ) 277da46fdd3b076e02b0171b2371685bad99869dc66sewardj{ 278da46fdd3b076e02b0171b2371685bad99869dc66sewardj ULong u0; 279da46fdd3b076e02b0171b2371685bad99869dc66sewardj HChar c; 280da46fdd3b076e02b0171b2371685bad99869dc66sewardj Bool minus = False; 281da46fdd3b076e02b0171b2371685bad99869dc66sewardj Int i, j, bufi = 0; 282da46fdd3b076e02b0171b2371685bad99869dc66sewardj buf[bufi] = 0; 283da46fdd3b076e02b0171b2371685bad99869dc66sewardj 284da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (syned) { 285da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (n0 < 0) { 286da46fdd3b076e02b0171b2371685bad99869dc66sewardj minus = True; 287da46fdd3b076e02b0171b2371685bad99869dc66sewardj u0 = (ULong)(-n0); 288da46fdd3b076e02b0171b2371685bad99869dc66sewardj } else { 289da46fdd3b076e02b0171b2371685bad99869dc66sewardj u0 = (ULong)(n0); 290da46fdd3b076e02b0171b2371685bad99869dc66sewardj } 291da46fdd3b076e02b0171b2371685bad99869dc66sewardj } else { 292da46fdd3b076e02b0171b2371685bad99869dc66sewardj u0 = (ULong)n0; 29335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 29435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 295da46fdd3b076e02b0171b2371685bad99869dc66sewardj while (1) { 296c7cd2142ff0172bd3702d0607426a8014d8842e5sewardj buf[bufi++] = toHChar('0' + toUInt(u0 % base)); 297da46fdd3b076e02b0171b2371685bad99869dc66sewardj u0 /= base; 298da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (u0 == 0) break; 29935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 300da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (minus) 301da46fdd3b076e02b0171b2371685bad99869dc66sewardj buf[bufi++] = '-'; 302da46fdd3b076e02b0171b2371685bad99869dc66sewardj 303da46fdd3b076e02b0171b2371685bad99869dc66sewardj buf[bufi] = 0; 304da46fdd3b076e02b0171b2371685bad99869dc66sewardj for (i = 0; i < bufi; i++) 305da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (buf[i] > '9') 306c7cd2142ff0172bd3702d0607426a8014d8842e5sewardj buf[i] = toHChar(buf[i] + (hexcaps ? 'A' : 'a') - '9' - 1); 307da46fdd3b076e02b0171b2371685bad99869dc66sewardj 308da46fdd3b076e02b0171b2371685bad99869dc66sewardj i = 0; 309da46fdd3b076e02b0171b2371685bad99869dc66sewardj j = bufi-1; 310da46fdd3b076e02b0171b2371685bad99869dc66sewardj while (i <= j) { 311da46fdd3b076e02b0171b2371685bad99869dc66sewardj c = buf[i]; 312da46fdd3b076e02b0171b2371685bad99869dc66sewardj buf[i] = buf[j]; 313da46fdd3b076e02b0171b2371685bad99869dc66sewardj buf[j] = c; 314da46fdd3b076e02b0171b2371685bad99869dc66sewardj i++; 315da46fdd3b076e02b0171b2371685bad99869dc66sewardj j--; 31635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 31735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 31835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 31935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 320da46fdd3b076e02b0171b2371685bad99869dc66sewardj/* A half-arsed and buggy, but good-enough, implementation of 321da46fdd3b076e02b0171b2371685bad99869dc66sewardj printf. */ 322da46fdd3b076e02b0171b2371685bad99869dc66sewardjstatic 323da46fdd3b076e02b0171b2371685bad99869dc66sewardjUInt vprintf_wrk ( void(*sink)(HChar), 32476714fdcf200b71609ab5b79aaef11c37c7b8912florian const HChar* format, 325da46fdd3b076e02b0171b2371685bad99869dc66sewardj va_list ap ) 326da46fdd3b076e02b0171b2371685bad99869dc66sewardj{ 327da46fdd3b076e02b0171b2371685bad99869dc66sewardj# define PUT(_ch) \ 328da46fdd3b076e02b0171b2371685bad99869dc66sewardj do { sink(_ch); nout++; } \ 329da46fdd3b076e02b0171b2371685bad99869dc66sewardj while (0) 33035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 331da46fdd3b076e02b0171b2371685bad99869dc66sewardj# define PAD(_n) \ 332da46fdd3b076e02b0171b2371685bad99869dc66sewardj do { Int _qq = (_n); for (; _qq > 0; _qq--) PUT(padchar); } \ 333da46fdd3b076e02b0171b2371685bad99869dc66sewardj while (0) 33435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 335da46fdd3b076e02b0171b2371685bad99869dc66sewardj# define PUTSTR(_str) \ 33655085f8680acc89d727e321f3b34cae1a8c4093aflorian do { const HChar* _qq = _str; for (; *_qq; _qq++) PUT(*_qq); } \ 337da46fdd3b076e02b0171b2371685bad99869dc66sewardj while (0) 33835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 33976714fdcf200b71609ab5b79aaef11c37c7b8912florian const HChar* saved_format; 340c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian Bool longlong, ljustify, is_sizet; 341da46fdd3b076e02b0171b2371685bad99869dc66sewardj HChar padchar; 34204fc6b1eab791c7387b81b9fd820f4ae6aaf90a2florian Int fwidth, nout, len1, len3; 34304fc6b1eab791c7387b81b9fd820f4ae6aaf90a2florian SizeT len2; 344da46fdd3b076e02b0171b2371685bad99869dc66sewardj HChar intbuf[100]; /* big enough for a 64-bit # in base 2 */ 34535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 346da46fdd3b076e02b0171b2371685bad99869dc66sewardj nout = 0; 347da46fdd3b076e02b0171b2371685bad99869dc66sewardj while (1) { 34835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 349da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (!format) 35035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj break; 351da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (*format == 0) 352da46fdd3b076e02b0171b2371685bad99869dc66sewardj break; 353da46fdd3b076e02b0171b2371685bad99869dc66sewardj 354da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (*format != '%') { 355da46fdd3b076e02b0171b2371685bad99869dc66sewardj PUT(*format); 356da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 35735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj continue; 35835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 359da46fdd3b076e02b0171b2371685bad99869dc66sewardj 360da46fdd3b076e02b0171b2371685bad99869dc66sewardj saved_format = format; 361c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian longlong = is_sizet = False; 362da46fdd3b076e02b0171b2371685bad99869dc66sewardj ljustify = False; 363da46fdd3b076e02b0171b2371685bad99869dc66sewardj padchar = ' '; 364da46fdd3b076e02b0171b2371685bad99869dc66sewardj fwidth = 0; 365da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 366da46fdd3b076e02b0171b2371685bad99869dc66sewardj 367da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (*format == '-') { 368da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 369da46fdd3b076e02b0171b2371685bad99869dc66sewardj ljustify = True; 37035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 371da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (*format == '0') { 372da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 373da46fdd3b076e02b0171b2371685bad99869dc66sewardj padchar = '0'; 37435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 375473dc16b5a24914e11dbf884af25cd388a26eb11florian if (*format == '*') { 376473dc16b5a24914e11dbf884af25cd388a26eb11florian fwidth = va_arg(ap, Int); 37704fc6b1eab791c7387b81b9fd820f4ae6aaf90a2florian vassert(fwidth >= 0); 378da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 379473dc16b5a24914e11dbf884af25cd388a26eb11florian } else { 380473dc16b5a24914e11dbf884af25cd388a26eb11florian while (*format >= '0' && *format <= '9') { 381473dc16b5a24914e11dbf884af25cd388a26eb11florian fwidth = fwidth * 10 + (*format - '0'); 382473dc16b5a24914e11dbf884af25cd388a26eb11florian format++; 383473dc16b5a24914e11dbf884af25cd388a26eb11florian } 38435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 385da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (*format == 'l') { 386da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 387da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (*format == 'l') { 388da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 389c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian longlong = True; 390da46fdd3b076e02b0171b2371685bad99869dc66sewardj } 391c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian } else if (*format == 'z') { 392c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian format++; 393c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian is_sizet = True; 39435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 39535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 396da46fdd3b076e02b0171b2371685bad99869dc66sewardj switch (*format) { 397da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 's': { 39855085f8680acc89d727e321f3b34cae1a8c4093aflorian const HChar* str = va_arg(ap, HChar*); 399da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (str == NULL) 400da46fdd3b076e02b0171b2371685bad99869dc66sewardj str = "(null)"; 401da46fdd3b076e02b0171b2371685bad99869dc66sewardj len1 = len3 = 0; 402da46fdd3b076e02b0171b2371685bad99869dc66sewardj len2 = vex_strlen(str); 4037d730cfce15157aa78b822aeb66a7fab13b12aa3cerion if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 4047d730cfce15157aa78b822aeb66a7fab13b12aa3cerion len3 = ljustify ? fwidth-len2 : 0; } 405da46fdd3b076e02b0171b2371685bad99869dc66sewardj PAD(len1); PUTSTR(str); PAD(len3); 40635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj break; 407da46fdd3b076e02b0171b2371685bad99869dc66sewardj } 408da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 'c': { 409da46fdd3b076e02b0171b2371685bad99869dc66sewardj HChar c = (HChar)va_arg(ap, int); 410da46fdd3b076e02b0171b2371685bad99869dc66sewardj HChar str[2]; 411da46fdd3b076e02b0171b2371685bad99869dc66sewardj str[0] = c; 412da46fdd3b076e02b0171b2371685bad99869dc66sewardj str[1] = 0; 413da46fdd3b076e02b0171b2371685bad99869dc66sewardj len1 = len3 = 0; 414da46fdd3b076e02b0171b2371685bad99869dc66sewardj len2 = vex_strlen(str); 4157d730cfce15157aa78b822aeb66a7fab13b12aa3cerion if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 4167d730cfce15157aa78b822aeb66a7fab13b12aa3cerion len3 = ljustify ? fwidth-len2 : 0; } 417da46fdd3b076e02b0171b2371685bad99869dc66sewardj PAD(len1); PUTSTR(str); PAD(len3); 41835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj break; 419da46fdd3b076e02b0171b2371685bad99869dc66sewardj } 420da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 'd': { 421da46fdd3b076e02b0171b2371685bad99869dc66sewardj Long l; 422c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian vassert(is_sizet == False); // %zd is obscure; we don't allow it 423da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (longlong) { 424da46fdd3b076e02b0171b2371685bad99869dc66sewardj l = va_arg(ap, Long); 425da46fdd3b076e02b0171b2371685bad99869dc66sewardj } else { 426da46fdd3b076e02b0171b2371685bad99869dc66sewardj l = (Long)va_arg(ap, Int); 427da46fdd3b076e02b0171b2371685bad99869dc66sewardj } 428da46fdd3b076e02b0171b2371685bad99869dc66sewardj convert_int(intbuf, l, 10/*base*/, True/*signed*/, 429da46fdd3b076e02b0171b2371685bad99869dc66sewardj False/*irrelevant*/); 430da46fdd3b076e02b0171b2371685bad99869dc66sewardj len1 = len3 = 0; 431da46fdd3b076e02b0171b2371685bad99869dc66sewardj len2 = vex_strlen(intbuf); 4327d730cfce15157aa78b822aeb66a7fab13b12aa3cerion if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 4337d730cfce15157aa78b822aeb66a7fab13b12aa3cerion len3 = ljustify ? fwidth-len2 : 0; } 434da46fdd3b076e02b0171b2371685bad99869dc66sewardj PAD(len1); PUTSTR(intbuf); PAD(len3); 43535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj break; 436b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion } 437da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 'u': 438da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 'x': 439da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 'X': { 440da46fdd3b076e02b0171b2371685bad99869dc66sewardj Int base = *format == 'u' ? 10 : 16; 441da46fdd3b076e02b0171b2371685bad99869dc66sewardj Bool hexcaps = True; /* *format == 'X'; */ 442da46fdd3b076e02b0171b2371685bad99869dc66sewardj ULong l; 443c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian if (is_sizet) { 444c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian l = (ULong)va_arg(ap, SizeT); 445c66ba6536adc89a69ed9caaf3c16d575b729e73cflorian } else if (longlong) { 446da46fdd3b076e02b0171b2371685bad99869dc66sewardj l = va_arg(ap, ULong); 447da46fdd3b076e02b0171b2371685bad99869dc66sewardj } else { 448da46fdd3b076e02b0171b2371685bad99869dc66sewardj l = (ULong)va_arg(ap, UInt); 449b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion } 450da46fdd3b076e02b0171b2371685bad99869dc66sewardj convert_int(intbuf, l, base, False/*unsigned*/, hexcaps); 451da46fdd3b076e02b0171b2371685bad99869dc66sewardj len1 = len3 = 0; 452da46fdd3b076e02b0171b2371685bad99869dc66sewardj len2 = vex_strlen(intbuf); 4537d730cfce15157aa78b822aeb66a7fab13b12aa3cerion if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 4547d730cfce15157aa78b822aeb66a7fab13b12aa3cerion len3 = ljustify ? fwidth-len2 : 0; } 455da46fdd3b076e02b0171b2371685bad99869dc66sewardj PAD(len1); PUTSTR(intbuf); PAD(len3); 456da46fdd3b076e02b0171b2371685bad99869dc66sewardj break; 457da46fdd3b076e02b0171b2371685bad99869dc66sewardj } 458da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 'p': 459da46fdd3b076e02b0171b2371685bad99869dc66sewardj case 'P': { 460c7cd2142ff0172bd3702d0607426a8014d8842e5sewardj Bool hexcaps = toBool(*format == 'P'); 46193a09742b0de3d61718882c2d999f64be402564dflorian ULong l = (Addr)va_arg(ap, void*); 462da46fdd3b076e02b0171b2371685bad99869dc66sewardj convert_int(intbuf, l, 16/*base*/, False/*unsigned*/, hexcaps); 463da46fdd3b076e02b0171b2371685bad99869dc66sewardj len1 = len3 = 0; 464da46fdd3b076e02b0171b2371685bad99869dc66sewardj len2 = vex_strlen(intbuf)+2; 4657d730cfce15157aa78b822aeb66a7fab13b12aa3cerion if (fwidth > len2) { len1 = ljustify ? 0 : fwidth-len2; 4667d730cfce15157aa78b822aeb66a7fab13b12aa3cerion len3 = ljustify ? fwidth-len2 : 0; } 467da46fdd3b076e02b0171b2371685bad99869dc66sewardj PAD(len1); PUT('0'); PUT('x'); PUTSTR(intbuf); PAD(len3); 468b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion break; 469b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion } 470eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case '%': { 471eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj PUT('%'); 472eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 473eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj } 47435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj default: 475da46fdd3b076e02b0171b2371685bad99869dc66sewardj /* no idea what it is. Print the format literally and 476da46fdd3b076e02b0171b2371685bad99869dc66sewardj move on. */ 477da46fdd3b076e02b0171b2371685bad99869dc66sewardj while (saved_format <= format) { 478da46fdd3b076e02b0171b2371685bad99869dc66sewardj PUT(*saved_format); 479da46fdd3b076e02b0171b2371685bad99869dc66sewardj saved_format++; 480da46fdd3b076e02b0171b2371685bad99869dc66sewardj } 48135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj break; 48235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 483da46fdd3b076e02b0171b2371685bad99869dc66sewardj 484da46fdd3b076e02b0171b2371685bad99869dc66sewardj format++; 485da46fdd3b076e02b0171b2371685bad99869dc66sewardj 48635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 487da46fdd3b076e02b0171b2371685bad99869dc66sewardj 488da46fdd3b076e02b0171b2371685bad99869dc66sewardj return nout; 489da46fdd3b076e02b0171b2371685bad99869dc66sewardj 490da46fdd3b076e02b0171b2371685bad99869dc66sewardj# undef PUT 491da46fdd3b076e02b0171b2371685bad99869dc66sewardj# undef PAD 492da46fdd3b076e02b0171b2371685bad99869dc66sewardj# undef PUTSTR 49335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 49435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 49535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 49635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/* A general replacement for printf(). Note that only low-level 49735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj debugging info should be sent via here. The official route is to 49835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj to use vg_message(). This interface is deprecated. 49935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj*/ 5005827784e6bb74e2a032b66ec310776c24fd88729sewardjstatic HChar myprintf_buf[1000]; 5015827784e6bb74e2a032b66ec310776c24fd88729sewardjstatic Int n_myprintf_buf; 50235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 5035827784e6bb74e2a032b66ec310776c24fd88729sewardjstatic void add_to_myprintf_buf ( HChar c ) 50435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{ 505c7cd2142ff0172bd3702d0607426a8014d8842e5sewardj Bool emit = toBool(c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/); 506da46fdd3b076e02b0171b2371685bad99869dc66sewardj myprintf_buf[n_myprintf_buf++] = c; 507da46fdd3b076e02b0171b2371685bad99869dc66sewardj myprintf_buf[n_myprintf_buf] = 0; 508da46fdd3b076e02b0171b2371685bad99869dc66sewardj if (emit) { 50935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj (*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) ); 51035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj n_myprintf_buf = 0; 511da46fdd3b076e02b0171b2371685bad99869dc66sewardj myprintf_buf[n_myprintf_buf] = 0; 51235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 51335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 51435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 515eebdb2b9c85a2b925e4725657a2db9805f3fcde0florianstatic UInt vex_vprintf ( const HChar* format, va_list vargs ) 51635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj{ 51735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj UInt ret; 51835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 51935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj n_myprintf_buf = 0; 52035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj myprintf_buf[n_myprintf_buf] = 0; 52135421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs ); 52235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 52335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj if (n_myprintf_buf > 0) { 52435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj (*vex_log_bytes)( myprintf_buf, n_myprintf_buf ); 52535421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj } 52635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 527eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian return ret; 528eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian} 529eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian 530eebdb2b9c85a2b925e4725657a2db9805f3fcde0florianUInt vex_printf ( const HChar* format, ... ) 531eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian{ 532eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian UInt ret; 533eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian va_list vargs; 534eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian va_start(vargs, format); 535eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian ret = vex_vprintf(format, vargs); 53635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj va_end(vargs); 53735421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 53835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj return ret; 53935421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj} 54035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 541eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian/* Use this function to communicate to users that a (legitimate) situation 542eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian occured that we cannot handle (yet). */ 543eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian__attribute__ ((noreturn)) 544eebdb2b9c85a2b925e4725657a2db9805f3fcde0florianvoid vfatal ( const HChar* format, ... ) 545eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian{ 546eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian va_list vargs; 547eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian va_start(vargs, format); 548eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian vex_vprintf( format, vargs ); 549eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian va_end(vargs); 550eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian vex_printf("Cannot continue. Good-bye\n\n"); 551eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian 552eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian (*vex_failure_exit)(); 553eebdb2b9c85a2b925e4725657a2db9805f3fcde0florian} 55435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj 55541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj/* A general replacement for sprintf(). */ 55641f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 5575827784e6bb74e2a032b66ec310776c24fd88729sewardjstatic HChar *vg_sprintf_ptr; 55841f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 5595827784e6bb74e2a032b66ec310776c24fd88729sewardjstatic void add_to_vg_sprintf_buf ( HChar c ) 56041f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj{ 56141f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj *vg_sprintf_ptr++ = c; 56241f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj} 56341f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 56476714fdcf200b71609ab5b79aaef11c37c7b8912florianUInt vex_sprintf ( HChar* buf, const HChar *format, ... ) 56541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj{ 56641f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj Int ret; 56741f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj va_list vargs; 56841f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 56941f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj vg_sprintf_ptr = buf; 57041f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 57141f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj va_start(vargs,format); 57241f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 57341f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj ret = vprintf_wrk ( add_to_vg_sprintf_buf, format, vargs ); 57441f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj add_to_vg_sprintf_buf(0); 57541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 57641f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj va_end(vargs); 57741f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 57841f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj vassert(vex_strlen(buf) == ret); 57941f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj return ret; 58041f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj} 58141f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 58241f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj 58348729060949c3c8e2cfdd9aae20df000dac279c0sewardj/*---------------------------------------------------------*/ 58448729060949c3c8e2cfdd9aae20df000dac279c0sewardj/*--- Misaligned memory access support ---*/ 58548729060949c3c8e2cfdd9aae20df000dac279c0sewardj/*---------------------------------------------------------*/ 58648729060949c3c8e2cfdd9aae20df000dac279c0sewardj 58748729060949c3c8e2cfdd9aae20df000dac279c0sewardjUInt read_misaligned_UInt_LE ( void* addr ) 58848729060949c3c8e2cfdd9aae20df000dac279c0sewardj{ 58948729060949c3c8e2cfdd9aae20df000dac279c0sewardj UChar* p = (UChar*)addr; 59048729060949c3c8e2cfdd9aae20df000dac279c0sewardj UInt w = 0; 59148729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[3]; 59248729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[2]; 59348729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[1]; 59448729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[0]; 59548729060949c3c8e2cfdd9aae20df000dac279c0sewardj return w; 59648729060949c3c8e2cfdd9aae20df000dac279c0sewardj} 59748729060949c3c8e2cfdd9aae20df000dac279c0sewardj 59848729060949c3c8e2cfdd9aae20df000dac279c0sewardjULong read_misaligned_ULong_LE ( void* addr ) 59948729060949c3c8e2cfdd9aae20df000dac279c0sewardj{ 60048729060949c3c8e2cfdd9aae20df000dac279c0sewardj UChar* p = (UChar*)addr; 60148729060949c3c8e2cfdd9aae20df000dac279c0sewardj ULong w = 0; 60248729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[7]; 60348729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[6]; 60448729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[5]; 60548729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[4]; 60648729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[3]; 60748729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[2]; 60848729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[1]; 60948729060949c3c8e2cfdd9aae20df000dac279c0sewardj w = (w << 8) | p[0]; 61048729060949c3c8e2cfdd9aae20df000dac279c0sewardj return w; 61148729060949c3c8e2cfdd9aae20df000dac279c0sewardj} 61248729060949c3c8e2cfdd9aae20df000dac279c0sewardj 61348729060949c3c8e2cfdd9aae20df000dac279c0sewardjvoid write_misaligned_UInt_LE ( void* addr, UInt w ) 61448729060949c3c8e2cfdd9aae20df000dac279c0sewardj{ 61548729060949c3c8e2cfdd9aae20df000dac279c0sewardj UChar* p = (UChar*)addr; 61648729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[0] = (w & 0xFF); w >>= 8; 61748729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[1] = (w & 0xFF); w >>= 8; 61848729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[2] = (w & 0xFF); w >>= 8; 61948729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[3] = (w & 0xFF); w >>= 8; 62048729060949c3c8e2cfdd9aae20df000dac279c0sewardj} 62148729060949c3c8e2cfdd9aae20df000dac279c0sewardj 62248729060949c3c8e2cfdd9aae20df000dac279c0sewardjvoid write_misaligned_ULong_LE ( void* addr, ULong w ) 62348729060949c3c8e2cfdd9aae20df000dac279c0sewardj{ 62448729060949c3c8e2cfdd9aae20df000dac279c0sewardj UChar* p = (UChar*)addr; 62548729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[0] = (w & 0xFF); w >>= 8; 62648729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[1] = (w & 0xFF); w >>= 8; 62748729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[2] = (w & 0xFF); w >>= 8; 62848729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[3] = (w & 0xFF); w >>= 8; 62948729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[4] = (w & 0xFF); w >>= 8; 63048729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[5] = (w & 0xFF); w >>= 8; 63148729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[6] = (w & 0xFF); w >>= 8; 63248729060949c3c8e2cfdd9aae20df000dac279c0sewardj p[7] = (w & 0xFF); w >>= 8; 63348729060949c3c8e2cfdd9aae20df000dac279c0sewardj} 63448729060949c3c8e2cfdd9aae20df000dac279c0sewardj 63548729060949c3c8e2cfdd9aae20df000dac279c0sewardj 63635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/ 637cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end main_util.c ---*/ 63835421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj/*---------------------------------------------------------------*/ 639