Subject: Re: When is ELF coming?
To: Jeffrey Hsu <hsu@freefall.freebsd.org>
From: John Birrell <jb@cimlogic.com.au>
List: port-alpha
Date: 11/21/1996 16:12:32
Jeffrey Hsu wrote:
>   > 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.
> 
> If the file descriptor has been set to non-blocking mode, _sys_read
> may not work as expected, no?  Another example would be write(), which
> is used internally inside libc.  Even if, using weak symbols, the libc
> routine correctly calls _sys_write(), it may not be expecting an EAGAIN
> error return.

[I'm not sure I'm able to explain this well.
 I'm doing NT stuff this week. %$#@!... *Sigh* ]

If libc is changed to use hidden names (like _sys_read) to solve
Chris' problem with ELF shared libraries then it will function 
exactly like it does now, until you try to use libpthread.

With libpthread (which is when things turn non-blocking internally and
the potential for EAGAIN occurs), the design comes unstuck because
libpthread wants to replace the _sys_read that libc is using.

If it were possible, the solution would require another level of aliasing.
Say a non-weak (strong) symbol is level 0, with increasing numbers being
weaker.

Take read as an example:

library           symbol              level      comments
-------------------------------------------------------------------------
libc              __sys_read          0          (the syscall)
                  _sys_read           1          (weak alias of __sys_read)
                  read                2          (weak alias of __sys_read)

libpthread        _sys_read           0          (the pthread wrapper)
                  read                1          (weak alias of _sys_read)


Then code libc functions (like res_send) to call a function called
_sys_read to do a "read". If linked against just libc, then this is
resolved to __sys_read (the actual syscall) by a level 1 alias. If also
linked against libpthread, then _sys_read (the pthread wrapper) is a
level 0 (== non-weak) alias. This works fine.

A user call to a function called "read" linked against just libc resolves
to __sys_read (the syscall) through a level 2 alias. When linked against
libpthread too, the "read" call resolves to _sys_read (the pthread
wrapper) through a level 1 alias which takes precedence over the level
2 alias found in libc.

If you take away the alias levels and just have a boolean weak symbol
like we have now, then the two "read" aliases can't be differentiated. 8-(

Does that make sense?

Can you see a solution (assuming that I've explained the problem 8-)?


-- 
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