From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31066 invoked by alias); 7 Aug 2009 13:40:19 -0000 Received: (qmail 31054 invoked by uid 22791); 7 Aug 2009 13:40:16 -0000 X-SWARE-Spam-Status: No, hits=-0.3 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_43,J_CHICKENPOX_53,J_CHICKENPOX_63,J_CHICKENPOX_73,J_CHICKENPOX_83,J_CHICKENPOX_93,SPF_PASS X-Spam-Check-By: sourceware.org Received: from hagrid.ecoscentric.com (HELO mail.ecoscentric.com) (212.13.207.197) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 07 Aug 2009 13:40:10 +0000 Received: from localhost (hagrid.ecoscentric.com [127.0.0.1]) by mail.ecoscentric.com (Postfix) with ESMTP id 50A582F78003; Fri, 7 Aug 2009 14:40:07 +0100 (BST) Received: from mail.ecoscentric.com ([127.0.0.1]) by localhost (hagrid.ecoscentric.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rqvQEfif9gLH; Fri, 7 Aug 2009 14:40:04 +0100 (BST) Date: Fri, 07 Aug 2009 13:40:00 -0000 Message-Id: From: Bart Veer To: John Dallaway CC: uwe.kindler@cetoni.de, ecos-devel@sourceware.org In-reply-to: <4A7C1841.6070900@dallaway.org.uk> (message from John Dallaway on Fri, 07 Aug 2009 13:04:17 +0100) Subject: Re: Strange __cxa_pure_virtual problem References: <4A7C118C.20200@cetoni.de> <4A7C1841.6070900@dallaway.org.uk> Mailing-List: contact ecos-devel-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: ecos-devel-owner@ecos.sourceware.org X-SW-Source: 2009-08/txt/msg00004.txt.bz2 >>>>> "John" == John Dallaway writes: John> Hi Uwe (and Bart) John> Bart, do you have any ideas why your implementation of John> __cxa_pure_virtual() in CYGPKG_INFRA might be ignored? It is not necessarily being ignored. The eCos version of __cxa_pure_virtual() ends up in libtarget.a, which is part of the same linker script GROUP() as libsupc++.a. So strictly speaking the linker is perfectly at liberty to choose one or the other. Normally I would expect it to pick whichever it came across first while reading in the library archives, which would mean the eCos libtarget.a one. I have no idea why changing the compiler optimization level would affect the linker behaviour. A couple of points: 1) __cxa_pure_virtual() is actually pretty useless, except possibly as a debugging tool. It is intend to catch the case where application code calls a virtual function for an object that is still being constructed, Ideally its use could be suppressed at compile-time, but even if we submitted a compiler patch for this it would not help any time soon. 2) it might be possible to fix the problem in the linker by making the library search order more deterministic. If the linker is not going to be deterministic about this then it should probably issue a warning about ambiguous duplicate definitions in libraries. Again that is not going to help anytime soon. 3) arguably __cxa_pure_virtual() should have been removed from libsupc++ in the prebuilt toolchains. But we don't want to respin toolchains for this, and anyway that would not help with the synthetic target where we want people to be able to use the existing Linux toolchain whenever possible. 4) since __cxa_pure_virtual() should never get called in correctly written code we could have a dummy symbol definition at an invalid location. That is what -Wl,--defsym -Wl,__cxa_pure_virtual=0 achieves, it tells the linker that __cxa_pure_virtual() can be found at location 0x0. The same could be achieved in the linker script. But 0x0 may not always be a sensible NULL location, some targets may have real code there. Plus, we don't want to start messing about with the linker flags for all targets, nor the linker scripts for all architectures and possibly all targets. So, I think there is one solution (untested) that may work: ---------------------------------------------------------------------------- 2009-08-07 Bart Veer * cdl/infra.cdl: move __cxa_pure_virtual() into extras.o to prevent linker ambiguity with the libsupc++ version. Index: cdl/infra.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/infra/current/cdl/infra.cdl,v retrieving revision 1.18 diff -u -p -r1.18 infra.cdl --- cdl/infra.cdl 29 Jan 2009 17:49:44 -0000 1.18 +++ cdl/infra.cdl 7 Aug 2009 13:30:03 -0000 @@ -59,7 +59,8 @@ cdl_package CYGPKG_INFRA { compile startup.cxx prestart.cxx pkgstart.cxx userstart.cxx \ dummyxxmain.cxx null.cxx simple.cxx fancy.cxx buffer.cxx \ diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx eprintf.c \ - pure.cxx gccsupport.cxx + gccsupport.cxx + compile -library=libextras.a pure.cxx # ==================================================================== ---------------------------------------------------------------------------- Basically this moves pure.cxx from libtarget.a to libextras.a/extras.o. That means the eCos version will be part of a .o file so will automatically be part of the executable with no need for searching libraries, so the libsupc++ version will never be considered. If __cxa_pure_virtual() is never used then linker garbage collection should take care of it. The disadvantage is that any dependencies of __cxa_pure_virtual() will get resolved before linker garbage collection takes place, so if any of those dependencies involve C++ static constructors or anything else covered by a linker script KEEP() then we have added bloat to the system. Looking at the current implementation: ---------------------------------------------------------------------------- extern "C" void __cxa_pure_virtual(void) { CYG_FAIL("attempt to use a virtual function before object has been constructed"); for ( ; ; ); } ---------------------------------------------------------------------------- in a production build (CYGDBG_USE_ASSERTS disabled) CYG_FAIL() maps to CYG_EMPTY_STATEMENT so no problem there. In a debug build we are likely to pull in cyg_assert_msg() and cyg_assert_fail(), which means all of diag_printf() and its dependencies. That is not actually too serious. For anything except a minimal configuration there should be other asserts in the system so those functions will get pulled in anyway. However, for a minimal debug configuration we may have bloated the system. We need to consider whether that is acceptable, or whether we should remove the CYG_FAIL() line from the function - given that __cxa_pure_virtual() serves little purpose anyway. This assumes moving pure.cxx to libextras.a fixes the problem. Hopefully somebody will try this in the near future. Bart -- Bart Veer eCos Configuration Architect eCosCentric Limited The eCos experts http://www.ecoscentric.com/ Barnwell House, Barnwell Drive, Cambridge, UK. Tel: +44 1223 245571 Registered in England and Wales: Reg No 4422071.