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