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