m_libcbase.c revision 25d7dfb102496d6432189290b9234dd19c6029ae
137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan 237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/*--------------------------------------------------------------------*/ 337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/*--- Entirely standalone libc stuff. m_libcbase.c ---*/ 437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan/*--------------------------------------------------------------------*/ 59ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant 69ad441ffec97db647fee3725b3424284fb913e14Howard Hinnant/* 737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan This file is part of Valgrind, a dynamic binary instrumentation 837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan framework. 937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan 1037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan Copyright (C) 2000-2007 Julian Seward 1137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan jseward@acm.org 1237a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan 1337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan This program is free software; you can redistribute it and/or 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar modify it under the terms of the GNU General Public License as 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar published by the Free Software Foundation; either version 2 of the 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar License, or (at your option) any later version. 1737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar This program is distributed in the hope that it will be useful, but 1937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan WITHOUT ANY WARRANTY; without even the implied warranty of 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 210193b74976719b8aea4cb8874ba36b75836a8d6eChandler Carruth General Public License for more details. 2237b97d1cf4501b94347e0b4e880f4b25825a289fAnton Korobeynikov 23cd25a5ffd64c5be8d4d838d21fd252ce246b898cStephen Canon You should have received a copy of the GNU General Public License 241c5f89b1dd741135a4007ab577723d422f421eecAnton Korobeynikov along with this program; if not, write to the Free Software 25b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 02111-1307, USA. 27b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 28b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar The GNU General Public License is contained in the file COPYING. 29b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar*/ 30b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 3137a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan#include "pub_core_basics.h" 32b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar#include "pub_core_libcbase.h" 3337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan 34b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar/* --------------------------------------------------------------------- 35b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar Char functions. 36b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ------------------------------------------------------------------ */ 3737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan 3837a6a455466e5b197311771a777ab241e471ed8aEdward O'CallaghanBool VG_(isspace) ( Char c ) 39b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 4037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan return (c == ' ' || c == '\n' || c == '\t' || 41b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar c == '\f' || c == '\v' || c == '\r'); 42b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 4337a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan 4437a6a455466e5b197311771a777ab241e471ed8aEdward O'CallaghanBool VG_(isdigit) ( Char c ) 45b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar{ 46b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return (c >= '0' && c <= '9'); 47b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 48b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 49b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar/* --------------------------------------------------------------------- 5037a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan Converting strings to numbers 51b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar ------------------------------------------------------------------ */ 52b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 5337a6a455466e5b197311771a777ab241e471ed8aEdward O'CallaghanLong VG_(atoll) ( Char* str ) 5437a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan{ 5537a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan Bool neg = False; 5637a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan Long n = 0; 5737a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan if (*str == '-') { str++; neg = True; }; 5837a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan while (*str >= '0' && *str <= '9') { 5937a6a455466e5b197311771a777ab241e471ed8aEdward O'Callaghan n = 10*n + (Long)(*str - '0'); 60b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar str++; 61b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar } 62b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar if (neg) n = -n; 63b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar return n; 64b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar} 65b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar 66b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel DunbarLong VG_(atoll16) ( Char* str ) 67{ 68 Bool neg = False; 69 Long n = 0; 70 if (*str == '-') { str++; neg = True; }; 71 if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X')) { 72 str += 2; 73 } 74 while (True) { 75 Char c = *str; 76 if (c >= '0' && c <= (Char)'9') { 77 n = 16*n + (Long)(c - '0'); 78 } 79 else 80 if (c >= 'A' && c <= (Char)'F') { 81 n = 16*n + (Long)((c - 'A') + 10); 82 } 83 else 84 if (c >= 'a' && c <= (Char)'f') { 85 n = 16*n + (Long)((c - 'a') + 10); 86 } 87 else { 88 break; 89 } 90 str++; 91 } 92 if (neg) n = -n; 93 return n; 94} 95 96Long VG_(atoll36) ( Char* str ) 97{ 98 Bool neg = False; 99 Long n = 0; 100 if (*str == '-') { str++; neg = True; }; 101 while (True) { 102 Char c = *str; 103 if (c >= '0' && c <= (Char)'9') { 104 n = 36*n + (Long)(c - '0'); 105 } 106 else 107 if (c >= 'A' && c <= (Char)'Z') { 108 n = 36*n + (Long)((c - 'A') + 10); 109 } 110 else 111 if (c >= 'a' && c <= (Char)'z') { 112 n = 36*n + (Long)((c - 'a') + 10); 113 } 114 else { 115 break; 116 } 117 str++; 118 } 119 if (neg) n = -n; 120 return n; 121} 122 123/* --------------------------------------------------------------------- 124 String functions 125 ------------------------------------------------------------------ */ 126 127Int VG_(strlen) ( const Char* str ) 128{ 129 Int i = 0; 130 while (str[i] != 0) i++; 131 return i; 132} 133 134Char* VG_(strcat) ( Char* dest, const Char* src ) 135{ 136 Char* dest_orig = dest; 137 while (*dest) dest++; 138 while (*src) *dest++ = *src++; 139 *dest = 0; 140 return dest_orig; 141} 142 143Char* VG_(strncat) ( Char* dest, const Char* src, SizeT n ) 144{ 145 Char* dest_orig = dest; 146 while (*dest) dest++; 147 while (*src && n > 0) { *dest++ = *src++; n--; } 148 *dest = 0; 149 return dest_orig; 150} 151 152Char* VG_(strpbrk) ( const Char* s, const Char* accept ) 153{ 154 const Char* a; 155 while (*s) { 156 a = accept; 157 while (*a) 158 if (*a++ == *s) 159 return (Char *) s; 160 s++; 161 } 162 return NULL; 163} 164 165Char* VG_(strcpy) ( Char* dest, const Char* src ) 166{ 167 Char* dest_orig = dest; 168 while (*src) *dest++ = *src++; 169 *dest = 0; 170 return dest_orig; 171} 172 173/* Copy bytes, not overrunning the end of dest and always ensuring 174 zero termination. */ 175void VG_(strncpy_safely) ( Char* dest, const Char* src, SizeT ndest ) 176{ 177 Int i = 0; 178 while (True) { 179 dest[i] = 0; 180 if (src[i] == 0) return; 181 if (i >= ndest-1) return; 182 dest[i] = src[i]; 183 i++; 184 } 185} 186 187Char* VG_(strncpy) ( Char* dest, const Char* src, SizeT ndest ) 188{ 189 Int i = 0; 190 while (True) { 191 if (i >= ndest) return dest; /* reached limit */ 192 dest[i] = src[i]; 193 if (src[i++] == 0) { 194 /* reached NUL; pad rest with zeroes as required */ 195 while (i < ndest) dest[i++] = 0; 196 return dest; 197 } 198 } 199} 200 201Int VG_(strcmp) ( const Char* s1, const Char* s2 ) 202{ 203 while (True) { 204 if (*s1 == 0 && *s2 == 0) return 0; 205 if (*s1 == 0) return -1; 206 if (*s2 == 0) return 1; 207 208 if (*(UChar*)s1 < *(UChar*)s2) return -1; 209 if (*(UChar*)s1 > *(UChar*)s2) return 1; 210 211 s1++; s2++; 212 } 213} 214 215static Bool isterm ( Char c ) 216{ 217 return ( VG_(isspace)(c) || 0 == c ); 218} 219 220Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 ) 221{ 222 while (True) { 223 if (isterm(*s1) && isterm(*s2)) return 0; 224 if (isterm(*s1)) return -1; 225 if (isterm(*s2)) return 1; 226 227 if (*(UChar*)s1 < *(UChar*)s2) return -1; 228 if (*(UChar*)s1 > *(UChar*)s2) return 1; 229 230 s1++; s2++; 231 } 232} 233 234Int VG_(strncmp) ( const Char* s1, const Char* s2, SizeT nmax ) 235{ 236 Int n = 0; 237 while (True) { 238 if (n >= nmax) return 0; 239 if (*s1 == 0 && *s2 == 0) return 0; 240 if (*s1 == 0) return -1; 241 if (*s2 == 0) return 1; 242 243 if (*(UChar*)s1 < *(UChar*)s2) return -1; 244 if (*(UChar*)s1 > *(UChar*)s2) return 1; 245 246 s1++; s2++; n++; 247 } 248} 249 250Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, SizeT nmax ) 251{ 252 Int n = 0; 253 while (True) { 254 if (n >= nmax) return 0; 255 if (isterm(*s1) && isterm(*s2)) return 0; 256 if (isterm(*s1)) return -1; 257 if (isterm(*s2)) return 1; 258 259 if (*(UChar*)s1 < *(UChar*)s2) return -1; 260 if (*(UChar*)s1 > *(UChar*)s2) return 1; 261 262 s1++; s2++; n++; 263 } 264} 265 266Char* VG_(strstr) ( const Char* haystack, Char* needle ) 267{ 268 Int n; 269 if (haystack == NULL) 270 return NULL; 271 n = VG_(strlen)(needle); 272 while (True) { 273 if (haystack[0] == 0) 274 return NULL; 275 if (VG_(strncmp)(haystack, needle, n) == 0) 276 return (Char*)haystack; 277 haystack++; 278 } 279} 280 281Char* VG_(strchr) ( const Char* s, Char c ) 282{ 283 while (True) { 284 if (*s == c) return (Char*)s; 285 if (*s == 0) return NULL; 286 s++; 287 } 288} 289 290Char* VG_(strrchr) ( const Char* s, Char c ) 291{ 292 Int n = VG_(strlen)(s); 293 while (--n > 0) { 294 if (s[n] == c) return (Char*)s + n; 295 } 296 return NULL; 297} 298 299/* --------------------------------------------------------------------- 300 A simple string matching routine, purloined from Hugs98. 301 '*' matches any sequence of zero or more characters 302 '?' matches any single character exactly 303 '\c' matches the character c only (ignoring special chars) 304 c matches the character c only 305 ------------------------------------------------------------------ */ 306 307/* Keep track of recursion depth. */ 308static Int recDepth; 309 310// Nb: vg_assert disabled because we can't use it from this module... 311static Bool string_match_wrk ( const Char* pat, const Char* str ) 312{ 313 //vg_assert(recDepth >= 0 && recDepth < 500); 314 recDepth++; 315 for (;;) { 316 switch (*pat) { 317 case '\0':recDepth--; 318 return (*str=='\0'); 319 case '*': do { 320 if (string_match_wrk(pat+1,str)) { 321 recDepth--; 322 return True; 323 } 324 } while (*str++); 325 recDepth--; 326 return False; 327 case '?': if (*str++=='\0') { 328 recDepth--; 329 return False; 330 } 331 pat++; 332 break; 333 case '\\':if (*++pat == '\0') { 334 recDepth--; 335 return False; /* spurious trailing \ in pattern */ 336 } 337 /* falls through to ... */ 338 default : if (*pat++ != *str++) { 339 recDepth--; 340 return False; 341 } 342 break; 343 } 344 } 345} 346 347Bool VG_(string_match) ( const Char* pat, const Char* str ) 348{ 349 Bool b; 350 recDepth = 0; 351 b = string_match_wrk ( pat, str ); 352 //vg_assert(recDepth == 0); 353 /* 354 VG_(printf)("%s %s %s\n", 355 b?"TRUE ":"FALSE", pat, str); 356 */ 357 return b; 358} 359 360 361/* --------------------------------------------------------------------- 362 mem* functions 363 ------------------------------------------------------------------ */ 364 365void* VG_(memcpy) ( void *dest, const void *src, SizeT sz ) 366{ 367 const UChar* s = (const UChar*)src; 368 UChar* d = (UChar*)dest; 369 const UInt* sI = (const UInt*)src; 370 UInt* dI = (UInt*)dest; 371 372 if (VG_IS_4_ALIGNED(dI) && VG_IS_4_ALIGNED(sI)) { 373 while (sz >= 16) { 374 dI[0] = sI[0]; 375 dI[1] = sI[1]; 376 dI[2] = sI[2]; 377 dI[3] = sI[3]; 378 sz -= 16; 379 dI += 4; 380 sI += 4; 381 } 382 if (sz == 0) 383 return dest; 384 while (sz >= 4) { 385 dI[0] = sI[0]; 386 sz -= 4; 387 dI += 1; 388 sI += 1; 389 } 390 if (sz == 0) 391 return dest; 392 s = (const UChar*)sI; 393 d = (UChar*)dI; 394 } 395 396 while (sz--) 397 *d++ = *s++; 398 399 return dest; 400} 401 402void* VG_(memset) ( void *dest, Int c, SizeT sz ) 403{ 404 Char *d = (Char *)dest; 405 while (sz >= 4) { 406 d[0] = c; 407 d[1] = c; 408 d[2] = c; 409 d[3] = c; 410 d += 4; 411 sz -= 4; 412 } 413 while (sz > 0) { 414 d[0] = c; 415 d++; 416 sz--; 417 } 418 return dest; 419} 420 421Int VG_(memcmp) ( const void* s1, const void* s2, SizeT n ) 422{ 423 Int res; 424 const UChar *p1 = s1; 425 const UChar *p2 = s2; 426 UChar a0; 427 UChar b0; 428 429 while (n != 0) { 430 a0 = p1[0]; 431 b0 = p2[0]; 432 p1 += 1; 433 p2 += 1; 434 res = a0 - b0; 435 if (res != 0) 436 return res; 437 n -= 1; 438 } 439 return 0; 440} 441 442/* --------------------------------------------------------------------- 443 Misc useful functions 444 ------------------------------------------------------------------ */ 445 446/* Returns the base-2 logarithm of x. Returns -1 if x is not a power of two. */ 447Int VG_(log2) ( Int x ) 448{ 449 Int i; 450 /* Any more than 32 and we overflow anyway... */ 451 for (i = 0; i < 32; i++) { 452 if (1 << i == x) return i; 453 } 454 return -1; 455} 456 457 458// Generic shell sort. Like stdlib.h's qsort(). 459void VG_(ssort)( void* base, SizeT nmemb, SizeT size, 460 Int (*compar)(void*, void*) ) 461{ 462 Int incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, 463 9841, 29524, 88573, 265720, 464 797161, 2391484 }; 465 Int lo = 0; 466 Int hi = nmemb-1; 467 Int i, j, h, bigN, hp; 468 469 bigN = hi - lo + 1; if (bigN < 2) return; 470 hp = 0; while (hp < 14 && incs[hp] < bigN) hp++; hp--; 471 472 #define SORT \ 473 for ( ; hp >= 0; hp--) { \ 474 h = incs[hp]; \ 475 for (i = lo + h; i <= hi; i++) { \ 476 ASSIGN(v,0, a,i); \ 477 j = i; \ 478 while (COMPAR(a,(j-h), v,0) > 0) { \ 479 ASSIGN(a,j, a,(j-h)); \ 480 j = j - h; \ 481 if (j <= (lo + h - 1)) break; \ 482 } \ 483 ASSIGN(a,j, v,0); \ 484 } \ 485 } 486 487 // Specialised cases 488 if (sizeof(ULong) == size) { 489 490 #define ASSIGN(dst, dsti, src, srci) \ 491 (dst)[(dsti)] = (src)[(srci)]; 492 493 #define COMPAR(dst, dsti, src, srci) \ 494 compar( (void*)(& (dst)[(dsti)]), (void*)(& (src)[(srci)]) ) 495 496 ULong* a = (ULong*)base; 497 ULong v[1]; 498 499 SORT; 500 501 } else if (sizeof(UInt) == size) { 502 503 UInt* a = (UInt*)base; 504 UInt v[1]; 505 506 SORT; 507 508 } else if (sizeof(UShort) == size) { 509 UShort* a = (UShort*)base; 510 UShort v[1]; 511 512 SORT; 513 514 } else if (sizeof(UChar) == size) { 515 UChar* a = (UChar*)base; 516 UChar v[1]; 517 518 SORT; 519 520 #undef ASSIGN 521 #undef COMPAR 522 523 } else if ( (4*sizeof(UWord)) == size ) { 524 /* special-case 4 word-elements. This captures a lot of cases 525 from symbol table reading/canonicalisaton, because both DiLoc 526 and DiSym are 4 word structures. */ 527 HChar* a = base; 528 HChar v[size]; 529 530 #define ASSIGN(dst, dsti, src, srci) \ 531 do { UWord* dP = (UWord*)&dst[size*(dsti)]; \ 532 UWord* sP = (UWord*)&src[size*(srci)]; \ 533 dP[0] = sP[0]; \ 534 dP[1] = sP[1]; \ 535 dP[2] = sP[2]; \ 536 dP[3] = sP[3]; \ 537 } while (0) 538 539 #define COMPAR(dst, dsti, src, srci) \ 540 compar( &dst[size*(dsti)], &src[size*(srci)] ) 541 542 SORT; 543 544 #undef ASSIGN 545 #undef COMPAR 546 547 // General case 548 } else { 549 HChar* a = base; 550 HChar v[size]; // will be at least 'size' bytes 551 552 #define ASSIGN(dst, dsti, src, srci) \ 553 VG_(memcpy)( &dst[size*(dsti)], &src[size*(srci)], size ); 554 555 #define COMPAR(dst, dsti, src, srci) \ 556 compar( &dst[size*(dsti)], &src[size*(srci)] ) 557 558 SORT; 559 560 #undef ASSIGN 561 #undef COMPAR 562 } 563 #undef SORT 564} 565 566// This random number generator is based on the one suggested in Kernighan 567// and Ritchie's "The C Programming Language". 568 569// A pseudo-random number generator returning a random UInt. If pSeed 570// is NULL, it uses its own seed, which starts at zero. If pSeed is 571// non-NULL, it uses and updates whatever pSeed points at. 572 573static UInt seed = 0; 574 575UInt VG_(random)( /*MOD*/UInt* pSeed ) 576{ 577 if (pSeed == NULL) 578 pSeed = &seed; 579 580 *pSeed = (1103515245 * *pSeed + 12345); 581 return *pSeed; 582} 583 584/*--------------------------------------------------------------------*/ 585/*--- end ---*/ 586/*--------------------------------------------------------------------*/ 587 588