Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Jan 2012 00:12:06 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Andreas Tobler <andreast@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r229693 - in head/lib/libc: powerpc powerpc64
Message-ID:  <20120106225728.G9027@besplex.bde.org>
In-Reply-To: <201201060921.q069Lfi8081051@svn.freebsd.org>
References:  <201201060921.q069Lfi8081051@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 6 Jan 2012, Andreas Tobler wrote:

> Log:
>  Use the macro WEAK_ALIAS. Tested on 32 and 64-bit.

This API should be fixed before using it extensively.  It has the args
reversed relative to the C API __weak_reference().  Also, its name is
different, and the spelling of "=" in its implementation is different.
Perhaps the arg order makes sense for both, since for WEAK_ALIAS() the
alias is the first arg, while for __weak_reference() the symbol being
referred to to create the alias is the first arg.  But this is still
confusing.

The easiest way to fix this is to remove WEAK_ALIAS() and add an asm
API WEAK_REFERENCE().  Unfortunately, ALIAS is a better name than
REFERENCE.  __weak_reference() is not so easy to change since it is
used extensively

Similarly for STRONG_ALIAS() and __strong_reference(), except
STRONG_REFERENCE() doesn't exist for most arches and __strong_reference()
didn't exist until this week, so neither is used extensively.

More details on current existence and use of these:

In the kernel, WEAK_ALIAS is not defined for amd64 or sparc64, and is
never used.

In libc, WEAK_ALIAS was only used for arm, ia64 and mips.  Now it is used
for some i386 string functions.

In the kernel, STRONG_ALIAS was only defined for mips, and was never used.
Now it is also defined for i386, and is never used.

In libc, STRONG_ALIAS was not used.  It was used for a few days in some
i386 string functions.  This was a bug.  Now WEAK_ALIAS is used instead,
and STRONG_ALIAS is not used again.  It is another bug that these
"optimized" i386 string functions (strchr/index and strrchr/rindex) even
exist.  amd64 doesn't have them.  The MI versions are not very optimal,
but neither are the i386 ones.

> Modified: head/lib/libc/powerpc/SYS.h
> ==============================================================================
> --- head/lib/libc/powerpc/SYS.h	Fri Jan  6 09:17:34 2012	(r229692)
> +++ head/lib/libc/powerpc/SYS.h	Fri Jan  6 09:21:40 2012	(r229693)
> @@ -44,10 +44,8 @@
> 	.align 2;						\
> 2:	b	PIC_PLT(CNAME(HIDENAME(cerror)));		\
> ENTRY(__CONCAT(__sys_,x));					\
> -	.weak	CNAME(x);					\
> -	.set	CNAME(x),CNAME(__CONCAT(__sys_,x));		\
> -	.weak	CNAME(__CONCAT(_,x));				\
> -	.set	CNAME(__CONCAT(_,x)),CNAME(__CONCAT(__sys_,x));	\
> +	WEAK_ALIAS(x,__CONCAT(__sys_,x));			\
> +	WEAK_ALIAS(__CONCAT(_,x),__CONCAT(__sys_,x));		\
> 	_SYSCALL(x);						\
> 	bso	2b
>

The style bugs in this should be fixed someday.  This is still messed up
to support K&R.  With ancient cpp's, you had to write __CONCAT(x,y) instead
of __CONCAT(x, y) to avoid getting a space between x and y.  This was fixed
in Standard C 22 years ago, but all SYS.h files in libc except ia64's one
still use the ugly __CONCAT(x,y) in most places.  ia64 hard-codes
__CONCAT(x, y) as x ## y instead.

The missing space after the comma for the WEAK_ALIAS() parameters is even
less necessary.  For ancient cpp's, it allowed WEAK_ALIAS to format the
asm directives without a space.  With STDC cpp's, the formatting is
controlled by the macro, but it is still hard to produce nice formatting
because cpp may change whitespace.

__weak_reference() also difference from WEAK_ALIAS() in the spelling
of "=".  It uses ".equ".  ".set" in the all the SYS.h's except ia64 and
mips (*) seems to be yet another spelling.

(*) ia64 avoids the hard coded directive using WEAK_ALIAS().  mips
hard-codes "=" instead of ".set".

Some other gratuitous differences in the SYS.h's:
- arm and mips use _C_LABEL() instead of CNAME()
- ia64 doesn't use either _C_LABEL() or CNAME()
- arm, ia64 and mips don't use HIDENAME() for cerror:
   - arm uses CERROR and hard-codes this as  _C_LABEL(cerror)
   - ia64 hard-codes it as .cerror
   - mips hard-codes it as __cerror.
- sparc64 doesn't use ENTRY() or END() and has to repeat things like .type
   and .size found in those when it defines _SYSENTRY() and _SYSEND().
   It doesn't use CNAME() in these definitions.  Underscores in these
   names are bogus, since these names are even less public than ENTRY()
   and END() which don't have them.

Some of these differences may be due to FreeBSD's cleaning up or down
of the decomposition of SYS.h and <machine/asm.h> only for older arches.
Both of these files are MD so you can hard-code things in either, but
I think it is best put as much of the details as possible in the lowest
level, which is <machine.asm.h>.  Using WEAK_ALIAS() from there is a
step in this direction.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120106225728.G9027>