Skip to content

Commit

Permalink
Add vdso fast syscall compatibility library
Browse files Browse the repository at this point in the history
Some application runtimes like Golang need libvdso
in order to lookup time. More specifically on startup
Golang gets passed in address of libvdso library so that
it can lookup addresses of these 3 function symbols - __vdso_time,
__vdso_gettimeofday and __vdso_clock_gettime. For details please
look at https://github.com/golang/go/blob/master/src/runtime/vdso_linux.go and
https://github.com/golang/go/blob/master/src/runtime/vdso_linux_amd64.go.

This patch adds implementation of 3 required functions (vdso.c)
and modifies Makefile and bootstrap skeleton files to produce
libvdso.so and add it the user image. One of the follow up patches
will actually add the logic to pass base address of libvdso ELF
as part of auxv when initializing Golang shared object.

The alternative to having separate libvdso.so would be linking
the __vdso_* functions directly to the loader.elf and passing its base
address to auxv but unfortunately it would not work for following reasons:

1. For some reason (possibly a bug) the base address of loader.elf
(per object::base()) is 0x0000000000000000 instead of expected 0x0000000000200000x
and Golang guards against address 0.

2. Even if the above was not an issue there is high probability
that Golang would have not been able to find symbols of __vdso_*
functions from loader.elf given that it directly reads content of
of the ELF to parse and find the symbols at binary level (it does
not use standard dlopen() and dlsym()).

The content of this patch was authored by Benoit Canet.

Signed-off-by: Waldemar Kozaczuk <jwkozaczuk@gmail.com>
Message-Id: <1521312416-29803-1-git-send-email-jwkozaczuk@gmail.com>
  • Loading branch information
wkozaczuk authored and nyh committed Mar 18, 2018
1 parent 6f5e403 commit 6454485
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 1 deletion.
7 changes: 6 additions & 1 deletion Makefile
Expand Up @@ -1873,6 +1873,11 @@ $(out)/libenviron.so: $(environ_sources)
$(makedir)
$(call quiet, $(CC) $(CFLAGS) -shared -o $(out)/libenviron.so $(environ_sources), CC libenviron.so)

$(out)/libvdso.so: libc/vdso/vdso.c
$(makedir)
$(call quiet, $(CC) -c -fPIC -o $(out)/libvdso.o libc/vdso/vdso.c, CC libvdso.o)
$(call quiet, $(LD) -shared -fPIC -o $(out)/libvdso.so $(out)/libvdso.o --version-script=libc/vdso/vdso.version, LINK libvdso.so)

bootfs_manifest ?= bootfs.manifest.skel

# If parameter "bootfs_manifest" has been changed since the last make,
Expand All @@ -1885,7 +1890,7 @@ $(bootfs_manifest_dep): phony
fi

$(out)/bootfs.bin: scripts/mkbootfs.py $(bootfs_manifest) $(bootfs_manifest_dep) $(tools:%=$(out)/%) \
$(out)/zpool.so $(out)/zfs.so $(out)/libenviron.so
$(out)/zpool.so $(out)/zfs.so $(out)/libenviron.so $(out)/libvdso.so
$(call quiet, olddir=`pwd`; cd $(out); $$olddir/scripts/mkbootfs.py -o bootfs.bin -d bootfs.bin.d -m $$olddir/$(bootfs_manifest) \
-D jdkbase=$(jdkbase) -D gccbase=$(gccbase) -D \
glibcbase=$(glibcbase) -D miscbase=$(miscbase), MKBOOTFS $@)
Expand Down
1 change: 1 addition & 0 deletions bootfs.manifest.skel
@@ -1,4 +1,5 @@
[manifest]
/libvdso.so: libvdso.so
/libuutil.so: libuutil.so
/zpool.so: zpool.so
/libzfs.so: libzfs.so
Expand Down
18 changes: 18 additions & 0 deletions libc/vdso/vdso.c
@@ -0,0 +1,18 @@
//#include "libc.h"
#include <time.h>
#include <sys/time.h>

time_t __vdso_time(time_t *tloc)
{
return time(tloc);
}

int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
{
return gettimeofday(tv, tz);
}

int __vdso_clock_gettime(clockid_t clk_id, struct timespec *tp)
{
return clock_gettime(clk_id, tp);
}
3 changes: 3 additions & 0 deletions libc/vdso/vdso.version
@@ -0,0 +1,3 @@
LINUX_2.6 {
global: *;
};
1 change: 1 addition & 0 deletions usr.manifest.skel
@@ -1,5 +1,6 @@
[manifest]
/libenviron.so: libenviron.so
/libvdso.so: libvdso.so
/zpool.so: zpool.so
/libzfs.so: libzfs.so
/libuutil.so: libuutil.so
Expand Down
1 change: 1 addition & 0 deletions usr_nozfs.manifest.skel
@@ -1,5 +1,6 @@
[manifest]
/libenviron.so: libenviron.so
/libvdso.so: libvdso.so
/tools/mount-nfs.so: tools/mount/mount-nfs.so
/tools/umount.so: tools/mount/umount.so
/usr/lib/libgcc_s.so.1: %(gccbase)s/lib64/libgcc_s.so.1
Expand Down

0 comments on commit 6454485

Please sign in to comment.