// Small freestanding C runtime subset shared by boot, kernel, drivers, and user support libraries. #include #include #include // Implements the strcpy operation. char* strcpy(char* dest, const char* src) { char* d = dest; while (*src) *d++ = *src++; *d = 0; return dest; } // Implements the strncpy operation. char* strncpy(char* dest, const char* src, size_t n) { size_t i; for (i = 0; i < n && src[i]; i++) dest[i] = src[i]; for (; i < n; i++) dest[i] = 0; return dest; } // Implements the strcat operation. char* strcat(char* dest, const char* src) { char* ptr = dest; while (*ptr != '\0') { ptr++; } while (*src != '\0') { *ptr = *src; ptr++; src++; } *ptr = '\0'; return dest; } // Implements the strncat operation. char* strncat(char* dest, const char* src, size_t n) { char* ptr = dest; while (*ptr != '\0') { ptr++; } while (n > 0 && *src != '\0') { *ptr = *src; ptr++; src++; n--; } *ptr = '\0'; return dest; } // Implements the strcmp operation. int strcmp(const char* s1, const char* s2) { while (*s1 && *s1 == *s2) s1++, s2++; return (unsigned char)*s1 - (unsigned char)*s2; } // Implements the strncmp operation. int strncmp(const char *s1, const char *s2, size_t n) { while (n && *s1 && (*s1 == *s2)) { s1++; s2++; n--; } return n == 0 ? 0 : *(unsigned char *)s1 - *(unsigned char *)s2; } // Implements the stricmp operation. int _stricmp(const char* s1, const char* s2) { // ASCII case folding works here because bit 0x20 distinguishes 'A' from 'a'. while (*s1 && ((*s1 | 0x20) == (*s2 | 0x20))) { s1++, s2++; } return (unsigned char)(*s1 | 0x20) - (unsigned char)(*s2 | 0x20); } // Implements the strlen operation. size_t strlen(const char* s) { size_t n = 0; while (*s++) n++; return n; } // Implements the strnlen operation. size_t strnlen(const char *s, size_t maxlen) { size_t len; for (len = 0; len < maxlen; len++) { if (s[len] == '\0') { break; } } return len; } // Implements the strchr operation. char* strchr(const char* s, int c) { while (*s) { if (*s == (char)c) return (char *)s; s++; } return NULL; } // Implements the strrchr operation. char* strrchr(const char* s, int c) { char ch = (char)c; const char* last = NULL; do { if (*s == ch) last = s; } while (*s++); return (char*)last; } // Implements the memset operation. void* memset(void* dest, int c, size_t n) { unsigned char* d = (unsigned char*)dest; size_t qwords = n / 8; size_t tail = n % 8; if (qwords > 0) { uint64_t value = (unsigned char)c; value |= value << 8; value |= value << 16; value |= value << 32; __stosq((unsigned __int64*)d, value, qwords); d += qwords * 8; } if (tail > 0) { __stosb(d, (unsigned char)c, tail); } return dest; } // Implements the memcpy operation. void* memcpy(void* dest, const void* src, size_t n) { unsigned char* d = (unsigned char*)dest; const unsigned char* s = (const unsigned char*)src; size_t qwords = n / 8; size_t tail = n % 8; if (qwords > 0) { __movsq((unsigned __int64*)d, (const unsigned __int64*)s, qwords); d += qwords * 8; s += qwords * 8; } if (tail > 0) { __movsb(d, s, tail); } return dest; } // Implements the memmove operation. void* memmove(void* dest, const void* src, size_t n) { unsigned char* d = (unsigned char*)dest; const unsigned char* s = (const unsigned char*)src; if (d < s) { // Forward copy: safe to use chunked __movsq + tail. size_t qwords = n / 8; size_t tail = n % 8; if (qwords > 0) { __movsq((unsigned __int64*)d, (const unsigned __int64*)s, qwords); d += qwords * 8; s += qwords * 8; } if (tail > 0) { __movsb(d, s, tail); } } else if (d > s) { // Backward copy: must process from end to avoid corruption. size_t qwords = n / 8; size_t tail = n % 8; // Copy tail bytes first from the very end. if (tail > 0) { for (size_t i = tail; i > 0; i--) { d[qwords * 8 + i - 1] = s[qwords * 8 + i - 1]; } } // Copy 64-bit chunks backward. if (qwords > 0) { unsigned __int64* dq = (unsigned __int64*)d; const unsigned __int64* sq = (const unsigned __int64*)s; for (size_t i = qwords; i > 0; i--) { dq[i - 1] = sq[i - 1]; } } } return dest; } // Implements the memcmp operation. int memcmp(const void* s1, const void* s2, size_t n) { const unsigned __int64* a64 = (const unsigned __int64*)s1; const unsigned __int64* b64 = (const unsigned __int64*)s2; size_t qwords = n / 8; size_t tail = n % 8; // Compare 8-byte blocks. for (size_t i = 0; i < qwords; i++) { if (a64[i] != b64[i]) { // Locate the exact mismatching byte within the quadword. const unsigned char* a8 = (const unsigned char*)&a64[i]; const unsigned char* b8 = (const unsigned char*)&b64[i]; for (size_t j = 0; j < 8; j++) { if (a8[j] != b8[j]) return (int)a8[j] - (int)b8[j]; } } } // Compare remaining tail bytes. const unsigned char* a8 = (const unsigned char*)(a64 + qwords); const unsigned char* b8 = (const unsigned char*)(b64 + qwords); for (size_t i = 0; i < tail; i++) { if (a8[i] != b8[i]) return (int)a8[i] - (int)b8[i]; } return 0; }