Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sun, 7 Feb 2010, Richard Henderson wrote: > > I imagine that QEMU's VDSO would not have the complicated bits that the > kernel's version does, where it arranges to read the clock without going into > kernel space. I imagine QEMU would simply stuff a normal syscall sequence in > there, which would automatically be emulated in the normal way. For what it's worth, this is how various other systems I'm aware of handle x86_64 VDSOs (both Valgrind and the m5 simulator do it this way). Vince
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On 02/06/2010 03:50 PM, Laurent Desnogues wrote: * target-i386 code should not have to know about linux vsyscall Given that we have to workaround 64-bit virtual address limitations (cf. Richard mail and previous discussions on the list), doing otherwise looks difficult. Actually, it should be easy for QEMU to handle this. The application is given the address of the VDSO in the AT_SYSINFO and AT_SYSINFO_EHDR entries of the auxvec (on the stack above argv and environ). We can place this anywhere we like; the fact that the kernel puts it in high memory is merely a convenience to the kernel. There *is* a legacy vsyscall address in high memory, from before the whole VDSO arrangement was worked out, but we could probably get away with ignoring that. Certainly well behaved applications will be honoring the VDSO when it is given. * it is not possible to step into vsyscall code using a debugger How would you achieve that? Your guest OS doesn't necessarily have the code mapped. I think this has to be considered as other syscalls, though slightly different. If QEMU implements the VDSO, the page *will* be mapped, and the debugger will Just Work. I imagine that QEMU's VDSO would not have the complicated bits that the kernel's version does, where it arranges to read the clock without going into kernel space. I imagine QEMU would simply stuff a normal syscall sequence in there, which would automatically be emulated in the normal way. Have a stare at the linux/arch/x86/vdso directory to see how things work. r~
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sun, Feb 7, 2010 at 1:22 AM, Jamie Lokier wrote: [...] >> >> How would you achieve that? Your guest OS >> doesn't necessarily have the code mapped. I >> think this has to be considered as other syscalls, >> though slightly different. > > There is no guest OS when doing -user emulation. > Only qemu. I meant that the vsyscall page doesn't exist on other guest systems but x86_64 running Linux. So if one wants to have it somehow mapped then it would have to be installed by QEMU, and QEMU can't install such a page due to limitations in the way it handles virtual addresses. >> > My favorite solution would be a vsyscall page mapped >> > to the correct fixed address and filled with QEMU >> > generated specific code, for example code which calls the >> > normal syscalls to do the work. This would only >> > need modifications for linux-user code. >> >> You mean you'd explicitly put somewhere x86_64 >> code that simulates the behaviour of vsyscall? > > That seems like a good idea to me. Why not indeed. But someone will first have to fix virtual memory management. Laurent
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sun, 7 Feb 2010, Jamie Lokier wrote: > Laurent Desnogues wrote: > > On Sat, Feb 6, 2010 at 8:49 AM, Stefan Weil wrote: > > [...] > > > I tested two different hosts with x86_64-linux-user: > > > > > > * 32 bit Intel (i386) - does not work with your patch > > > > For me x86_64 on i386 has always failed without > > even calling vsyscall :-) > > > > > * 64 bit AMD (x86_64) - works with your patch > > It's a bit worrying that it depends on the host architecture at all. > > How well does x86_64-linux-user emulation work on non-x86 hosts? x64user$ uname -a Linux linmac 2.6.32.3 #4 Sun Jan 31 09:52:58 MSK 2010 ppc 7447A, altivec supported PowerMac10,2 GNU/Linux x64user$ x86_64-linux-user/qemu-x86_64 -L ~/x/lut/gnemul/qemu-x86_64/ ~/x/lut/x86_64/uname -a Linux linmac 2.6.32.3 #4 Sun Jan 31 09:52:58 MSK 2010 x86-64 unknown [..snip..] -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
Laurent Desnogues wrote: > On Sat, Feb 6, 2010 at 8:49 AM, Stefan Weil wrote: > [...] > > I tested two different hosts with x86_64-linux-user: > > > > * 32 bit Intel (i386) - does not work with your patch > > For me x86_64 on i386 has always failed without > even calling vsyscall :-) > > > * 64 bit AMD (x86_64) - works with your patch It's a bit worrying that it depends on the host architecture at all. How well does x86_64-linux-user emulation work on non-x86 hosts? Does the vsyscall emulation depend only on the hosts's address sixe, or does it have to be an x86 host to work? > > * it is not possible to step into vsyscall code > > using a debugger > > How would you achieve that? Your guest OS > doesn't necessarily have the code mapped. I > think this has to be considered as other syscalls, > though slightly different. There is no guest OS when doing -user emulation. Only qemu. > > My favorite solution would be a vsyscall page mapped > > to the correct fixed address and filled with QEMU > > generated specific code, for example code which calls the > > normal syscalls to do the work. This would only > > need modifications for linux-user code. > > You mean you'd explicitly put somewhere x86_64 > code that simulates the behaviour of vsyscall? That seems like a good idea to me. -- Jamie
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sat, Feb 6, 2010 at 8:49 AM, Stefan Weil wrote: [...] > I tested two different hosts with x86_64-linux-user: > > * 32 bit Intel (i386) - does not work with your patch For me x86_64 on i386 has always failed without even calling vsyscall :-) > * 64 bit AMD (x86_64) - works with your patch > > Your patch improves the emulation for 64 bit hosts. > Nevertheless, it has some open points: > > * target-i386 code should not have to know about > linux vsyscall Given that we have to workaround 64-bit virtual address limitations (cf. Richard mail and previous discussions on the list), doing otherwise looks difficult. > * there is no vsyscall page in memory, > but very special programs might expect to see one > (it is even worse: the target sees the memory page > of the host) > > * it is not possible to step into vsyscall code > using a debugger How would you achieve that? Your guest OS doesn't necessarily have the code mapped. I think this has to be considered as other syscalls, though slightly different. > My favorite solution would be a vsyscall page mapped > to the correct fixed address and filled with QEMU > generated specific code, for example code which calls the > normal syscalls to do the work. This would only > need modifications for linux-user code. You mean you'd explicitly put somewhere x86_64 code that simulates the behaviour of vsyscall? Laurent
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On 02/05/2010 02:57 PM, Stefan Weil wrote: I tried to modify x86_64-linux-user to set up a vsyscall page in high memory, but this seems to be difficult (at least with 32 bit host). A 64-bit userland guest can only use the low 32-bits of its address space with a 32-bit host at the moment. If you can set up the vsyscall page in low memory, then you may be able to get this to work. Otherwise you'll have to wait for someone to re-write the userland memory management in qemu. r~
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
Laurent Desnogues schrieb: > On Fri, Feb 5, 2010 at 11:57 PM, Stefan Weil wrote: >> Laurent Desnogues schrieb: > [...] >> I'm still struggling with bntest and other x86_64-linux-user software >> calling any of the vsyscall functions. >> >> Laurent, your vsyscall patch only works on x86_64 hosts. >> >> A lot of software calls time() which uses vsyscall on x86_64 which >> does not work with x86_64-linux-user mode. > > I'm not sure I understand what you mean. Did you try > on some other host and it failed? Was your host > 32-bit? If so, I'm afraid user-mode will fail for more > reasons than vsyscall. > >> So the status of x86_64-linux-user is not more than experimental :-( >> >> I tried to modify x86_64-linux-user to set up a vsyscall page in high >> memory, >> but this seems to be difficult (at least with 32 bit host). >> >> Any hints how this should be done are welcome. > > My patch explicitly prevents the linking of the vsyscall > page. > > Could you provide more info about your host? > > > Laurent > I tested two different hosts with x86_64-linux-user: * 32 bit Intel (i386) - does not work with your patch * 64 bit AMD (x86_64) - works with your patch Your patch improves the emulation for 64 bit hosts. Nevertheless, it has some open points: * target-i386 code should not have to know about linux vsyscall * there is no vsyscall page in memory, but very special programs might expect to see one (it is even worse: the target sees the memory page of the host) * it is not possible to step into vsyscall code using a debugger My favorite solution would be a vsyscall page mapped to the correct fixed address and filled with QEMU generated specific code, for example code which calls the normal syscalls to do the work. This would only need modifications for linux-user code. Regards Stefan
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Fri, Feb 5, 2010 at 11:57 PM, Stefan Weil wrote: > Laurent Desnogues schrieb: [...] > > I'm still struggling with bntest and other x86_64-linux-user software > calling any of the vsyscall functions. > > Laurent, your vsyscall patch only works on x86_64 hosts. > > A lot of software calls time() which uses vsyscall on x86_64 which > does not work with x86_64-linux-user mode. I'm not sure I understand what you mean. Did you try on some other host and it failed? Was your host 32-bit? If so, I'm afraid user-mode will fail for more reasons than vsyscall. > So the status of x86_64-linux-user is not more than experimental :-( > > I tried to modify x86_64-linux-user to set up a vsyscall page in high > memory, > but this seems to be difficult (at least with 32 bit host). > > Any hints how this should be done are welcome. My patch explicitly prevents the linking of the vsyscall page. Could you provide more info about your host? Laurent
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
Laurent Desnogues schrieb: > On Sun, Oct 18, 2009 at 5:09 AM, Jamie Lokier wrote: > [...] >> Please don't do that. Some code traces instructions through the >> vsyscall/vdso page, and will be surprised if a syscall instruction >> does not do what's expected based on the registers at that point. >> >> Also I don't know if anyone's done this, but I have played with the >> idea of an optimising x86->x86 JIT translator (similar to valgrind or >> qemu's TCG) which would include the vdso instruction sequence in it's >> traces, just because it didn't treat that any differently from other >> userspace code. Making the syscall instruction behave differently due >> to EIP would break that sort of thing. >> >> There's no performance penalty in setting a few registers prior to >> using the syscall instruction normally, so please do that. > > My proposed patch intercepts vsyscall as soon as the PC is > in the [VSYSCALL_START, VSYSCALL_END[ range, so all > instructions in that range won't be translated. Doing it > differently will cause problems due to the virtual address. > >> On x86_64, the vsyscall page has fixed address (see >> linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has >> variable address. >> >> On x86_32, the vdso has randomised address unless configurd to be a >> fixed address. On older kernels it was a fixed address and some >> binary programs assume they can call that. > > So QEMU can't do things properly and some binaries will > fail, right? > > > Laurent I'm still struggling with bntest and other x86_64-linux-user software calling any of the vsyscall functions. Laurent, your vsyscall patch only works on x86_64 hosts. A lot of software calls time() which uses vsyscall on x86_64 which does not work with x86_64-linux-user mode. So the status of x86_64-linux-user is not more than experimental :-( I tried to modify x86_64-linux-user to set up a vsyscall page in high memory, but this seems to be difficult (at least with 32 bit host). Any hints how this should be done are welcome. Stefan
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
Laurent Desnogues schrieb: > On Sun, Oct 18, 2009 at 5:09 AM, Jamie Lokier wrote: > [...] >> Please don't do that. Some code traces instructions through the >> vsyscall/vdso page, and will be surprised if a syscall instruction >> does not do what's expected based on the registers at that point. >> >> Also I don't know if anyone's done this, but I have played with the >> idea of an optimising x86->x86 JIT translator (similar to valgrind or >> qemu's TCG) which would include the vdso instruction sequence in it's >> traces, just because it didn't treat that any differently from other >> userspace code. Making the syscall instruction behave differently due >> to EIP would break that sort of thing. >> >> There's no performance penalty in setting a few registers prior to >> using the syscall instruction normally, so please do that. > > My proposed patch intercepts vsyscall as soon as the PC is > in the [VSYSCALL_START, VSYSCALL_END[ range, so all > instructions in that range won't be translated. Doing it > differently will cause problems due to the virtual address. > >> On x86_64, the vsyscall page has fixed address (see >> linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has >> variable address. >> >> On x86_32, the vdso has randomised address unless configurd to be a >> fixed address. On older kernels it was a fixed address and some >> binary programs assume they can call that. > > So QEMU can't do things properly and some binaries will > fail, right? > > > Laurent I can confirm that some binaries fail: x86_64-linux-user/qemu-x86_64 ./bntest with bntest from openssl creates a core dump. Will Laurent's patch be applied, or is there a better way to fix the problem? Stefan
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sun, Oct 18, 2009 at 5:09 AM, Jamie Lokier wrote: [...] > > Please don't do that. Some code traces instructions through the > vsyscall/vdso page, and will be surprised if a syscall instruction > does not do what's expected based on the registers at that point. > > Also I don't know if anyone's done this, but I have played with the > idea of an optimising x86->x86 JIT translator (similar to valgrind or > qemu's TCG) which would include the vdso instruction sequence in it's > traces, just because it didn't treat that any differently from other > userspace code. Making the syscall instruction behave differently due > to EIP would break that sort of thing. > > There's no performance penalty in setting a few registers prior to > using the syscall instruction normally, so please do that. My proposed patch intercepts vsyscall as soon as the PC is in the [VSYSCALL_START, VSYSCALL_END[ range, so all instructions in that range won't be translated. Doing it differently will cause problems due to the virtual address. > On x86_64, the vsyscall page has fixed address (see > linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has > variable address. > > On x86_32, the vdso has randomised address unless configurd to be a > fixed address. On older kernels it was a fixed address and some > binary programs assume they can call that. So QEMU can't do things properly and some binaries will fail, right? Laurent
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sun, Oct 18, 2009 at 4:47 AM, Jamie Lokier wrote: > Laurent Desnogues wrote: >> A recent compiler (gcc 4.4.0) produces this code for a statically >> compiled program: >> >> 005779e0 : >> 5779e0: 48 83 ec 08 sub $0x8,%rsp >> 5779e4: 48 c7 c0 00 04 60 ff mov $0xff600400,%rax >> 5779eb: ff d0 callq *%rax >> 5779ed: 48 83 c4 08 add $0x8,%rsp >> 5779f1: c3 retq > > Yes. It's a fixed address. See the kernel at > linux/arch/x86/kernel/vsyscall_64.c. There are only 3 vsyscall > functions defined: vgettimeofday, vtime and vgetcpu. My proposed patch already implements vgettimeofday and vtime. vgetcpu is TBD. > Even though it's a statically linked program, I'm not sure if the > above code will work on really old kernels. All I can say is that it's what my toolchain generates. Interestingly, dynamically shared programs don't run with QEMU on my machine. It looks like the PC is completely wrong. > The vsyscall page is different from the vdso, which has variable > address, and the address is supplied to Glibc. vdso provides nearly > the same functions in a different way. I don't understand how vdso and vsyscall interact (or don't interact): as I showed above, a statically linked program will use vsyscall. For dynamically linked program, I can't say, given what I said above; there might be a loader issue here. Laurent
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sun, Oct 18, 2009 at 04:09:44AM +0100, Jamie Lokier wrote: > Edgar E. Iglesias wrote: > > Did you consider having the linux-user loader pass a qemu version of the > > x86_64 vdso to the guest through the auxvector? That version could probably > > implement the vsyscalls by translating them into syscalls with x86_64 code. > > That seems like a good idea. > > Note that on x86_64, there is _both_ a vsyscall page at a fixed > address, and a vdso page at a randomised address with different > contents. Binary programs can call either or both. > > On x86_32, there is only a vdso page. It can be a variable or fixed > address. To run old binaries (but not so old they don't know about > vsyscall), it needs to be mapped at a fixed address. Modern kernels > have it mapped at a randomised address, and therefore won't work with > those binaries. Thanks for clarifiying. If I understand correctly, my suggestion won't work for vsyscalls because the specific fixed address might be unavailable or already used by the host... Cheers
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
Edgar E. Iglesias wrote: > Did you consider having the linux-user loader pass a qemu version of the > x86_64 vdso to the guest through the auxvector? That version could probably > implement the vsyscalls by translating them into syscalls with x86_64 code. That seems like a good idea. Note that on x86_64, there is _both_ a vsyscall page at a fixed address, and a vdso page at a randomised address with different contents. Binary programs can call either or both. On x86_32, there is only a vdso page. It can be a variable or fixed address. To run old binaries (but not so old they don't know about vsyscall), it needs to be mapped at a fixed address. Modern kernels have it mapped at a randomised address, and therefore won't work with those binaries. > It probably doesn't even need to do that btw, just make sure to fill it > with syscall insns to raise exceptions and then have the linux-user/ code > treat syscalls with eip from vdso page differently. That way the CPU model > doesn't need to know about vdso and you can implement vsyscalls that may > need magic interactions with qemu. > > Or does that not work for some reason? Please don't do that. Some code traces instructions through the vsyscall/vdso page, and will be surprised if a syscall instruction does not do what's expected based on the registers at that point. Also I don't know if anyone's done this, but I have played with the idea of an optimising x86->x86 JIT translator (similar to valgrind or qemu's TCG) which would include the vdso instruction sequence in it's traces, just because it didn't treat that any differently from other userspace code. Making the syscall instruction behave differently due to EIP would break that sort of thing. There's no performance penalty in setting a few registers prior to using the syscall instruction normally, so please do that. > Performance? syscall insns (sysenter/syscall/int $0x80/vsyscall/vdso) could be translated to helpers for the exact type of system call if the system call number is known, saving a little overhead. > Are there maybe old binaries that don't look in the auxvector and > just assume a fixed address for the vdso? On x86_64, the vsyscall page has fixed address (see linux/arch/x86/kernel/vsyscall_64.c), but the vdso usually has variable address. On x86_32, the vdso has randomised address unless configurd to be a fixed address. On older kernels it was a fixed address and some binary programs assume they can call that. -- Jamie
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
Laurent Desnogues wrote: > A recent compiler (gcc 4.4.0) produces this code for a statically > compiled program: > > 005779e0 : > 5779e0: 48 83 ec 08 sub$0x8,%rsp > 5779e4: 48 c7 c0 00 04 60 ffmov$0xff600400,%rax > 5779eb: ff d0 callq *%rax > 5779ed: 48 83 c4 08 add$0x8,%rsp > 5779f1: c3 retq Yes. It's a fixed address. See the kernel at linux/arch/x86/kernel/vsyscall_64.c. There are only 3 vsyscall functions defined: vgettimeofday, vtime and vgetcpu. Even though it's a statically linked program, I'm not sure if the above code will work on really old kernels. The vsyscall page is different from the vdso, which has variable address, and the address is supplied to Glibc. vdso provides nearly the same functions in a different way. -- Jamie
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
Hi Edgar, On Sat, Oct 17, 2009 at 9:57 PM, Edgar E. Iglesias wrote: > > It feels a bit strange to have the CPU model know about linux vsyscalls. > Did you consider having the linux-user loader pass a qemu version of the > x86_64 vdso to the guest through the auxvector? That version could probably > implement the vsyscalls by translating them into syscalls with x86_64 code. > It probably doesn't even need to do that btw, just make sure to fill it > with syscall insns to raise exceptions and then have the linux-user/ code > treat syscalls with eip from vdso page differently. That way the CPU model > doesn't need to know about vdso and you can implement vsyscalls that may > need magic interactions with qemu. > > Or does that not work for some reason? Performance? > Are there maybe old binaries that don't look in the auxvector and just assume > a fixed address for the vdso? A recent compiler (gcc 4.4.0) produces this code for a statically compiled program: 005779e0 : 5779e0: 48 83 ec 08 sub$0x8,%rsp 5779e4: 48 c7 c0 00 04 60 ffmov$0xff600400,%rax 5779eb: ff d0 callq *%rax 5779ed: 48 83 c4 08 add$0x8,%rsp 5779f1: c3 retq I never heard of "auxvector" before. Is this related to what is discussed here? http://manugarg.googlepages.com/aboutelfauxiliaryvectors I dumped 4KB mapped at AT_SYSINFO_EHDR and processed it through readelf. Nothing matches the address above: 0: 0 NOTYPE LOCAL DEFAULT UND 1: ff70030c 0 SECTION LOCAL DEFAULT7 2: ff70080074 FUNCWEAK DEFAULT 12 clock_gettime@@LINUX_2.6 3: 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.6 4: ff7006c0 137 FUNCGLOBAL DEFAULT 12 __vdso_gettimeofday@@LINUX_2.6 5: ff70085061 FUNCGLOBAL DEFAULT 12 __vdso_getcpu@@LINUX_2.6 6: ff7006c0 137 FUNCWEAK DEFAULT 12 gettimeofday@@LINUX_2.6 7: ff70085061 FUNCWEAK DEFAULT 12 getcpu@@LINUX_2.6 8: ff70080074 FUNCGLOBAL DEFAULT 12 __vdso_clock_gettime@@LINUX_2.6 I probably missed your point :-) Thanks, Laurent
Re: [Qemu-devel] [PATCH] User mode: Handle x86_64 vsyscall
On Sat, Jul 11, 2009 at 05:14:47PM +0200, Laurent Desnogues wrote: > Hello, > > the attached patch implements two of the three x86_64 vsyscall's. > Also attached is a test that demonstrates the issue and hopefully > the fix. > > Note there is a trick in there: since vsyscall functions are in high > memory, page_l1_map will return NULL resulting in an abort when > calling tb_link_phys in tb_gen_code. Also perhaps not very nice > is the way a ret is simulated in cpu_loop. > > I didn't implement vgetcpu. Hello Laurent, It feels a bit strange to have the CPU model know about linux vsyscalls. Did you consider having the linux-user loader pass a qemu version of the x86_64 vdso to the guest through the auxvector? That version could probably implement the vsyscalls by translating them into syscalls with x86_64 code. It probably doesn't even need to do that btw, just make sure to fill it with syscall insns to raise exceptions and then have the linux-user/ code treat syscalls with eip from vdso page differently. That way the CPU model doesn't need to know about vdso and you can implement vsyscalls that may need magic interactions with qemu. Or does that not work for some reason? Performance? Are there maybe old binaries that don't look in the auxvector and just assume a fixed address for the vdso? @@ -327,6 +330,9 @@ void cpu_loop(CPUX86State *env) int trapnr; abi_ulong pc; target_siginfo_t info; +#ifdef TARGET_X86_64 +int syscall_num; +#endif for(;;) { trapnr = cpu_x86_exec(env); @@ -356,6 +362,37 @@ void cpu_loop(CPUX86State *env) env->eip = env->exception_next_eip; break; #endif +#ifdef TARGET_X86_64 +case EXCP_VSYSCALL: if you open up a new block here, the declaration of syscall_num can be moved here (eliminating one #ifdef). You could maybe also do the syscall mapping in the vsyscall.h file. Something like this: env->regs[R_EAX] = do_syscall(env, x86_64_vdsoaddr2syscall(env->eip), env->regs[R_EDI], env->regs[R_ESI], Cheers > > > Laurent > > Signed-off-by: Laurent Desnogues > #include > #include > #include > #include > #include > > static void print_tod(const struct timeval *tv, const struct timezone *tz) > { > if (tv) > printf(" tv=%10ld.%06ld us", > tv->tv_sec, tv->tv_usec); > else > fputs(" (tv null)", stdout); > if (tz) > printf(" tz=%d/%d", > tz->tz_minuteswest, tz->tz_dsttime); > else > fputs(" (tz null)", stdout); > fputc('\n', stdout); > } > > static time_t t1, t2; > static struct timeval tv1, tv2; > static struct timezone tz1, tz2; > > int main(void) > { > int ret; > > fputs("Checking vtime with NULL param\n", stdout); > t1 = time(NULL); > printf(" %ld\n", t1); > sleep(1); > t2 = time(NULL); > printf(" %ld (should be t1 + 1)\n", t2); > > fputs("Checking vtime with non NULL param\n", stdout); > time(&t1); > printf(" %ld\n", t1); > sleep(1); > time(&t2); > printf(" %ld (should be t1 + 1)\n", t2); > fputc('\n', stdout); > > > fputs("Checking gettimeofday\n", stdout); > ret = gettimeofday(&tv1, &tz1); > printf(" ret=%d", ret); > print_tod(&tv1, &tz1); > sleep(1); > ret = gettimeofday(&tv2, &tz2); > printf(" ret=%d", ret); > print_tod(&tv2, &tz2); > > fputs("Checking gettimeofday (tv NULL)\n", stdout); > ret = gettimeofday(NULL, &tz1); > printf(" ret=%d", ret); > print_tod(NULL, &tz1); > sleep(1); > ret = gettimeofday(NULL, &tz2); > printf(" ret=%d", ret); > print_tod(NULL, &tz2); > > fputs("Checking gettimeofday (tz NULL)\n", stdout); > ret = gettimeofday(&tv1, NULL); > printf(" ret=%d", ret); > print_tod(&tv1, NULL); > sleep(1); > ret = gettimeofday(&tv2, NULL); > printf(" ret=%d", ret); > print_tod(&tv2, NULL); > > fputs("Checking gettimeofday (tv and tz NULL)\n", stdout); > ret = gettimeofday(NULL, NULL); > printf(" ret=%d", ret); > print_tod(NULL, NULL); > sleep(1); > ret = gettimeofday(NULL, NULL); > printf(" ret=%d", ret); > print_tod(NULL, NULL); > > return 0; > }