Re: changes in i386 and x86_64 assembrer

Bela Lubkin <[email protected]> Sun, 26 Dec 2010 16:47:08 -0800
Newsgroups gmane.linux.lib.dietlibc
Message-ID <[email protected]>
Felix von Leitner wrote:

> > There are also a population of errors at 521..530, defined in kernel
> > source: include/linux/errno.h.  These are inside `#ifdef __KERNEL__' and
> > commented "These should never be seen by user programs"; but they do
> > leak into user space.
>
> > One of the high values is ENOTSUPP (524), which is returned by a fair
> > number of paths.  This simple program invokes one of them to demonstrate
> > that something is wrong (requires SCTP protocol driver):
>
> Please file that as a bug in the kernel.  The kernel should not return
> those.

Can do; but I don't propose to find/demonstrate/report every instance.

dietlibc still needs to move threshold to at least cover ERFKILL.  If
512+ are kernel-internel then the threshold should probably be set to
511?

> > 2: save 2 bytes of code:
>
> > > 	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:
>
> > Setting %eax to return -1 can be shortened:
>
> >    	...
> >    	pop	(%eax)
> >   	stc
> >   #else
> >   	mov	%eax,errno
> >   #endif
> >   	sbb	%eax,%eax               # eax = eax - eax - CY = -1
>
> How do you know the carry flag is not set in the non-stc case?
>
> I think this is too obfuscating for this small of a gain.

Ah, but that obfuscation is already in the code!  The non-threaded path
already uses the carry (borrow) flag as set by `neg %eax' (note %eax is
guaranteed nonzero).  My proposed change just unifies the threaded path
with that.

If `stc; sbb' is too obfuscated then `neg; sbb' is more so.  So really,
this needs inline documentation to clarify the *old* code:

#define MAX_USER_ERRNO 511		/* (should be in linux/errno.h) */

	cmp	$-MAX_USER_ERRNO,%eax
	jb	.Lnoerror		# treat as *unsigned* compare
	neg	%eax			# sets CY = 1 since %eax != 0
#ifndef WANT_THREAD_SAFE
	mov	%eax,errno
#else
	push	%eax
	call	__errno_location	# (destroys CY)
	pop	(%eax)
	stc				# now CY = 1 on all paths
#endif
	sbb	%eax,%eax		# eax = (eax - eax) - CY = -1
.Lnoerror:

>Bela<