1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * vdso_test_gettimeofday.c: Sample code to test parse_vdso.c and |
4 | * vDSO gettimeofday() |
5 | * Copyright (c) 2014 Andy Lutomirski |
6 | * |
7 | * Compile with: |
8 | * gcc -std=gnu99 vdso_test_gettimeofday.c parse_vdso_gettimeofday.c |
9 | * |
10 | * Tested on x86, 32-bit and 64-bit. It may work on other architectures, too. |
11 | */ |
12 | |
13 | #include <stdint.h> |
14 | #include <elf.h> |
15 | #include <stdio.h> |
16 | #include <sys/auxv.h> |
17 | #include <sys/time.h> |
18 | |
19 | #include "../kselftest.h" |
20 | #include "parse_vdso.h" |
21 | |
22 | /* |
23 | * ARM64's vDSO exports its gettimeofday() implementation with a different |
24 | * name and version from other architectures, so we need to handle it as |
25 | * a special case. |
26 | */ |
27 | #if defined(__aarch64__) |
28 | const char *version = "LINUX_2.6.39" ; |
29 | const char *name = "__kernel_gettimeofday" ; |
30 | #elif defined(__riscv) |
31 | const char *version = "LINUX_4.15" ; |
32 | const char *name = "__vdso_gettimeofday" ; |
33 | #else |
34 | const char *version = "LINUX_2.6" ; |
35 | const char *name = "__vdso_gettimeofday" ; |
36 | #endif |
37 | |
38 | int main(int argc, char **argv) |
39 | { |
40 | unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); |
41 | if (!sysinfo_ehdr) { |
42 | printf("AT_SYSINFO_EHDR is not present!\n" ); |
43 | return KSFT_SKIP; |
44 | } |
45 | |
46 | vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR)); |
47 | |
48 | /* Find gettimeofday. */ |
49 | typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz); |
50 | gtod_t gtod = (gtod_t)vdso_sym(version, name); |
51 | |
52 | if (!gtod) { |
53 | printf("Could not find %s\n" , name); |
54 | return KSFT_SKIP; |
55 | } |
56 | |
57 | struct timeval tv; |
58 | long ret = gtod(&tv, 0); |
59 | |
60 | if (ret == 0) { |
61 | printf("The time is %lld.%06lld\n" , |
62 | (long long)tv.tv_sec, (long long)tv.tv_usec); |
63 | } else { |
64 | printf("%s failed\n" , name); |
65 | return KSFT_FAIL; |
66 | } |
67 | |
68 | return 0; |
69 | } |
70 | |