Home | History | Annotate | Download | only in linux
      1 // Copyright (c) 2012, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 // This source file provides replacements for libc functions that we need. If
     31 // we call the libc functions directly we risk crashing in the dynamic linker
     32 // as it tries to resolve uncached PLT entries.
     33 
     34 #include "common/linux/linux_libc_support.h"
     35 
     36 #include <stddef.h>
     37 
     38 extern "C" {
     39 
     40 size_t my_strlen(const char* s) {
     41   size_t len = 0;
     42   while (*s++) len++;
     43   return len;
     44 }
     45 
     46 int my_strcmp(const char* a, const char* b) {
     47   for (;;) {
     48     if (*a < *b)
     49       return -1;
     50     else if (*a > *b)
     51       return 1;
     52     else if (*a == 0)
     53       return 0;
     54     a++;
     55     b++;
     56   }
     57 }
     58 
     59 int my_strncmp(const char* a, const char* b, size_t len) {
     60   for (size_t i = 0; i < len; ++i) {
     61     if (*a < *b)
     62       return -1;
     63     else if (*a > *b)
     64       return 1;
     65     else if (*a == 0)
     66       return 0;
     67     a++;
     68     b++;
     69   }
     70 
     71   return 0;
     72 }
     73 
     74 // Parse a non-negative integer.
     75 //   result: (output) the resulting non-negative integer
     76 //   s: a NUL terminated string
     77 // Return true iff successful.
     78 bool my_strtoui(int* result, const char* s) {
     79   if (*s == 0)
     80     return false;
     81   int r = 0;
     82   for (;; s++) {
     83     if (*s == 0)
     84       break;
     85     const int old_r = r;
     86     r *= 10;
     87     if (*s < '0' || *s > '9')
     88       return false;
     89     r += *s - '0';
     90     if (r < old_r)
     91       return false;
     92   }
     93 
     94   *result = r;
     95   return true;
     96 }
     97 
     98 // Return the length of the given unsigned integer when expressed in base 10.
     99 unsigned my_uint_len(uintmax_t i) {
    100   if (!i)
    101     return 1;
    102 
    103   int len = 0;
    104   while (i) {
    105     len++;
    106     i /= 10;
    107   }
    108 
    109   return len;
    110 }
    111 
    112 // Convert an unsigned integer to a string
    113 //   output: (output) the resulting string is written here. This buffer must be
    114 //     large enough to hold the resulting string. Call |my_uint_len| to get the
    115 //     required length.
    116 //   i: the unsigned integer to serialise.
    117 //   i_len: the length of the integer in base 10 (see |my_uint_len|).
    118 void my_uitos(char* output, uintmax_t i, unsigned i_len) {
    119   for (unsigned index = i_len; index; --index, i /= 10)
    120     output[index - 1] = '0' + (i % 10);
    121 }
    122 
    123 const char* my_strchr(const char* haystack, char needle) {
    124   while (*haystack && *haystack != needle)
    125     haystack++;
    126   if (*haystack == needle)
    127     return haystack;
    128   return (const char*) 0;
    129 }
    130 
    131 const char* my_strrchr(const char* haystack, char needle) {
    132   const char* ret = NULL;
    133   while (*haystack) {
    134     if (*haystack == needle)
    135       ret = haystack;
    136     haystack++;
    137   }
    138   return ret;
    139 }
    140 
    141 void* my_memchr(const void* src, int needle, size_t src_len) {
    142   const unsigned char* p = (const unsigned char*)src;
    143   const unsigned char* p_end = p + src_len;
    144   for (; p < p_end; ++p) {
    145     if (*p == needle)
    146       return (void*)p;
    147   }
    148   return NULL;
    149 }
    150 
    151 // Read a hex value
    152 //   result: (output) the resulting value
    153 //   s: a string
    154 // Returns a pointer to the first invalid charactor.
    155 const char* my_read_hex_ptr(uintptr_t* result, const char* s) {
    156   uintptr_t r = 0;
    157 
    158   for (;; ++s) {
    159     if (*s >= '0' && *s <= '9') {
    160       r <<= 4;
    161       r += *s - '0';
    162     } else if (*s >= 'a' && *s <= 'f') {
    163       r <<= 4;
    164       r += (*s - 'a') + 10;
    165     } else if (*s >= 'A' && *s <= 'F') {
    166       r <<= 4;
    167       r += (*s - 'A') + 10;
    168     } else {
    169       break;
    170     }
    171   }
    172 
    173   *result = r;
    174   return s;
    175 }
    176 
    177 const char* my_read_decimal_ptr(uintptr_t* result, const char* s) {
    178   uintptr_t r = 0;
    179 
    180   for (;; ++s) {
    181     if (*s >= '0' && *s <= '9') {
    182       r *= 10;
    183       r += *s - '0';
    184     } else {
    185       break;
    186     }
    187   }
    188   *result = r;
    189   return s;
    190 }
    191 
    192 void my_memset(void* ip, char c, size_t len) {
    193   char* p = (char *) ip;
    194   while (len--)
    195     *p++ = c;
    196 }
    197 
    198 size_t my_strlcpy(char* s1, const char* s2, size_t len) {
    199   size_t pos1 = 0;
    200   size_t pos2 = 0;
    201 
    202   while (s2[pos2] != '\0') {
    203     if (pos1 + 1 < len) {
    204       s1[pos1] = s2[pos2];
    205       pos1++;
    206     }
    207     pos2++;
    208   }
    209   if (len > 0)
    210     s1[pos1] = '\0';
    211 
    212   return pos2;
    213 }
    214 
    215 size_t my_strlcat(char* s1, const char* s2, size_t len) {
    216   size_t pos1 = 0;
    217 
    218   while (pos1 < len && s1[pos1] != '\0')
    219     pos1++;
    220 
    221   if (pos1 == len)
    222     return pos1;
    223 
    224   return pos1 + my_strlcpy(s1 + pos1, s2, len - pos1);
    225 }
    226 
    227 int my_isspace(int ch) {
    228   // Matches the C locale.
    229   const char spaces[] = " \t\f\n\r\t\v";
    230   for (size_t i = 0; i < sizeof(spaces); i++) {
    231     if (ch == spaces[i])
    232       return 1;
    233   }
    234   return 0;
    235 }
    236 
    237 }  // extern "C"
    238