Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Jul 2002 16:29:22 -0700
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Taavi Talvik <taavi@uninet.ee>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Linker sets portability
Message-ID:  <3D34AC52.2D882455@mindspring.com>
References:  <20020717014008.Y99892-100000@valu.uninet.ee>

next in thread | previous in thread | raw e-mail | index | archive | help
Taavi Talvik wrote:
> Probably this belongs to questions, but anyway:
> 
> How portable is idea of using linker sets? Is it possible
> to use them (maybe using some preprocessor wizardry) on
> linux/solaris/win/etc? Do they have somewhat similiar facilities?

"Moderately portable".

A linker set is basically a mechanism for getting the linker
to aggregate instances of a structure element into an array
of structure elements, and then set a total count.

In effect, it allows you to "magically" declare an initialized
array of data in a distributed fashion, instead of having to
declare it al together, in one module.

It is an abuce of the method that the GNU ld uses in order to
aggregate lists of constructor and destructor references for
support of virtual, pure virtual, and template classes as
single instances, rather than as static per object instances.

This basically allows you to do "templateclassname<int> foo;",
and end up with only one copy of the member function code (the
constructor, destructor, etc.) for the entire program, even if
you statically declare instances of this class type in multiple
compilation units.


The simple answer to your question is that you can abuse this
mechanism wherever you use ELF, GNU ld is used as your linker,
and your compiler supports inline assembly with ELF section
attribution.

This answer is "good enough" if you are using GNU tools on all
your platforms, so you could stop reading now.  However, if you
are not...


The more complete answer is that any linker that supports a C++
compiler, and for which the combination permits a single instance
of a constructor/destructor for a virtual or pure virtual base
class *might* support linker sets, if the code was implemented
generically enough (i.e. the aggregation effect is by attribute,
not by specific name, and limited to e.g. ".init" and ".fini").

If it supports single instancing with template classes, rather
than static instancing, then you are *guaranteed* that the linker
can support linker sets.

In general, this must be supported to enable implementation of
certain C++ standard mandated elements, in particular, static
data members, such as list<type>::count (an integer count of
elements on a per type list), which could not be implemented
with per compilation unit static instances.  So the claim
"standards compliant", if accurate, usually means "yes".

Whether the C compiler can generate them is based on the ability of
the C compiler to generate linker C++ feature triggering code...
which bascially means inline assembly, and the ability to specify
enough information to trigger the linker effect (i.e. if the
linker looks at the object attribute ans the compiler attributes
objects as "compiled C code" as distinct from "compiled C++ code",
then it won't work; because of the need for C++ code to link with
system libraries written in C, though, this check is unlikely).

Microsoft DLL's have that ability, derived from OLE, and based on
the current COM (Common Object Model) to create arbitrary support
for aggregate objects.  Specifically, Microsoft DLL's which are
instances of COM objects generally have "process attach" and
"process detach" entry points (equivalent to ".init" and ".fini"
in UNIX for the creation of global constructors and destructors).

They also have the ability to support arbitrary "thread attach"
and "thread detach" entry points.   These are necessary to be able
to support "rental" and "apartment" model threading, which permits
you to create a thread-unsafe library, and maintain the ability to
use it from a threaded program anyway (UNIX is very behind Microsoft
here; an example is the LDAP and IMAP4 client libraries, both of
which could benefit from these models, but of course, the LDAP
libraries are generally not thread safe even on Win32, because
people don't know how to program to Windows threads models).

Because they need to be able to create a worker thread at "process
attach", kill it at "process detach", and IPC with it from threads
which rendesvous at "thread attach" and "thread detach", Microsoft
supports an arbitrary extension mechanism in their linker, which
you can access from Visual C++ inline asm directives (the WSOCK32
-- "winsock" -- API requires this ability, since it uses an event
engine to translate windows events for asynchornous events; every
Windows network application effectively relies on a hidden window
with an event loop in it based on a "process attach" to the DLL).

--

So the general answer is "pretty much everyone whose linker is
capable of linking programs compliant with the C++ standards,
and whose C compiler supports a sufficiently sophisticated ability
to escape to inline assebly to generate the data that the linker
uses to accomplish C++ specific features, can be made to support
linker sets".

Of course... "the implementation is left as an exercise for the
student"... 8-).

-- Terry

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3D34AC52.2D882455>