summaryrefslogtreecommitdiffstats
path: root/Documentation/vDSO/vdso_standalone_test_x86.c
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-06-12 17:53:10 -0700
committerH. Peter Anvin <hpa@zytor.com>2014-06-12 19:01:24 -0700
commit4ebbefd6b93c34d6da0d950b1d2e0dcca2f1e6ef (patch)
tree5d94b4e1dd26d5c1a4ce2866486936333ca2e96f /Documentation/vDSO/vdso_standalone_test_x86.c
parent6e8f21584a30ba6ce73cfef34f316d5bf3fadaab (diff)
downloadlinux-4ebbefd6b93c34d6da0d950b1d2e0dcca2f1e6ef.tar.bz2
x86/vdso/doc: Make vDSO examples more portable
This adds a new vdso_test.c that's written entirely in C. It also makes all of the vDSO examples work on 32-bit x86. Cc: Stefani Seibold <stefani@seibold.net> Signed-off-by: Andy Lutomirski <luto@amacapital.net> Link: http://lkml.kernel.org/r/62b701fc44b79f118ac2b2d64d19965fc5c291fb.1402620737.git.luto@amacapital.net Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'Documentation/vDSO/vdso_standalone_test_x86.c')
-rw-r--r--Documentation/vDSO/vdso_standalone_test_x86.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/Documentation/vDSO/vdso_standalone_test_x86.c b/Documentation/vDSO/vdso_standalone_test_x86.c
index 1523f5d681f3..d46240265c50 100644
--- a/Documentation/vDSO/vdso_standalone_test_x86.c
+++ b/Documentation/vDSO/vdso_standalone_test_x86.c
@@ -1,13 +1,14 @@
/*
- * vdso_test.c: Sample code to test parse_vdso.c on x86_64
- * Copyright (c) 2011 Andy Lutomirski
+ * vdso_test.c: Sample code to test parse_vdso.c on x86
+ * Copyright (c) 2011-2014 Andy Lutomirski
* Subject to the GNU General Public License, version 2
*
* You can amuse yourself by compiling with:
* gcc -std=gnu99 -nostdlib
- * -Os -fno-asynchronous-unwind-tables -flto
+ * -Os -fno-asynchronous-unwind-tables -flto -lgcc_s
* vdso_standalone_test_x86.c parse_vdso.c
- * to generate a small binary with no dependencies at all.
+ * to generate a small binary. On x86_64, you can omit -lgcc_s
+ * if you want the binary to be completely standalone.
*/
#include <sys/syscall.h>
@@ -35,21 +36,31 @@ int strcmp(const char *a, const char *b)
return 0;
}
-/* ...and two syscalls. This is x86_64-specific. */
-static inline long linux_write(int fd, const void *data, size_t len)
+/* ...and two syscalls. This is x86-specific. */
+static inline long x86_syscall3(long nr, long a0, long a1, long a2)
{
-
long ret;
- asm volatile ("syscall" : "=a" (ret) : "a" (__NR_write),
- "D" (fd), "S" (data), "d" (len) :
+#ifdef __x86_64__
+ asm volatile ("syscall" : "=a" (ret) : "a" (nr),
+ "D" (a0), "S" (a1), "d" (a2) :
"cc", "memory", "rcx",
"r8", "r9", "r10", "r11" );
+#else
+ asm volatile ("int $0x80" : "=a" (ret) : "a" (nr),
+ "b" (a0), "c" (a1), "d" (a2) :
+ "cc", "memory" );
+#endif
return ret;
}
+static inline long linux_write(int fd, const void *data, size_t len)
+{
+ return x86_syscall3(__NR_write, fd, (long)data, (long)len);
+}
+
static inline void linux_exit(int code)
{
- asm volatile ("syscall" : : "a" (__NR_exit), "D" (code));
+ x86_syscall3(__NR_exit, code, 0, 0);
}
void to_base10(char *lastdig, uint64_t n)
@@ -104,8 +115,14 @@ __attribute__((externally_visible)) void c_main(void **stack)
asm (
".text\n"
".global _start\n"
- ".type _start,@function\n"
- "_start:\n\t"
- "mov %rsp,%rdi\n\t"
- "jmp c_main"
+ ".type _start,@function\n"
+ "_start:\n\t"
+#ifdef __x86_64__
+ "mov %rsp,%rdi\n\t"
+ "jmp c_main"
+#else
+ "push %esp\n\t"
+ "call c_main\n\t"
+ "int $3"
+#endif
);