changes in i386 and x86_64 assembrer
Nikola Vladov <[email protected]> Thu, 23 Dec 2010 15:29:26 +0200
| Newsgroups | gmane.linux.lib.dietlibc |
|---|---|
| Message-ID | <[email protected]> |
First, happy holidays!
I see that on some ARCH files in unified.S exist the function
__error_unified_syscall
It is missing on x86_64 and i386. I find it a nice solution.
Using this function the files time.S and gettimeofday.S on x86_64 become:
----------------------------------------------
.text
.global time
.type time,@function
time:
mov $0xffffffffff600400,%rax
call *%rax
jmp __error_unified_syscall
----------------------------------------------
.text
.global gettimeofday
.type gettimeofday,@function
gettimeofday:
mov $0xffffffffff600000,%rax
call *%rax
jmp __error_unified_syscall
----------------------------------------------
Then we need to change x86_64/unified.S little:
movzwl %ax, %eax
mov %rcx, %r10
syscall
+.global __error_unified_syscall
+__error_unified_syscall:
cmpq $-128, %rax
jbe .Lnoerror
negl %eax
That is all for x86_64. May be in the future __error_unified_syscall
will be used in other functions. With above changes time.o and
gettimeofday.o on my PC are each 14 bytes. In current dietlibc they
are 31 and 28 bytes. Why time.S uses gettimeofday? One reason is that
time should return time_t and syscalls return int type?
--------
On i386 the changes for __error_unified_syscall are also minimal.
I describe them here. This is not a diff -- I made next with an editor.
movl 8*4(%edi),%esi
movl 10*4(%edi),%ebp
movl 9*4(%edi),%edi
#ifdef WANT_SYSENTER
call *.Lvsyscall /* 0xffffe000 */
#else
int $0x80
#endif
+ pop %ebp
+ pop %ebx
+ pop %esi
+ pop %edi
+.global __error_unified_syscall
+__error_unified_syscall:
cmp $-124,%eax
jb .Lnoerror
neg %eax
#ifdef WANT_THREAD_SAFE
- movl %eax,%ebx
- call __errno_location
- movl %ebx,(%eax)
+ /* we cannot use anymore %ebp; it is recovered already above! */
+ push %eax
+ call __errno_location
+ pop (%eax)
orl $-1,%eax
#else
mov %eax,errno
sbb %eax,%eax # eax = eax - eax - CY = -1
#endif
.Lnoerror:
- pop %ebp
- pop %ebx
- pop %esi
- pop %edi
/* here we go and "reuse" the return for weak-void functions */
#include "dietuglyweaks.h"
ret
---------
And here are the files with them I tested that both vsyscalls work
on x86_64. They work with glibc and dietlibc correct.
I used vtime and vgettimeofday to be shure that the link is correct.
---------------- Vtime.S ---------------
.text
.global vtime
.type vtime,@function
vtime:
mov $0xffffffffff600400,%rax
call *%rax
ret
.text
.global vgettimeofday
.type vgettimeofday,@function
vgettimeofday:
mov $0xffffffffff600000,%rax
call *%rax
ret
---------------- vt.c ------------------
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
extern time_t vtime(void *);
extern int vgettimeofday(void *, void *);
int main() {
struct timeval tv;
printf("%ld\n", vtime(0));
vgettimeofday(&tv, 0);
printf("%ld\n", tv.tv_sec);
return 0;
}
Regards,
Nikola