Subject: Re: shared library versions.
To: A Wizard of Earth C <terry@cs.weber.edu>
From: Paul Kranenburg <pk@cs.few.eur.nl>
List: current
Date: 11/08/1993 23:31:51
> I am curious as to whether or not this allows you to use "strip" against
> a program linked against a shared library or not; the implication in
> being able to add things to the library is that the GOT doesn't change
> symbol order, and new symbols occur later in the table (at least with my
> implementation).
> 
Yes, you strip a program. The "external" symbol table is not used at all
by the run-time linkers. Also, the order of entries in the GOT is not
important. If you rebuild a shared library, you can re-order it any way you
like, whether or not you bump version numbers.

> -- but then shared referenced objects would not, technically, be "stripped"
> if you kept the symbols around.
The only symbols kept are those necessary for dynamic linking, which generally
are the same symbols you would normally expect to see in an unstripped
program, apart from debugging and file symbols. These symbols are located in
a different location (within the text segment, actually) as it would be far
too much of a hassle to require that people not strip their binaries.
Anyway, the internal format of the symbol table has slightly changed in
format too.

> My impression was that
> major revs occur on *any* interface change, and minor revs are only for
> bug fixes without an interface change.
> 
Ok. Let's proof my point by intimidation :-) :
If I change the interface to read() from "read(int fd, char *buf, int n)" to
"read(int n, int fd, char *buf)", this would affect the odd program if you
try to run it with this new shared lib. Therefore, you would change the major
revision number. No program linked against a lower (other) revision of the
same lib will try to use the new one, but in stead will continue to search for
a matching major revision number. The same holds true for any change in
semantics (eg. if I were to interchange the meaning of "read" and "write").

Now, merely adding a function _foo() to a shared library would not change 
anything to existing programs. Only programs that actually start using the
new _foo() would no longer run correctly with older revisions of the same lib.
It's in this case that I would propose bumping the minor revision number.

Mere bug fixes should not be reflected in the revision numbers.

> PIC compiled standard library with a seperate GOT to avoid the split
> into two files (.a vs. .sa+.so), and if so, why did you avoid it?  I
> assume that you did and the answer will be to allow duplicate data
> pages [potentially unchanged by the app] to exist in a library?  If
> so, I would think it would take a library with a relatively large amount
> of data to equal the symbols kept in the binary -- but then again, this
> could add up quickly with a lot of libraries (then again, the symbols
> being kept around for X have got to be a bear...).
> 

I'm not sure what you're getting at in your last sentence. As far as
initialized data exported from shared libraries is concerned: if they
are referenced from non-PIC code (ie. the "main" program), an address
is allocated for them at link time (not unlike commons). The run-time
linker will copy the contents of the "master" copy (in the data segment
of the shared library) to this allocated address (after all other relocation
has been completed). Any other data in the shared library not referenced
in this way stays put at its original location.

From what I've seen so far, the amount of data copied does generally not
exceed a few hundred bytes (std{in,out,err}, _ctype_, sys_errlist[]).
I'm sure somebody can cook up pathological cases, but generally the amount
of code that remains shareable by doing it is worth the trouble.

-pk

------------------------------------------------------------------------------