sign-extend regression test for x32
authorSzabolcs Nagy <nsz@port70.net>
Tue, 18 Mar 2014 23:25:49 +0000 (00:25 +0100)
committerSzabolcs Nagy <nsz@port70.net>
Tue, 18 Mar 2014 23:25:49 +0000 (00:25 +0100)
src/regression/syscall-sign-extend.c [new file with mode: 0644]

diff --git a/src/regression/syscall-sign-extend.c b/src/regression/syscall-sign-extend.c
new file mode 100644 (file)
index 0000000..89ef9b6
--- /dev/null
@@ -0,0 +1,39 @@
+// commit 5f95f965e933c5b155db75520ac27c92ddbcf400 2014-03-18
+// syscall should not sign extend pointers on x32
+#define _GNU_SOURCE
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/syscall.h>
+#include "test.h"
+
+#define T(f) ((f) && (t_error(#f " failed: %s\n", strerror(errno)), 0))
+
+static unsigned long long tsdiff(struct timespec ts2, struct timespec ts)
+{
+       if (ts2.tv_nsec < ts.tv_nsec) {
+               ts2.tv_nsec += 1000000000;
+               ts2.tv_sec--;
+       }
+       if (ts2.tv_sec < ts.tv_sec)
+               return -1;
+       return (ts2.tv_sec - ts.tv_sec)*1000000000ULL + (ts2.tv_nsec - ts.tv_nsec);
+}
+
+int main(void)
+{
+       struct timespec ts, ts2;
+       unsigned long long diff;
+
+       // test syscall with pointer
+       T(syscall(SYS_clock_gettime, CLOCK_REALTIME, &ts));
+
+       // check if timespec is filled correctly
+       T(clock_gettime(CLOCK_REALTIME, &ts2));
+       diff = tsdiff(ts2, ts);
+       if (diff > 10 * 1000000000ULL)
+               t_error("large diff between clock_gettime calls: %llu ns\n", diff);
+
+       return t_status;
+}