On 26/02/2025 11:44, Thomas Weißschuh wrote: > vdso_standalone_test_x86 provides its own ASM syscall wrappers and > _start() implementation. The in-tree nolibc library already provides > this functionality for multiple architectures. By making use of nolibc, > the standalone testcase can be built from the exact same codebase as the > non-standalone version. > > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@xxxxxxxxxxxxx> Reviewed-by: Vincenzo Frascino <vincenzo.frascino@xxxxxxx> > --- > tools/testing/selftests/vDSO/Makefile | 8 +- > .../selftests/vDSO/vdso_standalone_test_x86.c | 168 +-------------------- > 2 files changed, 7 insertions(+), 169 deletions(-) > > diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile > index bc8ca186fb877dc11740c37f1e07e45e84c2ae92..12a0614b9fd4983deffe5d6a7cfa06ba8d92a516 100644 > --- a/tools/testing/selftests/vDSO/Makefile > +++ b/tools/testing/selftests/vDSO/Makefile > @@ -22,13 +22,17 @@ include ../lib.mk > > CFLAGS += $(TOOLS_INCLUDES) > > +CFLAGS_NOLIBC := -nostdlib -nostdinc -ffreestanding -fno-asynchronous-unwind-tables \ > + -fno-stack-protector -include $(top_srcdir)/tools/include/nolibc/nolibc.h \ > + -I$(top_srcdir)/tools/include/nolibc/ $(KHDR_INCLUDES) > + > $(OUTPUT)/vdso_test_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c > $(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.c > $(OUTPUT)/vdso_test_abi: parse_vdso.c vdso_test_abi.c > $(OUTPUT)/vdso_test_clock_getres: vdso_test_clock_getres.c > > -$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c > -$(OUTPUT)/vdso_standalone_test_x86: CFLAGS +=-nostdlib -fno-asynchronous-unwind-tables -fno-stack-protector > +$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c | headers > +$(OUTPUT)/vdso_standalone_test_x86: CFLAGS:=$(CFLAGS_NOLIBC) $(CFLAGS) > > $(OUTPUT)/vdso_test_correctness: vdso_test_correctness.c > $(OUTPUT)/vdso_test_correctness: LDFLAGS += -ldl > diff --git a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c > deleted file mode 100644 > index 500608f89c66b5747e3d845ebc54e4c3a35b6ccd..0000000000000000000000000000000000000000 > --- a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c > +++ /dev/null > @@ -1,167 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-only > -/* > - * vdso_test.c: Sample code to test parse_vdso.c on x86 > - * Copyright (c) 2011-2014 Andy Lutomirski > - * > - * You can amuse yourself by compiling with: > - * gcc -std=gnu99 -nostdlib > - * -Os -fno-asynchronous-unwind-tables -flto -lgcc_s > - * vdso_standalone_test_x86.c parse_vdso.c > - * 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> > -#include <sys/time.h> > -#include <unistd.h> > -#include <stdint.h> > -#include <linux/auxvec.h> > - > -#include "parse_vdso.h" > - > -/* We need some libc functions... */ > -int strcmp(const char *a, const char *b) > -{ > - /* This implementation is buggy: it never returns -1. */ > - while (*a || *b) { > - if (*a != *b) > - return 1; > - if (*a == 0 || *b == 0) > - return 1; > - a++; > - b++; > - } > - > - return 0; > -} > - > -/* > - * The clang build needs this, although gcc does not. > - * Stolen from lib/string.c. > - */ > -void *memcpy(void *dest, const void *src, size_t count) > -{ > - char *tmp = dest; > - const char *s = src; > - > - while (count--) > - *tmp++ = *s++; > - return dest; > -} > - > -/* ...and two syscalls. This is x86-specific. */ > -static inline long x86_syscall3(long nr, long a0, long a1, long a2) > -{ > - long ret; > -#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) > -{ > - x86_syscall3(__NR_exit, code, 0, 0); > -} > - > -void to_base10(char *lastdig, time_t n) > -{ > - while (n) { > - *lastdig = (n % 10) + '0'; > - n /= 10; > - lastdig--; > - } > -} > - > -unsigned long getauxval(const unsigned long *auxv, unsigned long type) > -{ > - unsigned long ret; > - > - if (!auxv) > - return 0; > - > - while (1) { > - if (!auxv[0] && !auxv[1]) { > - ret = 0; > - break; > - } > - > - if (auxv[0] == type) { > - ret = auxv[1]; > - break; > - } > - > - auxv += 2; > - } > - > - return ret; > -} > - > -void c_main(void **stack) > -{ > - /* Parse the stack */ > - long argc = (long)*stack; > - stack += argc + 2; > - > - /* Now we're pointing at the environment. Skip it. */ > - while(*stack) > - stack++; > - stack++; > - > - /* Now we're pointing at auxv. Initialize the vDSO parser. */ > - vdso_init_from_sysinfo_ehdr(getauxval((unsigned long *)stack, AT_SYSINFO_EHDR)); > - > - /* Find gettimeofday. */ > - typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz); > - gtod_t gtod = (gtod_t)vdso_sym("LINUX_2.6", "__vdso_gettimeofday"); > - > - if (!gtod) > - linux_exit(1); > - > - struct timeval tv; > - long ret = gtod(&tv, 0); > - > - if (ret == 0) { > - char buf[] = "The time is .000000\n"; > - to_base10(buf + 31, tv.tv_sec); > - to_base10(buf + 38, tv.tv_usec); > - linux_write(1, buf, sizeof(buf) - 1); > - } else { > - linux_exit(ret); > - } > - > - linux_exit(0); > -} > - > -/* > - * This is the real entry point. It passes the initial stack into > - * the C entry point. > - */ > -asm ( > - ".text\n" > - ".global _start\n" > - ".type _start,@function\n" > - "_start:\n\t" > -#ifdef __x86_64__ > - "mov %rsp,%rdi\n\t" > - "and $-16,%rsp\n\t" > - "sub $8,%rsp\n\t" > - "jmp c_main" > -#else > - "push %esp\n\t" > - "call c_main\n\t" > - "int $3" > -#endif > - ); > diff --git a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c > new file mode 120000 > index 0000000000000000000000000000000000000000..4d3d96f1e440c965474681a6f35375a60b3921be > --- /dev/null > +++ b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c > @@ -0,0 +1 @@ > +vdso_test_gettimeofday.c > \ No newline at end of file > -- Regards, Vincenzo