I wrote a very simple program with calls time()
to illustrate the use ofstrace
, but I'm having a problem; the time()
call doesn't seem to actually produce a syscall!
I ended up stepping into the time()
function in GDB and now I'm more confused than ever. From the disassembly of 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 is this function actually getting the current time if it does not call the kernel? Its flow is:
- Prologue
- Get some value from
(0x7ffff7ffad94 + 0xffffffffffffd30d)
(0x7ffff7ff80a8
) and put it in rax (to be returned) - Check if rdi (first argument) was null
- If not put the value in rax (return value) there also
- Epilogue
This makes sense with the functionality of time()
; if the argument is null, it just returns the value, but if not it also puts it in the argument. The question I have is, where is it getting the time value? What's so magical about address 0x7ffff7ff80a8
, and how does it do this without a syscall?
I'm using GCC 6.3.0 and Ubuntu GLIBC 2.24-9ubuntu2.2.