[RFC] Cygwin libstdc++ plan (operator new/delete replacement)

Dave Korn dave.korn.cygwin@googlemail.com
Sun Jun 28 13:35:00 GMT 2009

    Hi everybody,

  Here's a way to implement C++ replacement of the C++ operators new, delete,
etc., etc. (hereafter ONDEE).  This is a simpler approach than going the whole
hog with load-time dynamic relinking, and may be a better one for that reason;
on the other hand, it's a little more fragile than having all the support at
the lower end of the toolchain, as it relies on the g++ driver specs being
used when compiling and linking C++.  That's probably not a serious downside,
as not using the driver to link is already a "don't do this unless you really
know what you're doing" kind of activity, but I mention it so it can be taken
into consideration.

  The heart of the trick is to use LD's --wrap option to redirect all
references to the replaceable ONDEE functions.  The cygwin DLL then exports
these wrapper functions, so every reference to an ONDEE function in either
DLLs or EXEs gets redirected to the cygwin DLL.

  Meanwhile, we add a struct in _cygwin_crt0_common.cc that records the real
values of whichever ONDEE symbols are referenced in the final link so we know
what overrides were in effect at that time.

  We keep a pointer in the DLL's internal per_process struct to the current
set of overrides.  At process startup time, this points to the DLL's own
private internal versions of the ONDEE functions; as the application's DLLs
are loaded and perform their crt0 common init, they inherit any defaults that
they don't have overrides for into their own list of overrides, and then
register the resulting set as the global set of overrides.

  The application does likewise with its own overrides, so by the time we're
ready to start executing, the full final set of overrides are in place, and
this all happens before static c-tors get called in __main.

  The rest of the patch contains little of note.  There's a new module,
libstdcxx_wrapper.cc, which contains the wrapper functions; they trivally jump
through the function pointers in the override struct.  There are exports for
the wrappers in cygwin.din.

  I've added a bit of makefile hackery so that we can selectively remove the
-nostdinc and -nostdincxx flags when compiling particular source files.  I
think it's probably important to #include the real "new" header file where
we're doing this and get all the definitive types and definitions from the
compiler's headers.  (I still had to go and copy and paste the declarations
into _cygwin_crt0_common.cc because there's no other way to apply the
necessary attributes to them.)

  One omission that I'd have to rectify before this could be a submission
rather than an RFC is that I haven't remembered to bump the abi version number
in this patch.  There's also some rather long lines I expect I'd better wrap.

  Apart from that this is the final shape of a working solution to the
problem.  I think it's wholly backward compatible: old applications and DLLs
won't know about or use the redirectors or wrappers.  Statically-linked apps -
which are the only apps where ONDEE replacement has ever worked - won't
change.  Old dynamically-linked apps will continue to import directly from
libstdc++ or to use any overrides that they linked at final-link time, and
libstdc++ will continue to not be interposed in this case.  I do not expect
there to be any requirement for new DLLs or EXEs to be compatible with older
versions of the DLL.

  There might just be a corner case with dynamically-linked apps that link
against a mix of new and old DLLs and where the old DLLs supplied overrides.
But since none of this has actually worked correctly ever anyway, I think it's
reasonable to require a recompile.  We're breaking ABIs with abandon right now :)

  From the GCC side of things, I need do very little except add something like

#define CXX_WRAP_SPEC "\
  --wrap _Znwj \
  --wrap _Znaj \
  --wrap _ZdlPv \
  --wrap _ZdaPv \
  --wrap _ZnwjRKSt9nothrow_t \
  --wrap _ZnajRKSt9nothrow_t \
  --wrap _ZdlPvRKSt9nothrow_t \
  --wrap _ZdaPvRKSt9nothrow_t "

to the linker spec.  If we agree this is a reasonable approach to take, I
could rush out a gcc4-4.3.2-3 update to add this very quickly.

  So, would everyone be happy to do it this way?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: cygwin-dll-libstdcxx-wrappers.diff
Type: text/x-c
Size: 16142 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-developers/attachments/20090628/d8032f20/attachment.bin>

More information about the Cygwin-developers mailing list