linux/tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
<<
>>
Prefs
   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__)
  28const char *version = "LINUX_2.6.39";
  29const char *name = "__kernel_gettimeofday";
  30#else
  31const char *version = "LINUX_2.6";
  32const char *name = "__vdso_gettimeofday";
  33#endif
  34
  35int main(int argc, char **argv)
  36{
  37        unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
  38        if (!sysinfo_ehdr) {
  39                printf("AT_SYSINFO_EHDR is not present!\n");
  40                return KSFT_SKIP;
  41        }
  42
  43        vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
  44
  45        /* Find gettimeofday. */
  46        typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
  47        gtod_t gtod = (gtod_t)vdso_sym(version, name);
  48
  49        if (!gtod) {
  50                printf("Could not find %s\n", name);
  51                return KSFT_SKIP;
  52        }
  53
  54        struct timeval tv;
  55        long ret = gtod(&tv, 0);
  56
  57        if (ret == 0) {
  58                printf("The time is %lld.%06lld\n",
  59                       (long long)tv.tv_sec, (long long)tv.tv_usec);
  60        } else {
  61                printf("%s failed\n", name);
  62                return KSFT_FAIL;
  63        }
  64
  65        return 0;
  66}
  67