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