aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-09-11 16:13:11 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-09-11 16:13:11 +0000
commitcd69ef4c8a66e7155967a8b661a014856979cf31 (patch)
tree4a351ae4a4ca91abf29c85254b85ea8da71f74b0 /src/bin
parent59a9dfd11860888a35e96dfe51af63cea5cecfe1 (diff)
downloadefl-cd69ef4c8a66e7155967a8b661a014856979cf31.tar.gz
efl-cd69ef4c8a66e7155967a8b661a014856979cf31.tar.xz
efl-cd69ef4c8a66e7155967a8b661a014856979cf31.zip
merge: add evil files
SVN revision: 76464
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/evil/Makefile.am53
-rw-r--r--src/bin/evil/evil_suite.c221
-rw-r--r--src/bin/evil/evil_suite.h14
-rw-r--r--src/bin/evil/evil_test_dlfcn.c80
-rw-r--r--src/bin/evil/evil_test_dlfcn.h8
-rw-r--r--src/bin/evil/evil_test_environment.c178
-rw-r--r--src/bin/evil/evil_test_environment.h8
-rw-r--r--src/bin/evil/evil_test_gettimeofday.c51
-rw-r--r--src/bin/evil/evil_test_gettimeofday.h8
-rw-r--r--src/bin/evil/evil_test_link.c158
-rw-r--r--src/bin/evil/evil_test_link.h8
-rw-r--r--src/bin/evil/evil_test_memcpy.c145
-rw-r--r--src/bin/evil/evil_test_memcpy.h8
-rw-r--r--src/bin/evil/evil_test_mkstemp.c53
-rw-r--r--src/bin/evil/evil_test_mkstemp.h8
-rw-r--r--src/bin/evil/evil_test_pipe.c126
-rw-r--r--src/bin/evil/evil_test_pipe.h8
-rw-r--r--src/bin/evil/evil_test_print.c46
-rw-r--r--src/bin/evil/evil_test_print.h8
-rw-r--r--src/bin/evil/evil_test_realpath.c44
-rw-r--r--src/bin/evil/evil_test_realpath.h8
-rw-r--r--src/bin/evil/evil_test_util.c110
-rw-r--r--src/bin/evil/evil_test_util.h8
-rw-r--r--src/bin/evil/memcpy_glibc_arm.S231
-rwxr-xr-xsrc/bin/evil/memcpy_glibc_i686.S81
-rw-r--r--src/bin/evil/test_evil.c27
26 files changed, 1698 insertions, 0 deletions
diff --git a/src/bin/evil/Makefile.am b/src/bin/evil/Makefile.am
new file mode 100644
index 000000000..538bbdcc6
--- /dev/null
+++ b/src/bin/evil/Makefile.am
@@ -0,0 +1,53 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir) \
+-I$(top_srcdir)/bin \
+-I$(top_srcdir)/src/lib \
+@EVIL_CPPFLAGS@
+
+AM_CFLAGS = @EVIL_CFLAGS@
+
+bin_PROGRAMS = evil_suite test_evil
+
+evil_suite_SOURCES = \
+evil_suite.c \
+evil_test_dlfcn.c \
+evil_test_environment.c \
+evil_test_gettimeofday.c \
+evil_test_link.c \
+evil_test_memcpy.c \
+evil_test_mkstemp.c \
+evil_test_pipe.c \
+evil_test_print.c \
+evil_test_realpath.c \
+evil_test_util.c \
+evil_suite.h \
+evil_test_dlfcn.h \
+evil_test_environment.h \
+evil_test_gettimeofday.h \
+evil_test_link.h \
+evil_test_memcpy.h \
+evil_test_mkstemp.h \
+evil_test_pipe.h \
+evil_test_print.h \
+evil_test_realpath.h \
+evil_test_util.h
+
+if EVIL_HAVE_WINCE
+
+evil_suite_SOURCES += memcpy_glibc_arm.S
+
+#else
+
+#suite_SOURCES += memcpy_glibc_i686.S
+
+endif
+
+evil_suite_LDADD = $(top_builddir)/src/lib/libdl.la $(top_builddir)/src/lib/libevil.la -lm
+evil_suite_LDFLAGS = -Wl,--enable-auto-import
+
+test_evil_SOURCES = test_evil.c
+test_evil_LDADD = $(top_builddir)/src/lib/libevil.la
+test_evil_LDFLAGS = -Wl,--enable-auto-import
diff --git a/src/bin/evil/evil_suite.c b/src/bin/evil/evil_suite.c
new file mode 100644
index 000000000..ba928f068
--- /dev/null
+++ b/src/bin/evil/evil_suite.c
@@ -0,0 +1,221 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include "Evil.h"
+#include "evil_suite.h"
+#include "evil_test_dlfcn.h"
+#include "evil_test_environment.h"
+#include "evil_test_gettimeofday.h"
+#include "evil_test_link.h"
+#include "evil_test_memcpy.h"
+#include "evil_test_mkstemp.h"
+#include "evil_test_pipe.h"
+#include "evil_test_print.h"
+#include "evil_test_realpath.h"
+#include "evil_test_util.h"
+
+
+typedef int(*function)(suite *s);
+
+struct test
+{
+ const char *name;
+ function fct;
+};
+
+struct list
+{
+ void *data;
+ int succeed;
+ list *next;
+};
+
+struct suite
+{
+ LARGE_INTEGER freq;
+ LARGE_INTEGER start;
+ LARGE_INTEGER end;
+
+ list *first;
+ list *l;
+
+ int tests_count;
+ int tests_success;
+};
+
+
+static suite *
+suite_new(void)
+{
+ suite *s;
+
+ s = (suite *)malloc(sizeof(suite));
+ if (!s) return NULL;
+
+ if (!QueryPerformanceFrequency(&s->freq))
+ {
+ free(s);
+ return NULL;
+ }
+
+ s->first = NULL;
+ s->l = NULL;
+
+ s->tests_count = 0;
+ s->tests_success = 0;
+
+ return s;
+}
+
+static void
+suite_del(suite *s)
+{
+ list *l;
+ list *tmp;
+
+ if (!s) return;
+
+ l = s->first;
+ while (l)
+ {
+ tmp = l->next;
+ free(l->data);
+ free(l);
+ l = tmp;
+ }
+
+ free(s);
+}
+
+void
+suite_time_start(suite *s)
+{
+ QueryPerformanceCounter(&s->start);
+}
+
+void
+suite_time_stop(suite *s)
+{
+ QueryPerformanceCounter(&s->end);
+}
+
+double
+suite_time_get(suite *s)
+{
+ return (double)(s->end.QuadPart - s->start.QuadPart) / (double)s->freq.QuadPart;
+}
+
+static void
+suite_test_add(suite *s, const char *name, function fct)
+{
+ test *t;
+ list *l;
+
+ t = (test *)malloc(sizeof(test));
+ if (!t) return;
+
+ l = (list *)malloc(sizeof(list));
+ if (!l)
+ {
+ free(t);
+ return;
+ }
+
+ t->name = name;
+ t->fct = fct;
+
+ l->data = t;
+ l->succeed = 0;
+ l->next = NULL;
+
+ if (!s->first) s->first = l;
+
+ if (!s->l)
+ s->l = l;
+ else
+ {
+ s->l->next = l;
+ s->l =l;
+ }
+}
+
+static void
+suite_run(suite *s)
+{
+ list *l;
+
+ l = s->first;
+ while (l)
+ {
+ test *t;
+
+ t = (test *)l->data;
+ l->succeed = t->fct(s);
+ printf("%s test: %s\n", t->name, l->succeed ? "success" : "failure");
+ s->tests_count++;
+ if (l->succeed)
+ s->tests_success++;
+ l = l->next;
+ }
+}
+
+static void
+suite_show(suite *s)
+{
+ printf ("\n%d/%d tests passed (%d%%)\n",
+ s->tests_success,
+ s->tests_count,
+ (100 * s->tests_success) / s->tests_count);
+}
+
+int
+main(void)
+{
+ test tests[] = {
+ { "dlfcn ", test_dlfcn },
+ { "environment ", test_environment },
+ { "gettimeofday", test_gettimeofday },
+ { "link ", test_link },
+ { "mkstemp ", test_mkstemp },
+ { "pipe ", test_pipe },
+ { "print ", test_print },
+ { "realpath ", test_realpath },
+ { "util ", test_util },
+/* { "memcpy ", test_memcpy }, */
+ { NULL, NULL },
+ };
+ suite *s;
+ int i;
+
+ if (!evil_init())
+ return EXIT_FAILURE;
+
+ s = suite_new();
+ if (!s)
+ {
+ evil_shutdown();
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; tests[i].name; ++i)
+ {
+ suite_test_add(s, tests[i].name, tests[i].fct);
+ }
+
+ suite_run(s);
+
+ suite_show(s);
+
+ suite_del(s);
+ evil_shutdown();
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/bin/evil/evil_suite.h b/src/bin/evil/evil_suite.h
new file mode 100644
index 000000000..d3284b4fb
--- /dev/null
+++ b/src/bin/evil/evil_suite.h
@@ -0,0 +1,14 @@
+#ifndef __EVIL_SUITE_H__
+#define __EVIL_SUITE_H__
+
+
+typedef struct test test;
+typedef struct list list;
+typedef struct suite suite;
+
+void suite_time_start(suite *s);
+void suite_time_stop(suite *s);
+double suite_time_get(suite *s);
+
+
+#endif /* __EVIL_SUITE_H__ */
diff --git a/src/bin/evil/evil_test_dlfcn.c b/src/bin/evil/evil_test_dlfcn.c
new file mode 100644
index 000000000..fb32dd154
--- /dev/null
+++ b/src/bin/evil/evil_test_dlfcn.c
@@ -0,0 +1,80 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+#include <dlfcn.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_dlfcn.h"
+
+
+typedef int (*_evil_init)(void);
+typedef int (*_evil_shutdwon)(void);
+
+
+static int
+test_dlfcn_test_dlopen(void)
+{
+ void *handle;
+
+ handle = dlopen("libevil-1.dll", 0);
+ if (!handle)
+ return 0;
+
+ if (dlclose(handle))
+ return 0;
+
+ return 1;
+}
+
+static int
+test_dlfcn_test_dlsym(void)
+{
+ void *handle;
+ _evil_init sym_init;
+ _evil_shutdwon sym_shutdown;
+
+ handle = dlopen("libevil-1.dll", 0);
+ if (!handle)
+ return 0;
+
+ sym_init = dlsym(handle, "evil_init");
+ if (!sym_init)
+ {
+ dlclose(handle);
+ return 0;
+ }
+
+ sym_shutdown = dlsym(handle, "evil_shutdown");
+ if (!sym_shutdown)
+ {
+ dlclose(handle);
+ return 0;
+ }
+
+ if (dlclose(handle))
+ return 0;
+
+ return 1;
+}
+
+static int
+test_dlfcn_tests_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_dlfcn_test_dlopen();
+ res &= test_dlfcn_test_dlsym();
+
+ return res;
+}
+
+int
+test_dlfcn(suite *s)
+{
+
+ return test_dlfcn_tests_run(s);
+}
diff --git a/src/bin/evil/evil_test_dlfcn.h b/src/bin/evil/evil_test_dlfcn.h
new file mode 100644
index 000000000..0c9bce689
--- /dev/null
+++ b/src/bin/evil/evil_test_dlfcn.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_DLFCN_H__
+#define __EVIL_TEST_DLFCN_H__
+
+
+int test_dlfcn(suite *s);
+
+
+#endif /* __EVIL_TEST_DLFCN_H__ */
diff --git a/src/bin/evil/evil_test_environment.c b/src/bin/evil/evil_test_environment.c
new file mode 100644
index 000000000..3048a4012
--- /dev/null
+++ b/src/bin/evil/evil_test_environment.c
@@ -0,0 +1,178 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_environment.h"
+
+
+static int
+test_env_test_setenv_NULL(void)
+{
+ char *val;
+ int res;
+
+ res = setenv("EVIL_TEST_ENV", NULL, 1);
+ if (res < 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV");
+
+ return val ? 0 : 1;
+}
+
+static int
+test_env_test_setenv_NULL_after_set(void)
+{
+ char *val;
+ int res;
+
+ res = setenv("EVIL_TEST_ENV", "val", 1);
+ if (res < 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV");
+ if (!val)
+ return 0;
+
+ if (strcmp(val, "val"))
+ return 0;
+
+ res = setenv("EVIL_TEST_ENV", NULL, 1);
+ if (res < 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV");
+
+ return val ? 0 : 1;
+}
+
+static int
+test_env_test_getenv_one(void)
+{
+ char *val;
+ int res;
+
+ res = setenv("EVIL_TEST_ENV", "val", 1);
+ if (res < 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV");
+ if (!val)
+ return 0;
+
+ if (strcmp(val, "val"))
+ return 0;
+
+ return 1;
+}
+
+static int
+test_env_test_getenv_two(void)
+{
+ char *val;
+ int res;
+
+ res = setenv("EVIL_TEST_ENV1", "val1", 1);
+ if (res < 0)
+ return 0;
+
+ res = setenv("EVIL_TEST_ENV2", "val2", 1);
+ if (res < 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV1");
+ if (!val)
+ return 0;
+ if (strcmp(val, "val1"))
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV2");
+ if (!val)
+ return 0;
+
+ if (strcmp(val, "val2"))
+ return 0;
+
+ return 1;
+}
+
+static int
+test_env_test_getenv_two_swapped(void)
+{
+ char *val;
+ int res;
+
+ res = setenv("EVIL_TEST_ENV1", "val1", 1);
+ if (res < 0)
+ return 0;
+
+ res = setenv("EVIL_TEST_ENV2", "val2", 1);
+ if (res < 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV2");
+ if (!val)
+ return 0;
+ if (strcmp(val, "val2"))
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV1");
+ if (!val)
+ return 0;
+
+ if (strcmp(val, "val1"))
+ return 0;
+
+ return 1;
+}
+
+static int
+test_env_test_unsetenv(void)
+{
+ char *val;
+ int res;
+
+ res = setenv("EVIL_TEST_ENV", "val", 1);
+ if (res < 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV");
+ if (!val)
+ return 0;
+
+ if (unsetenv("EVIL_TEST_ENV") != 0)
+ return 0;
+
+ val = getenv("EVIL_TEST_ENV");
+ if (val)
+ return 0;
+
+ return 1;
+}
+
+static int
+test_env_tests_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_env_test_setenv_NULL();
+ res &= test_env_test_setenv_NULL_after_set();
+ res &= test_env_test_getenv_one();
+ res &= test_env_test_getenv_two();
+ res &= test_env_test_getenv_two_swapped();
+ res &= test_env_test_unsetenv();
+
+ return res;
+}
+
+int
+test_environment(suite *s)
+{
+
+ return test_env_tests_run(s);
+}
diff --git a/src/bin/evil/evil_test_environment.h b/src/bin/evil/evil_test_environment.h
new file mode 100644
index 000000000..763ee401b
--- /dev/null
+++ b/src/bin/evil/evil_test_environment.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_ENVIRONMENT_H__
+#define __EVIL_TEST_ENVIRONMENT_H__
+
+
+int test_environment(suite *s);
+
+
+#endif /* __EVIL_TEST_ENVIRONMENT_H__ */
diff --git a/src/bin/evil/evil_test_gettimeofday.c b/src/bin/evil/evil_test_gettimeofday.c
new file mode 100644
index 000000000..49742eb5d
--- /dev/null
+++ b/src/bin/evil/evil_test_gettimeofday.c
@@ -0,0 +1,51 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+#include <math.h>
+#include <sys/time.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_gettimeofday.h"
+
+static int
+test_time_test_gettimeofday(void)
+{
+ struct timeval tp1;
+ struct timeval tp2;
+ double delta;
+
+ gettimeofday (&tp1, NULL);
+
+ Sleep(1000);
+
+ gettimeofday (&tp2, NULL);
+
+ delta = (double)(tp2.tv_sec - tp1.tv_sec) + (double)(tp2.tv_usec - tp1.tv_usec) / 1000000.0;
+ if (fabs(delta - 1) > 0.005)
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+test_time_tests_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_time_test_gettimeofday();
+
+ return res;
+}
+
+int
+test_gettimeofday(suite *s)
+{
+
+ return test_time_tests_run(s);
+}
diff --git a/src/bin/evil/evil_test_gettimeofday.h b/src/bin/evil/evil_test_gettimeofday.h
new file mode 100644
index 000000000..ad3155b14
--- /dev/null
+++ b/src/bin/evil/evil_test_gettimeofday.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_GETTIMEOFDAY_H__
+#define __EVIL_TEST_GETTIMEOFDAY_H__
+
+
+int test_gettimeofday(suite *s);
+
+
+#endif /* __EVIL_TEST_GETTIMEOFDAY_H__ */
diff --git a/src/bin/evil/evil_test_link.c b/src/bin/evil/evil_test_link.c
new file mode 100644
index 000000000..cf4cd931a
--- /dev/null
+++ b/src/bin/evil/evil_test_link.c
@@ -0,0 +1,158 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_link.h"
+
+static int
+test_link_test_file_create(const char *name, const char *data)
+{
+ FILE *f;
+ size_t length;
+ size_t res;
+
+ f = fopen(name, "wb");
+ if (!f)
+ return 0;
+
+ length = strlen(data) + 1;
+ res = fwrite(data, 1, length, f);
+ if (res < length)
+ {
+ fclose(f);
+ return 0;
+ }
+
+ fclose(f);
+
+ return 1;
+}
+
+static int
+test_link_test_symlink(void)
+{
+#ifdef _WIN32_WCE
+ const char *old_name = "\\efl\\evil_test_link.dat";
+ const char *new_name = "\\efl\\evil_test_link.lnk";
+#else
+ const char *old_name = "evil_test_link.dat";
+ const char *new_name = "evil_test_link.lnk";
+#endif
+
+ if (!test_link_test_file_create(old_name,
+ "evil_test_link symlink data\n"))
+ return 0;
+
+ if (symlink(old_name, new_name) < 0)
+ {
+ unlink(old_name);
+ return 0;
+ }
+
+ if (unlink(new_name) < 0)
+ {
+ unlink(old_name);
+ return 0;
+ }
+
+ if (unlink(old_name) < 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+test_link_test_readlink(void)
+{
+ char buf[1024];
+#ifdef _WIN32_WCE
+ const char *old_name = "\\efl\\evil_test_link.dat";
+ const char *new_name = "\\efl\\evil_test_link.lnk";
+#else
+ const char *old_name = "evil_test_link.dat";
+ const char *new_name = "evil_test_link.lnk";
+#endif
+ const char *data = "evil_test_link symlink data\n";
+ FILE *f;
+ ssize_t s1;
+ size_t s2;
+ int l;
+
+ if (!test_link_test_file_create(old_name, data))
+ return 0;
+
+ if (symlink(old_name, new_name) < 0)
+ return 0;
+
+ if ((s1 = readlink(new_name, buf, 1023)) < 0)
+ {
+ unlink(old_name);
+ unlink(new_name);
+ return 0;
+ }
+
+ buf[s1] = '\0';
+
+ f = fopen(buf, "rb");
+ if (!f)
+ {
+ unlink(old_name);
+ unlink(new_name);
+ return 0;
+ }
+
+ l = strlen(data);
+ s2 = fread(buf, 1, l + 1, f);
+
+ if ((int)s2 != (l + 1))
+ {
+ fclose(f);
+ unlink(old_name);
+ unlink(new_name);
+ return 0;
+ }
+
+ if (strcmp(buf, data))
+ {
+ fclose(f);
+ unlink(old_name);
+ unlink(new_name);
+ return 0;
+ }
+
+ fclose(f);
+
+ if (unlink(new_name) < 0)
+ {
+ unlink(old_name);
+ return 0;
+ }
+
+ if (unlink(old_name) < 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+test_link_tests_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_link_test_symlink();
+ res &= test_link_test_readlink();
+
+ return res;
+}
+
+int
+test_link(suite *s)
+{
+
+ return test_link_tests_run(s);
+}
diff --git a/src/bin/evil/evil_test_link.h b/src/bin/evil/evil_test_link.h
new file mode 100644
index 000000000..6f8bfa232
--- /dev/null
+++ b/src/bin/evil/evil_test_link.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_LINK_H__
+#define __EVIL_TEST_LINK_H__
+
+
+int test_link(suite *s);
+
+
+#endif /* __EVIL_TEST_LINK_H__ */
diff --git a/src/bin/evil/evil_test_memcpy.c b/src/bin/evil/evil_test_memcpy.c
new file mode 100644
index 000000000..0adfe373f
--- /dev/null
+++ b/src/bin/evil/evil_test_memcpy.c
@@ -0,0 +1,145 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include "evil_suite.h"
+#include "evil_test_memcpy.h"
+
+
+typedef void *(*memcpy_decl)(void *dest, const void *src, size_t n);
+
+void *memcpy_glibc(void *dest, const void *src, size_t n);
+
+
+static unsigned char *buf1 = NULL;
+static unsigned char *buf2 = NULL;
+static size_t page_size = 0;
+
+
+#if defined (__MINGW32CE__) || defined (_MSC_VER)
+static int
+getpagesize()
+{
+ return 1024;
+}
+#endif /* __MINGW32CE__ || _MSC_VER */
+
+
+static void
+test_memcpy_test_run(suite *s, memcpy_decl fct, char *dst, const char *src, size_t len)
+{
+ double best;
+ int i;
+
+ best = 1000000000.0;
+
+ for (i = 0; i < 128; ++i)
+ {
+ double time;
+
+ suite_time_start(s);
+ fct(dst, src, len);
+ suite_time_stop(s);
+ time = suite_time_get(s);
+ if (time < best) best = time;
+ }
+
+ printf (" %e", best);
+}
+
+static void
+test_memcpy_tests_run(suite *s, size_t align1, size_t align2, size_t len)
+{
+ size_t i, j;
+ char *s1, *s2;
+
+ printf ("running test..\n");
+
+/* align1 &= 63; */
+/* if (align1 + len >= page_size) */
+/* return; */
+
+/* align2 &= 63; */
+/* if (align2 + len >= page_size) */
+/* return; */
+
+ s1 = (char *) (buf1 + align1);
+ s2 = (char *) (buf2 + align2);
+
+ for (i = 0, j = 1; i < len; i++, j += 23)
+ s1[i] = j;
+
+ printf ("length: %6d, align %2d/%2d:", (int)len, align1, align2);
+
+ test_memcpy_test_run(s, memcpy, s2, s1, len);
+#ifdef _WIN32_WCE
+ test_memcpy_test_run(s, memcpy_glibc, s2, s1, len);
+#endif /* _WIN32_WCE */
+
+ printf ("\n");
+}
+
+int
+test_memcpy(suite *s)
+{
+ size_t i;
+
+ page_size = 2 * 1024;
+
+ buf1 = (unsigned char *)malloc(16 * getpagesize());
+ if (!buf1) return 0;
+
+ buf2 = (unsigned char *)malloc(16 * getpagesize());
+ if (!buf2)
+ {
+ free(buf1);
+ return 0;
+ }
+
+ memset (buf1, 0xa5, page_size);
+ memset (buf2, 0x5a, page_size);
+
+ for (i = 0; i < 5; ++i)
+ {
+ test_memcpy_tests_run(s, 0, 0, 1 << i);
+ test_memcpy_tests_run(s, i, 0, 1 << i);
+ test_memcpy_tests_run(s, 0, i, 1 << i);
+ test_memcpy_tests_run(s, i, i, 1 << i);
+ }
+
+ for (i = 0; i < 32; ++i)
+ {
+ test_memcpy_tests_run(s, 0, 0, i);
+ test_memcpy_tests_run(s, i, 0, i);
+ test_memcpy_tests_run(s, 0, i, i);
+ test_memcpy_tests_run(s, i, i, i);
+ }
+
+ for (i = 3; i < 32; ++i)
+ {
+ if ((i & (i - 1)) == 0)
+ continue;
+ test_memcpy_tests_run(s, 0, 0, 16 * i);
+ test_memcpy_tests_run(s, i, 0, 16 * i);
+ test_memcpy_tests_run(s, 0, i, 16 * i);
+ test_memcpy_tests_run(s, i, i, 16 * i);
+ }
+
+ test_memcpy_tests_run(s, 0, 0, getpagesize ());
+ test_memcpy_tests_run(s, 0, 0, 2 * getpagesize ());
+ test_memcpy_tests_run(s, 0, 0, 4 * getpagesize ());
+ test_memcpy_tests_run(s, 0, 0, 8 * getpagesize ());
+ test_memcpy_tests_run(s, 0, 0, 16 * getpagesize ());
+
+ free(buf2);
+ free(buf1);
+
+ return 1;
+}
diff --git a/src/bin/evil/evil_test_memcpy.h b/src/bin/evil/evil_test_memcpy.h
new file mode 100644
index 000000000..808dd09f3
--- /dev/null
+++ b/src/bin/evil/evil_test_memcpy.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_MEMCPY__
+#define __EVIL_TEST_MEMCPY__
+
+
+int test_memcpy(suite *s);
+
+
+#endif /* __EVIL_TEST_MEMCPY__ */
diff --git a/src/bin/evil/evil_test_mkstemp.c b/src/bin/evil/evil_test_mkstemp.c
new file mode 100644
index 000000000..dc8c4e64f
--- /dev/null
+++ b/src/bin/evil/evil_test_mkstemp.c
@@ -0,0 +1,53 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_mkstemp.h"
+
+
+static int
+test_mkstemp_test(void)
+{
+ char _template[PATH_MAX];
+#ifdef _WIN32_WCE
+ char cwd[PATH_MAX];
+#endif
+ int fd;
+
+#ifdef _WIN32_WCE
+ if (!getcwd(cwd, PATH_MAX))
+ return 0;
+ _snprintf(_template, PATH_MAX, "%s\\%s", cwd, "file_XXXXXX");
+#else
+ _snprintf(_template, PATH_MAX, "%s", "file_XXXXXX");
+#endif
+
+ fd = mkstemp(_template);
+
+ if (fd < 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+test_mkstemp_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_mkstemp_test();
+
+ return res;
+}
+
+int
+test_mkstemp(suite *s)
+{
+
+ return test_mkstemp_run(s);
+}
diff --git a/src/bin/evil/evil_test_mkstemp.h b/src/bin/evil/evil_test_mkstemp.h
new file mode 100644
index 000000000..f5bb0c427
--- /dev/null
+++ b/src/bin/evil/evil_test_mkstemp.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_MKSTEMP_H__
+#define __EVIL_TEST_MKSTEMP_H__
+
+
+int test_mkstemp(suite *s);
+
+
+#endif /* __EVIL_TEST_MKSTEMP_H__ */
diff --git a/src/bin/evil/evil_test_pipe.c b/src/bin/evil/evil_test_pipe.c
new file mode 100644
index 000000000..2fc530d54
--- /dev/null
+++ b/src/bin/evil/evil_test_pipe.c
@@ -0,0 +1,126 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+# define WIN32_LEAN_AND_MEAN
+# include <winsock2.h>
+# undef WIN32_LEAN_AND_MEAN
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_pipe.h"
+
+
+#define FDREAD 0
+#define FDWRITE 1
+
+typedef struct
+{
+ int val;
+ int fd_write;
+} data;
+
+
+static DWORD WINAPI
+thread (void *param)
+{
+ data *d;
+ void *buf[1];
+
+ Sleep (2 * 1000);
+ d = (data *)param;
+ buf[0] = d;
+ send(d->fd_write, (char *)buf, sizeof(buf), 0);
+
+ return 0;
+}
+
+static int
+test_pipe_test(void)
+{
+ int sockets[2];
+ struct timeval t;
+ fd_set rfds;
+ int ret;
+ data *d;
+ DWORD thread_id;
+ HANDLE h;
+
+ FD_ZERO(&rfds);
+
+ t.tv_sec = 5;
+ t.tv_usec = 0;
+
+ if (pipe(sockets) < 0)
+ return 0;
+
+ FD_SET(sockets[FDREAD], &rfds);
+ fcntl(sockets[FDREAD], F_SETFL, O_NONBLOCK);
+
+ d = (data *)malloc(sizeof (data));
+ if (!d)
+ return 0;
+
+ d->val = 14;
+ d->fd_write = sockets[FDWRITE];
+
+ h = CreateThread(NULL, 0, thread, d, 0, &thread_id);
+ if (!h)
+
+ ret = select(sockets[FDREAD] + 1, &rfds, NULL, NULL, &t);
+
+ if (ret < 0)
+ goto free_d;
+ else if (ret == 0)
+ goto close_h;
+ else /* ret > 0 */
+ {
+ void *buf[1];
+ data *d2 = NULL;
+ int len;
+
+ while ((len = recv(sockets[FDREAD], (char *)buf, sizeof(buf), 0)) > 0)
+ {
+ if (len == sizeof(buf))
+ {
+ d2 = (data *)buf[0];
+ break;
+ }
+ }
+ if (d2 && (d2->val == d->val))
+ ret = 1;
+ else
+ ret = 0;
+ }
+
+ CloseHandle(h);
+ free(d);
+
+ return ret;
+
+ close_h:
+ CloseHandle(h);
+ free_d:
+ free(d);
+ return 0;
+}
+
+static int
+test_pipe_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_pipe_test();
+
+ return res;
+}
+
+int
+test_pipe(suite *s)
+{
+ return test_pipe_run(s);
+}
diff --git a/src/bin/evil/evil_test_pipe.h b/src/bin/evil/evil_test_pipe.h
new file mode 100644
index 000000000..ff8041f71
--- /dev/null
+++ b/src/bin/evil/evil_test_pipe.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_PIPE_H__
+#define __EVIL_TEST_PIPE_H__
+
+
+int test_pipe(suite *s);
+
+
+#endif /* __EVIL_TEST_PIPE_H__ */
diff --git a/src/bin/evil/evil_test_print.c b/src/bin/evil/evil_test_print.c
new file mode 100644
index 000000000..b930a538f
--- /dev/null
+++ b/src/bin/evil/evil_test_print.c
@@ -0,0 +1,46 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_print.h"
+
+static int
+test_print_test(void)
+{
+ char buf[16];
+ int i1 = 1;
+ size_t i2 = 123456;
+ int res;
+
+ res = printf("%02hhd\n", i1);
+ if (res != 3)
+ return 0;
+
+ res = snprintf(buf, sizeof(buf), "%zu", i2);
+ if (res != 6)
+ return 0;
+
+ return 1;
+}
+
+static int
+test_print_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_print_test();
+
+ return res;
+}
+
+int
+test_print(suite *s)
+{
+ return test_print_run(s);
+}
diff --git a/src/bin/evil/evil_test_print.h b/src/bin/evil/evil_test_print.h
new file mode 100644
index 000000000..2bbf43904
--- /dev/null
+++ b/src/bin/evil/evil_test_print.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_PRINT_H__
+#define __EVIL_TEST_PRINT_H__
+
+
+int test_print(suite *s);
+
+
+#endif /* __EVIL_TEST_PRINT_H__ */
diff --git a/src/bin/evil/evil_test_realpath.c b/src/bin/evil/evil_test_realpath.c
new file mode 100644
index 000000000..f9a48cb97
--- /dev/null
+++ b/src/bin/evil/evil_test_realpath.c
@@ -0,0 +1,44 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_realpath.h"
+
+
+static int
+test_realpath_test(void)
+{
+ char buf[PATH_MAX];
+ char *filename;
+ char *result;
+
+ filename = "evil_suite.exe";
+
+ if (!(result = realpath(filename, buf)))
+ return 0;
+
+ printf ("res : %s\n", buf);
+
+ return 1;
+}
+
+static int
+test_realpath_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_realpath_test();
+
+ return res;
+}
+
+int
+test_realpath(suite *s)
+{
+ return test_realpath_run(s);
+}
diff --git a/src/bin/evil/evil_test_realpath.h b/src/bin/evil/evil_test_realpath.h
new file mode 100644
index 000000000..0205aad14
--- /dev/null
+++ b/src/bin/evil/evil_test_realpath.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_REALPATH_H__
+#define __EVIL_TEST_REALPATH_H__
+
+
+int test_realpath(suite *s);
+
+
+#endif /* __EVIL_TEST_REALPATH_H__ */
diff --git a/src/bin/evil/evil_test_util.c b/src/bin/evil/evil_test_util.c
new file mode 100644
index 000000000..6226ceb04
--- /dev/null
+++ b/src/bin/evil/evil_test_util.c
@@ -0,0 +1,110 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+
+#include <Evil.h>
+
+#include "evil_suite.h"
+#include "evil_test_util.h"
+
+
+static int test_path_absolute_test_1(void)
+{
+ char *path;
+ int result;
+
+ path = NULL;
+ result = evil_path_is_absolute(path);
+ if (result != 0)
+ return 0;
+
+ return 1;
+}
+
+static int test_path_absolute_test_2(void)
+{
+ char *path;
+ int result;
+
+ path = "1";
+ result = evil_path_is_absolute(path);
+ if (result != 0)
+ return 0;
+
+ return 1;
+}
+
+static int test_path_absolute_test_3(void)
+{
+ char *path;
+ int result;
+
+ path = "1:\\";
+ result = evil_path_is_absolute(path);
+ if (result != 0)
+ return 0;
+
+ return 1;
+}
+
+static int test_path_absolute_test_4(void)
+{
+ char *path;
+ int result;
+
+ path = "1/\\";
+ result = evil_path_is_absolute(path);
+ if (result != 0)
+ return 0;
+
+ return 1;
+}
+
+static int test_path_absolute_test_5(void)
+{
+ char *path;
+ int result;
+
+ path = "F:/foo";
+ result = evil_path_is_absolute(path);
+ if (result == 0)
+ return 0;
+
+ return 1;
+}
+
+static int test_path_absolute_test_6(void)
+{
+ char *path;
+ int result;
+
+ path = "C:\\foo";
+ result = evil_path_is_absolute(path);
+ if (result == 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+test_path_absolute_run(suite *s __UNUSED__)
+{
+ int res;
+
+ res = test_path_absolute_test_1();
+ res &= test_path_absolute_test_2();
+ res &= test_path_absolute_test_3();
+ res &= test_path_absolute_test_4();
+ res &= test_path_absolute_test_5();
+ res &= test_path_absolute_test_6();
+
+ return res;
+}
+
+int
+test_util(suite *s)
+{
+ return test_path_absolute_run(s);
+}
diff --git a/src/bin/evil/evil_test_util.h b/src/bin/evil/evil_test_util.h
new file mode 100644
index 000000000..bee5c7a16
--- /dev/null
+++ b/src/bin/evil/evil_test_util.h
@@ -0,0 +1,8 @@
+#ifndef __EVIL_TEST_UTIL_H__
+#define __EVIL_TEST_UTIL_H__
+
+
+int test_util(suite *s);
+
+
+#endif /* __EVIL_TEST_UTIL_H__ */
diff --git a/src/bin/evil/memcpy_glibc_arm.S b/src/bin/evil/memcpy_glibc_arm.S
new file mode 100644
index 000000000..7c4289864
--- /dev/null
+++ b/src/bin/evil/memcpy_glibc_arm.S
@@ -0,0 +1,231 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ Contributed by MontaVista Software, Inc. (written by Nicolas Pitre)
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Copyright (C) 2008 Vincent Torri
+ modification of the name and of the entry / end declaration
+ */
+
+/*
+ * Data preload for architectures that support it (ARM V5TE and above)
+ */
+#if (!defined (__ARM_ARCH_2__) && !defined (__ARM_ARCH_3__) \
+ && !defined (__ARM_ARCH_3M__) && !defined (__ARM_ARCH_4__) \
+ && !defined (__ARM_ARCH_4T__) && !defined (__ARM_ARCH_5__) \
+ && !defined (__ARM_ARCH_5T__))
+#define PLD(code...) code
+#else
+#define PLD(code...)
+#endif
+
+/*
+ * This can be used to enable code to cacheline align the source pointer.
+ * Experiments on tested architectures (StrongARM and XScale) didn't show
+ * this a worthwhile thing to do. That might be different in the future.
+ */
+//#define CALGN(code...) code
+#define CALGN(code...)
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull lsr
+#define push lsl
+#else
+#define pull lsl
+#define push lsr
+#endif
+
+ .text
+
+/* Prototype: void *memcpy_glibc(void *dest, const void *src, size_t n); */
+
+ .align
+ .global memcpy_glibc
+ .func memcpy_glibc
+memcpy_glibc:
+
+ stmfd sp!, {r0, r4, lr}
+
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #0] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb r3, ip, #32 )
+ CALGN( sbcnes r4, r3, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, r3 ) @ C gets set
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #0] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 4f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+3: PLD( pld [r1, #124] )
+4: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ subs r2, r2, #32
+ stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ bge 3b
+ PLD( cmn r2, #96 )
+ PLD( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6: nop
+ ldr r3, [r1], #4
+ ldr r4, [r1], #4
+ ldr r5, [r1], #4
+ ldr r6, [r1], #4
+ ldr r7, [r1], #4
+ ldr r8, [r1], #4
+ ldr lr, [r1], #4
+
+ add pc, pc, ip
+ nop
+ nop
+ str r3, [r0], #4
+ str r4, [r0], #4
+ str r5, [r0], #4
+ str r6, [r0], #4
+ str r7, [r0], #4
+ str r8, [r0], #4
+ str lr, [r0], #4
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldrneb r3, [r1], #1
+ ldrcsb r4, [r1], #1
+ ldrcsb ip, [r1]
+ strneb r3, [r0], #1
+ strcsb r4, [r0], #1
+ strcsb ip, [r0]
+
+ ldmfd sp!, {r0, r4, pc}
+
+9: rsb ip, ip, #4
+ cmp ip, #2
+ ldrgtb r3, [r1], #1
+ ldrgeb r4, [r1], #1
+ ldrb lr, [r1], #1
+ strgtb r3, [r0], #1
+ strgeb r4, [r0], #1
+ subs r2, r2, ip
+ strb lr, [r0], #1
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr lr, [r1], #4
+ beq 17f
+ bgt 18f
+
+
+ .macro forward_copy_shift pull push
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r1, #31 )
+ CALGN( rsb ip, ip, #32 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #0] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 13f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+12: PLD( pld [r1, #124] )
+13: ldmia r1!, {r4, r5, r6, r7}
+ mov r3, lr, pull #\pull
+ subs r2, r2, #32
+ ldmia r1!, {r8, r9, ip, lr}
+ orr r3, r3, r4, push #\push
+ mov r4, r4, pull #\pull
+ orr r4, r4, r5, push #\push
+ mov r5, r5, pull #\pull
+ orr r5, r5, r6, push #\push
+ mov r6, r6, pull #\pull
+ orr r6, r6, r7, push #\push
+ mov r7, r7, pull #\pull
+ orr r7, r7, r8, push #\push
+ mov r8, r8, pull #\pull
+ orr r8, r8, r9, push #\push
+ mov r9, r9, pull #\pull
+ orr r9, r9, ip, push #\push
+ mov ip, ip, pull #\pull
+ orr ip, ip, lr, push #\push
+ stmia r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov r3, lr, pull #\pull
+ ldr lr, [r1], #4
+ subs ip, ip, #4
+ orr r3, r3, lr, push #\push
+ str r3, [r0], #4
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: sub r1, r1, #(\push / 8)
+ b 8b
+
+ .endm
+
+
+ forward_copy_shift pull=8 push=24
+
+17: forward_copy_shift pull=16 push=16
+
+18: forward_copy_shift pull=24 push=8
+
+.endfunc
diff --git a/src/bin/evil/memcpy_glibc_i686.S b/src/bin/evil/memcpy_glibc_i686.S
new file mode 100755
index 000000000..72da118cf
--- /dev/null
+++ b/src/bin/evil/memcpy_glibc_i686.S
@@ -0,0 +1,81 @@
+/* Copy memory block and return pointer to beginning of destination block
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \
+ CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \
+ addl LENGTH, VAL_REG; \
+ cmpl 8+BP_MEM, VAL_REG; \
+ jbe 0f; /* continue if value <= high */ \
+ BOUNDS_VIOLATED; \
+ 0: subl LENGTH, VAL_REG /* restore value */
+
+# define RETURN_BOUNDED_POINTER(BP_MEM) \
+ movl RTN(%esp), %edx; \
+ movl %eax, 0(%edx); \
+ movl 4+BP_MEM, %eax; \
+ movl %eax, 4(%edx); \
+ movl 8+BP_MEM, %eax; \
+ movl %eax, 8(%edx)
+
+#define PTR_SIZE 12
+#define RTN_SIZE 4
+#define LINKAGE 8
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+
+ .align
+ .global memcpy_glibc
+ .func memcpy_glibc
+memcpy_glibc:
+
+ pushl %ebp
+ movl %esp, %ebp
+
+ movl LEN(%esp), %ecx
+ movl %edi, %eax
+ movl DEST(%esp), %edi
+ movl %esi, %edx
+ movl SRC(%esp), %esi
+
+ cld
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ movl %eax, %edi
+ movl %edx, %esi
+ movl DEST(%esp), %eax
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ movl %ebp, %esp
+ popl %ebp
+
+.endfunc
diff --git a/src/bin/evil/test_evil.c b/src/bin/evil/test_evil.c
new file mode 100644
index 000000000..5b91172cb
--- /dev/null
+++ b/src/bin/evil/test_evil.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#include <windows.h>
+
+
+
+int
+main()
+{
+ struct timeval tv;
+ double t1 = 0.0;
+ double t2 = 0.0;
+
+ if (gettimeofday(&tv, NULL) == 0)
+ t1 = tv.tv_sec + tv.tv_usec / 1000000.0;
+
+ Sleep(3000);
+
+ if (gettimeofday(&tv, NULL) == 0)
+ t2 = tv.tv_sec + tv.tv_usec / 1000000.0;
+
+ printf ("3 seconds ? %f\n", t2 - t1);
+
+ return EXIT_SUCCESS;
+}