Subject: Re: When is ELF coming?
To: Curt Sampson <cjs@portal.ca>
From: John Birrell <jb@cimlogic.com.au>
List: port-alpha
Date: 11/20/1996 19:00:17
Curt Sampson wrote:
> What I can't figure out is what the use of this is. I mean, I
> understand that it's useful not to have your entire namespace filled
> with the symbols from all your libraries even before you start :-),

Here's why I need it:

libc has a syscall (function) called "read", for example. Suppose I
want a threaded process using POSIX threads implemented in user-space.
libpthread needs to supply a function called "read" that provides
a blocking interface to the programmer, but actually does non-blocking
calls to the kernel. To allow an application to be linked to both libc
and libpthread (to share common code), libc needs to have its version
of the syscall with a non-weak name like "_sys_read" with a weak symbol
called "read". If an application is linked against libc only, the
linker won't find a non-weak symbol for "read", so it will use the
weak one. If the same application is linked against libc _and_
libpthread, then the linker will link "read" calls to the symbol in
libpthread, ignoring the weak one in libc.

Another example:

Chris has updated his cerror.S code to allow for J.T.'s design of
__errno based on _REENTRANT. If the current tool set supported
weak symbols, a better (IMHO) design would have been to have cerror.S
coded with "_cerror" as the non-weak symbol with a weak alias for "cerror"
and leave the code accessing the global errno variable directly. Then
in libpthread, the version of cerror with a non-weak symbol would have
the code to access a thread-specific error variable (which will be slower).
The way it stands now, if you build libc on NetBSD/Alpha with -D_REENTRANT
you'll take a performance hit whenever errors are returned from syscalls.

> but isn't a linker supposed to do this sort of thing automagically?

You tell the linker what you want it to do. One of the ways of telling
it is via the "weak" bit. Without this, the linker would have two
symbols of the same name - which one would it take? Probably the
wrong one.

> This seems to work now; I can put my own getpid() in a program and
> that will be called instead of the library routine without complaint,
> and even though I link against libc (for printf), which contains
> getpid().

I think you'll find that if you override getpid (by providing your
own non-weak symbol), then any library call that calls getpid will
call *your* routine and probably end in tears.

mktemp() in libc calls getpid(). I tried this:

---------------------------------------------------------------------
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

pid_t getpid()
{
    printf("This is not the real getpid!\n");
    return(1);
}

int main()
{
    char path[128] = "/tmp/harry.XXXX";
    char *ptr;
    if ((ptr = mktemp(path)) != NULL)
       printf("mktemp returned '%s'\n",ptr);
    return(0);
}
---------------------------------------------------------------------

and when I run it:

This is not the real getpid!
mktemp returned '/tmp/harry.0001'

Now if libc had getpid with the non-weak symbol as "_sys_getpid" and
a weak symbol as "getpid", my design would have libc internals calling
_sys_getpid, not getpid. So, according to the principle of least
astonishment 8-), weak symbols in libc are desirable. But...

When you add libpthread into the equation, this gets really tricky
if you consider libc functions that are layered on top of functions
that libpthread provides a replacement for. "read" is a good example.
"res_send" calls "read". In a threaded program, res_send in libc
needs to call "read" in libpthread, not "_sys_read" in libc so that
libpthread handles the blocking case. And then if you code a function
called "read", I'm sunk. I'd need degrees of weakness to handle _three_
functions with apparently the same name. 8-(

> cjs

-- 
John Birrell                                CIMlogic Pty Ltd
jb@cimlogic.com.au                          119 Cecil Street
Ph  +61  3 9690 6900                        South Melbourne Vic 3205
Fax +61  3 9690 6650                        Australia
Mob +61 18  353  137