I'm seeing a crash in SPI because cyg_spi_at91_bus_init is
being invoked twice.

The problem is that SPI is using *both* the old style C++
constructors as well as the new C global constructors.

In cyg_type.h, CYGBLD_ATTRIB_C_INIT_PRI is only defined
for C files, so the C++ file will build the C++ constructors as well.

My first attempt at fixing this failed, because linker garbage
collection will toss out cyg_spi_at91_bus_init() when there is
no reference to it. Apparently a C global constructor is not
a reference that the linker takes into account...

My next attempt will be to remove the usage of the C constructor
in spi_at91.c. It's the *ONLY* place it is used in the entire eCos.
Wouldn't it be better to wait until there is some clean fix for this?

Is there a GCC attribute to mark a fn as KEEP() or does this
require diving into the linker script?

Using built-in specs.
Target: arm-eabi
Configured with: /home/test/src/toolchains/gcc/gcc-4.3.2/configure -v
--target=arm-eabi --prefix=/home/test/build/toolchains/arm-eabi/tools
--with-newlib --with-gnu-as --with-gnu-ld --enable-languages=c,c++
--disable-__cxa_atexit --enable-threads
--with-bugurl=http://bugs.ecos.sourceware.org/
--with-pkgversion='eCosCentric GNU tools 4.3.2-sw' --with-cpu=arm7tdmi
--with-gmp=/opt/gmp-4.2.2 --with-mpfr=/opt/mpfr-2.3.0
Thread model: single
gcc version 4.3.2 (eCosCentric GNU tools 4.3.2-sw)


-- 
Øyvind Harboe
US toll free 1-866-980-3434 / International +47 51 63 25 00
http://www.zylin.com/zy1000.html
ARM7 ARM9 ARM11 XScale Cortex
JTAG debugger and flash programmer
diff -r 0c51e5cb890a packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx
--- a/packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx  Fri Jul 16 
14:53:40 2010 +0000
+++ b/packages/devs/spi/arm/at91/current/src/spi_at91_init.cxx  Wed Aug 11 
21:59:27 2010 +0200
@@ -50,7 +50,7 @@
 
 // This file is not needed if we support CYGBLD_ATTRIB_C_INIT_PRI, as the
 // init happens directly in spi_at91.c then.
-#ifndef CYGBLD_ATTRIB_C_INIT_PRI
+#if !CYGBLD_HAS_ATTRIB_C_INIT()
 
 // -------------------------------------------------------------------------
 
diff -r 0c51e5cb890a packages/infra/current/include/cyg_type.h
--- a/packages/infra/current/include/cyg_type.h Fri Jul 16 14:53:40 2010 +0000
+++ b/packages/infra/current/include/cyg_type.h Wed Aug 11 21:59:27 2010 +0200
@@ -287,7 +287,11 @@
 #define CYGBLD_ATTRIB_INIT_BEFORE( _pri_ ) CYGBLD_ATTRIB_INIT_PRI(_pri_-100)
 #define CYGBLD_ATTRIB_INIT_AFTER( _pri_ )  CYGBLD_ATTRIB_INIT_PRI(_pri_+100)
 
-#if defined(__GNUC__) && !defined(__cplusplus) && (__GNUC_VERSION__ >= 40300)
+// From C++ we need to be able to tell if we have the init capability available
+// from C
+#define CYGBLD_HAS_ATTRIB_C_INIT() (defined(__GNUC__) && (__GNUC_VERSION__ >= 
40300))
+
+#if CYGBLD_HAS_ATTRIB_C_INIT() && !defined(__cplusplus)
 // Equivalents of the above for C functions, available from gcc 4.3 onwards.
 # define CYGBLD_ATTRIB_C_INIT_PRI( _pri_)       __attribute__((constructor 
(_pri_)))
 # define CYGBLD_ATTRIB_C_INIT_BEFORE( _pri_ )   __attribute__((constructor 
(_pri_-100)))
-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

Reply via email to