delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/1999/11/21/03:29:27

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Unsubscribe: <mailto:cygwin-unsubscribe-archive-cygwin=delorie DOT com AT sourceware DOT cygnus DOT com>
List-Subscribe: <mailto:cygwin-subscribe AT sourceware DOT cygnus DOT com>
List-Archive: <http://sourceware.cygnus.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sourceware DOT cygnus DOT com>
List-Help: <mailto:cygwin-help AT sourceware DOT cygnus DOT com>, <http://sourceware.cygnus.com/ml/#faqs>
Sender: cygwin-owner AT sourceware DOT cygnus DOT com
Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com
From: gschmidt AT pinball-wizard DOT mit DOT edu
Message-Id: <199911210828.DAA04748@pinball-wizard.mit.edu>
To: cygwin AT sourceware DOT cygnus DOT com
Cc: Mumit Khan <khan AT nanotech DOT wisc DOT edu>, gcc AT gcc DOT gnu DOT org
Subject: Workaround for virtual function/dllimport bug, also patch guidance request
In-reply-to: Your message of "Wed, 17 Nov 1999 12:06:38 CST."
<199911171806 DOT MAA07458 AT pluto DOT xraylith DOT wisc DOT edu>
Date: Sun, 21 Nov 1999 03:28:21 EST

Mumit Khan <khan AT nanotech DOT wisc DOT edu> writes: 
> There are a few nasty bugs when you have virtual functions and also
> inline functions in DLL imported classes. It's going to take quite
> a few tweaks in the C++ front end to fix these, and unfortunately
> I don't have the time right now. Hopefully someone else will jump
> in fix these ... the vtable issue is particular harder to fix since
> the GNU C++ vtables use offsets, which don't work for dllimported
> functions.

I finally gritted my teeth and dove into the source last night.

My understanding of the problem is that dllimported functions
currently can't appear in vtables, so when you derive a child class
from a parent class exported from a DLL and don't override all of the
virtual members, you get the aforementioned error.  Normally when you
take the address of a dllimported function in global scope, ie

void func(void) __declspec(dllimport);
void (*some_pointer)(void) = func;

GCC works around the problem of func not having an address knowable at
compiletime by generating an initialization function that's called
automatically at startup that sets func to the correct value.  But
vtables are handled separately and GCC aborts instead of knowing to
add the vtable to the runtime-init list.  As far as I can tell the
offset data, whether in the vtable or a thunk function, isn't part of
the problem -- it can be computed at compile-time from the header
files, right?

A workaround exists.  Keep in mind that if a function isn't declared
dllimport but is in fact imported from a DLL, the springboard function
in the import library gets used (at a slight performance penalty.)
Since you *can* take the address of the springboard function at
compile time, it can go in the vtable, so if you simply *don't declare
virtual functions as dllimport* but just make sure they're exported
correctly when the import library is made, everything will be fine
(except for the small performance hit.)

However, you still must declare any static class data as dllimport.
So instead of tagging the whole class __declspec(dllimport), you have
to individually tag just the static data members, and optionally
non-virtual functions for performace.  I've tested this in a toy case
and it seems to work as reasoned.

Since I don't want to go through the whole library retagging all of
the classes, and since I want to keep MSVC compatibility, and since
this case should really be handled correctly, I've been thinking about
the best way to patch this.  I know very little about GCC so any
suggestions are appreciated.  Should I:

-- add code to finish_file or thereabouts to catch the case where a
vtable would contain addresses not known at compiletime and tack stuff
on to the static storage duration function (the ___static_initialization_
and_destruction thingy) to init the vtable at runtime?  this is the
"right way" in the sense that the springboard function isn't used, so
it's most efficient at the expense of a few extra bytes of init
function..

-- hack the dllimport attribute so that when it's applied to a class,
it filters down only to members that are static data or non-virtual
functions, and is automatically turned off for virtual functions (even
if you try to do it manually, I guess)?  this has the advantage of not
touching the front end, just config/i386/winnt.c (or that's my initial
impression)..

-- something else?

thanks,

Geoff Schmidt
gschmidt AT mit DOT edu

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019