From: prener@watson.ibm.com (Dan Prener)
Subject: Re: AIXv3 shared-library binding anomolies
Date: Tue, 21 Jul 1992 08:35:06 GMT
Distribution: comp
Disclaimer: This posting represents the poster's views, not necessarily those of IBM
	<PRENER.92Jul18020046@prener.watson.ibm.com>
	<1992Jul18.143244.12523@athena.mit.edu>
	<PRENER.92Jul19022217@prener.watson.ibm.com>
	<1992Jul20.223521.1080@ultra.com>
Organization: IBM T.J. Watson Research Center, Hawthorne, New York

In article <1992Jul20.223521.1080@ultra.com> marc@mercutio.ultra.com (Marc Kwiatkowski {Host Software-AIX}) writes:

>In article <PRENER.92Jul19022217@prener.watson.ibm.com> prener@watson.ibm.com (Dan Prener) writes:

>>   We are both wrong.  I was thinking of the case of the call using a
>>   function pointer.  That takes 6 cycles, because the function pointer
>>   (i.e., the address of the function descriptor) must be loaded regardless
>>   of whether the function is in a shared library.

>There are two separate issues here.  First, the shared libc binds 
>local function calls at load time.  

Actually, it binds them at link time.  Is that what you mean by "load time"?
I tend to think of load time as the time "exec" loads the program.

>That is, a call by function foo00
>in the libc namespace to function foo01 in the libc namespace gets bound at
>load time.  So, if the program declares a function foo01 in the application
>namespace and then calls foo00, foo00 will still call foo01 in the 
>libc namespace.  In this case, efficiency is an issue, but it is questionable
>whether or not this is a valid area for optimization.  As a comparison,
>imagine someone discovering that they could write a user application that
>could used traps and other protected-mode instructions, and then being told
>by the developers that both kernel and user threads run in protected mode
>because it is more efficient.  While the statement is true, it also
>useless, because, by definition, user threads cannot run in a protected mode.
>Similarly, it is true that static binding of intra-libc function calls
>is more efficient, but by definition application space functions must
>override their libc counterparts, period.  

The optimization can, of course, be defeated by linking a non-shared copy
of libc.  The issue can get more complicated with other libraries, since
some other libraries may make use of the tight binding of shared libraries.

Just out of curiousity, where is the definition that says that application
space functions must override their libc counterparts?

>The second issue is that for inter-libc function calls, the 
>libc search path is also bound at load time.  For example, consider
>an application that uses a shared library libshare.a that redefines 
>the function write().  When the application calls write directly, the
>run-time binding correctly transfers execution to the libshare.a version
>of write(), however, if the application calls printf the run-time binding
>of write() within libc.a does not reevaluate the search path, and so does
>not discover that libshare.a is the correct namespace to use.  This has
>nothing to do with efficiency.  The cost of run-time binding to the 
>libshare.a write() or the /unix write() is exactly the same.

This second issue is not orthogonal to the first, though.  Given the
lack of indirection in the current scheme, there is no way the bindings
can be changed at run time.

>I am a little skeptical about the claims of improved performance by 
>statically binding inter-library calls to exported functions.  What 
>percentage of all function calls within libc.a are calls to libc.a entry 
>points?

The figure would depend on the application.  Statically, I think the
vast majority are.
--
                                   Dan Prener (prener@watson.ibm.com)
Newsgroups: comp.unix.aix