Why doesn't time () from time.h have syscall for sys_time?

I wrote a very simple program with time() calls to illustrate the use of strace , but I had a problem; calling time() does not seem to create self-tuning!

I ended up moving to the time() function in GDB, and now I'm more confused than ever. From disassembling the time() function:

 0x7ffff7ffad90 <time>: push rbp 0x7ffff7ffad91 <time+1>: test rdi,rdi 0x7ffff7ffad94 <time+4>: mov rax,QWORD PTR [rip+0xffffffffffffd30d] # 0x7ffff7ff80a8 0x7ffff7ffad9b <time+11>: mov rbp,rsp 0x7ffff7ffad9e <time+14>: je 0x7ffff7ffada3 <time+19> 0x7ffff7ffada0 <time+16>: mov QWORD PTR [rdi],rax 0x7ffff7ffada3 <time+19>: pop rbp 0x7ffff7ffada4 <time+20>: ret 

How does this function actually get the current time if it does not call the kernel? His stream:

  • Prologue
  • Get some value from (0x7ffff7ffad94 + 0xffffffffffffd30d) ( 0x7ffff7ff80a8 ) and put it in rax (to return)
  • Check if rdi (first argument) was null
  • If you do not put the value in rax (return value), also
  • Epilogue

This makes sense with the time() functionality; if the argument is null, it just returns a value, but if not, it also puts it in the argument. The question I have is, where does it get the value of time? What is so magical about 0x7ffff7ff80a8 , and how to do it without syscall?

I am using GCC 6.3.0 and Ubuntu GLIBC 2.24-9ubuntu2.2.

+8
assembly gcc linux x86-64 glibc
source share
1 answer

Read the time (7) . Your time (2) call probably uses vdso (7) (maybe via clock_gettime (2) or via __vdso_time ). If vdso (7) is used ,

When a system trace calls strace (1) calls, characters (system calls) that are exported by vDSO will not appear in the trace output.

Details may be kernel and libc specific (and, of course, architecture).

For similar vDSO reasons, strace date does not display syscalls time related.

And vDSO is a really handy feature. Due to this, temporary calls (e.g. clock_gettime (2) ...) go very fast (about 40 nanoseconds on my i5-4690S). AFAIU, no context switch (or user mode ) occurs.

So your 0x7ffff7ff80a8 is probably in vDSO (and the kernel guarantees that it contains the current time). You can check using proc (5) (for example, reading and showing /proc/self/maps from your program) or, possibly, using ldd (1) .

+6
source share

All Articles