Viewing file: pr95443-1.c (2.79 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* { dg-do run { target { sysconf && mmap } } } */ /* { dg-options "-O2 -minline-all-stringops" } */
#include <stdint.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #ifndef MAP_ANON #define MAP_ANON 0 #endif #ifndef MAP_FAILED #define MAP_FAILED ((void *)-1) #endif
uint8_t shift[256];
static size_t __attribute__ ((noclone, noinline)) hash2(const unsigned char *p) { return (((size_t)(p)[0] - ((size_t)(p)[-1] << 3)) % sizeof (shift)); }
char * simple_strstr (const char *haystack, const char *needle) { const unsigned char *hs = (const unsigned char *) haystack; const unsigned char *ne = (const unsigned char *) needle; size_t ne_len = strlen ((const char*)ne); size_t hs_len = strnlen ((const char*)hs, ne_len | 512);
if (hs_len < ne_len) return NULL;
if (memcmp (hs, ne, ne_len) == 0) return (char *) hs;
const unsigned char *end = hs + hs_len - ne_len; size_t tmp, shift1; size_t m1 = ne_len - 1; size_t offset = 0;
memset (shift, 0, sizeof (shift)); for (int i = 1; i < m1; i++) shift[hash2 (ne + i)] = i; shift1 = m1 - shift[hash2 (ne + m1)]; shift[hash2 (ne + m1)] = m1;
while (1) { if (__builtin_expect (hs > end, 0)) { end += strnlen ((const char*)end + m1 + 1, 2048); if (hs > end) return NULL; }
do { hs += m1; tmp = shift[hash2 (hs)]; } while (tmp == 0 && hs <= end);
hs -= tmp; if (tmp < m1) continue;
if (m1 < 15 || memcmp (hs + offset, ne + offset, 8) == 0) { if (memcmp (hs, ne, m1) == 0) return (void *) hs;
offset = (offset >= 8 ? offset : m1) - 8; }
hs += shift1; } }
static int check_result (const char *s1, const char *s2, char *exp_result) { char *result = simple_strstr (s1, s2); if (result != exp_result) return -1;
return 0; }
void __attribute__ ((noclone, noinline)) check1 (void) { const char s1[] = "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD"; const char s2[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD"; char *exp_result;
exp_result = simple_strstr (s1, s2); if (check_result (s1, s2, exp_result) != 0) abort (); }
int main (void) { unsigned char *buf1, *buf2; size_t page_size = 2 * sysconf(_SC_PAGESIZE); buf1 = mmap (0, (1 + 1) * page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (buf1 == MAP_FAILED) return -1; if (mprotect (buf1 + 1 * page_size, page_size, PROT_NONE)) return -1; buf2 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (buf2 == MAP_FAILED) return -1; if (mprotect (buf2 + page_size, page_size, PROT_NONE)) return -1;
memset (buf1, 0xa5, 1 * page_size); memset (buf2, 0x5a, page_size);
check1 (); return 0; }
|