md.jamal
md.jamal

Reputation: 4517

Where is linux-vdso.so.1 present on the file system

I am learning about VDSO, wrote a simple application which calls gettimeofday()

#define _GNU_SOURCE
#include <sys/syscall.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    struct timeval current_time;

    if (gettimeofday(&current_time, NULL) == -1)
        printf("gettimeofday");

    getchar();

    exit(EXIT_SUCCESS);
}

ldd on the binary shows 'linux-vdso'

$ ldd ./prog
    linux-vdso.so.1 (0x00007ffce147a000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6ef9e8e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f6efa481000)

I did a find for the libvdso library and there is no such library present in my entire file system.

sudo find / -name 'linux-vdso.so*'

Where is the library present?

Upvotes: 64

Views: 73248

Answers (2)

Stefan Steiger
Stefan Steiger

Reputation: 82166

find / -name '*vdso*.so*' 

yields

/lib/modules/4.15.0-108-generic/vdso/vdso64.so
/lib/modules/4.15.0-108-generic/vdso/vdso32.so
/lib/modules/4.15.0-108-generic/vdso/vdsox32.so

linux-vdso.so is a virtual symbolic link to the bitness-compatible respective vdso*.so.
vDSO = virtual dynamic shared object

Note on vdsox32:
x32 is a Linux ABI which is kind of a mix between x86 and x64.
It uses 32-bit address size but runs in full 64-bit mode, including all 64-bit instructions and registers available.

   Making system calls can be slow.  In x86 32-bit systems, you can
   trigger a software interrupt (int $0x80) to tell the kernel you
   wish to make a system call.  However, this instruction is
   expensive: it goes through the full interrupt-handling paths in
   the processor's microcode as well as in the kernel.  Newer
   processors have faster (but backward incompatible) instructions
   to initiate system calls.  Rather than require the C library to
   figure out if this functionality is available at run time, the C
   library can use functions provided by the kernel in the vDSO.

   Note that the terminology can be confusing.  On x86 systems, the
   vDSO function used to determine the preferred method of making a
   system call is named "__kernel_vsyscall", but on x86-64, the term
   "vsyscall" also refers to an obsolete way to ask the kernel what
   time it is or what CPU the caller is on.

   One frequently used system call is gettimeofday(2).  This system
   call is called both directly by user-space applications as well
   as indirectly by the C library.  Think timestamps or timing loops
   or polling—all of these frequently need to know what time it is
   right now.  This information is also not secret—any application
   in any privilege mode (root or any unprivileged user) will get
   the same answer.  Thus the kernel arranges for the information
   required to answer this question to be placed in memory the
   process can access.  Now a call to gettimeofday(2) changes from a
   system call to a normal function call and a few memory accesses.

Also

You must not assume the vDSO is mapped at any particular location
in the user's memory map. The base address will usually be
randomized at run time every time a new process image is created
(at execve(2) time). This is done for security reasons, to prevent "return-to-libc" attacks.

And

Since the vDSO is a fully formed ELF image, you can do symbol lookups on it.

And also

If you are trying to call the vDSO in your own application rather than using the C library, you're most likely doing it wrong.

as well as

Why does the vDSO exist at all? There are some system calls the
kernel provides that user-space code ends up using frequently, to
the point that such calls can dominate overall performance. This
is due both to the frequency of the call as well as the context-
switch overhead that results from exiting user space and entering
the kernel.

Upvotes: 6

P.P
P.P

Reputation: 121357

It's a virtual shared object that doesn't have any physical file on the disk; it's a part of the kernel that's exported into every program's address space when it's loaded.

It's main purpose to make more efficient to call certain system calls (which would otherwise incur performance issues like this). The most prominent being gettimeofday(2).

You can read more about it here: http://man7.org/linux/man-pages/man7/vdso.7.html

Upvotes: 90

Related Questions