[comp.lang.c++] SunOS shared libraries and virtual tables

gjb@cs.brown.edu (Gregory Brail) (03/19/91)

In SunOS, one can make libraries "shared," which means their code in
memory is shared between all processes that use them, and all those
executables use the same file to get at the code. However, external
initialized data (like global constants, for instance) cannot be
shared. One can, however, manually put all external initialized data
in a separate part of the library so it won't be shared and the rest
of the library will be.

With C, this is easy. With C++, however, all virtual tables and
pointers to virtual tables fall under the "external initialized data"
category, or at least that's how I understand it.

Has anyone come up with a good way to solve this problem? One can just
ignore the problem with virtual tables -- the shared libraries still
work (although less efficiently). One could also use the +e0 and +e1
arguments to cfront by creating one (or a few) files that contain just
class definitions and putting those definitions in the non-shared part
of the library. This, however, is a pain, and getting a few hundred
class definitions into one file isn't easy, to say the least.

The shared version of libC that comes with Sun C++ appears to have the
virtual tables in the sharable portion of the library. Is this the
correct solution, or should one put the virtual tables in the
non-shared portion? And if that's the case, what's the easiest way to
do that?

Thanks in advance for the help.

				-greg
+----------------------------------------------------+
Greg Brail
Internet: gjb@cs.brown.edu  BITNET: gjb@browncs.bitnet
UUCP:	..uunet!brunix!gjb  Home:   (401)273-1172

dsr@mir.mitre.org (Douglas S. Rand) (03/19/91)

In article <68989@brunix.UUCP>, gjb@cs.brown.edu (Gregory Brail) writes:
> In SunOS, one can make libraries "shared," which means their code in
> memory is shared between all processes that use them, and all those
> executables use the same file to get at the code. However, external
> initialized data (like global constants, for instance) cannot be
> shared. One can, however, manually put all external initialized data
> in a separate part of the library so it won't be shared and the rest
> of the library will be.
> 
> With C, this is easy. With C++, however, all virtual tables and
> pointers to virtual tables fall under the "external initialized data"
> category, or at least that's how I understand it.
> 
> Has anyone come up with a good way to solve this problem? One can just
> ignore the problem with virtual tables -- the shared libraries still
> work (although less efficiently). One could also use the +e0 and +e1
> arguments to cfront by creating one (or a few) files that contain just
> class definitions and putting those definitions in the non-shared part
> of the library. This, however, is a pain, and getting a few hundred
> class definitions into one file isn't easy, to say the least.
> 
> The shared version of libC that comes with Sun C++ appears to have the
> virtual tables in the sharable portion of the library. Is this the
> correct solution, or should one put the virtual tables in the
> non-shared portion? And if that's the case, what's the easiest way to
> do that?
> 
> Thanks in advance for the help.
> 
> 				-greg
> +----------------------------------------------------+
> Greg Brail
> Internet: gjb@cs.brown.edu  BITNET: gjb@browncs.bitnet
> UUCP:	..uunet!brunix!gjb  Home:   (401)273-1172

It's really pretty simple.  All read-only linkage can be shared.  Are
virtual tables apropriate for read-only linkage?  No run-time initialization?
If so they can be treated as any const declaration and put in the read-only
pure code space.  Otherwise they must go in a per-user read/write space.

Only in Unix is this a new debate.

-- 
Douglas S. Rand 
Internet:   <dsrand@mitre.org>
Snail:	    MITRE, Burlington Road, Bedford, MA 
Disclaimer: MITRE might agree with me - then again...
Amateur Radio: KC1KJ

benson@odi.com (Benson I. Margulies) (03/20/91)

Our experience is this:

Ignore sun's description of "exported, initialized data." It is, in
fact too narrow.

If its a global scope item with a non-zero initialization, put it in
the .sa archive, whether or not is is "exported." According to sun's
documentation, writable items accessed purely within a libary aren't
supposed to require placement in the .sa file, but something is wrong
(documentation or code, I don't know which) and they come up zero if
they aren't in the .sa file.

A tip-off of trouble is "creeping B disease." If you forget to move
something to exports, it will show up in the base executable as a "B",
as well as being a "D" in the library.

Vtbls are not modified at runtime by sane programs, and so can stay in
the shared libs. Our do, and are perfectly happy.

Watch Out For Static Constructors! munch has no way to distinguish the
constituent .o files of a shared lib, so static constructors for a
shared lib are an all or nothing proposition.

It is possible to use patch (actually, nothing at all) rather than
munch for SunOS shared libs, but you have to replace _main with a
version that crawls around the structures hanging off _DYNAMIC
at runtime. 

-- 
Benson I. Margulies