How get constructors to run? (arm-elf)

Chris Houghton at Astrometric Instruments, Inc. houghton@astrometric.com
Wed Feb 19 19:41:00 GMT 2003


Hello all,

I've managed to get what I've seen referred to as a "bare bones" build 
targeted for an Atmel AT91 chip (using gcc 2.95.2 built for arm-elf) MOSTLY 
working.  Thanks to all on the list (I've been lurking and taking-up all 
the good advice ;>).

However, I am stuck with a problem that I can't get the constructors to run 
in my C++ program.  I found the following suggestion from Bill Gatliff in 
the archives:

 > .ctor and .dtor are function pointer tables.
 >
 > To see how they work, compile any C++ module that has global object
 > instantiations in it, and look at the assembly language.  In general,
 > what happens is (at least for the PPC EABI target) the compiler
 > generates a function that contains a "this" pointer for the global
 > object, and a call to the object's constructor.
 >
 > .ctor and .dtor are lists of pointers to these functions.  For the
 > EABI target, putting them in ROM is ok.
 >
 > Here's a snipped from some of my ppc-eabi startup code, that you may
 > find illustrative:
 >
 >
 > /* a symbol created by the linker, resides at the start of .ctor. */
 > extern void (*__CTOR_LIST__[])(void);
 >
 > /* the end of .ctor */
 > extern void (*__CTOR_END__[])(void);
 >
 > /*
 >   Invokes constructors by walking through
 >   all the function pointers in the .ctor section.
 > */
 > void __eabi_ctors ( void )
 > {
 >   int wctor;
 >   int nctor = __CTOR_END__ - __CTOR_LIST__;
 >
 >
 >   for( wctor = 0; wctor < nctor; wctor++ )
 >     (*(__CTOR_LIST__[wctor]))();
 >
 >   return;
 > }

Thanks Bill!  I put the code in my __gccmain.

However there is a problem with it for me: it doesn't work.

My code DOES call the function whose address is in the ctors list but this 
function is a compiler-generated routine called _GLOBAL_.I.ClientInChar 
(discovered with objdump -D) which then calls another compiler-generated 
routine called __static_initialization_and_destruction_0 which has buried 
within a bl (ARM branch-link) to my constructor.  But it branches past the 
branch-link and never actually calls my constructor.

Perhaps it requires some arguments and not just (void) for a parameter list?

Here's the dissassembly with the bl to my constructor at 564 and 56e.  I 
actually have two instances of the object and I suspect that the two calls 
are with the respective "this" pointers for my two instances.  The two 
"this" pointers being at 5cc and 5d0 in the bss section.  It even looks 
like the below code would initialize  locations 5cc and 5do but it branches 
and returns at location 550 when I stepi through the code in gdb.  Again, 
are there parameters that I should be passing in?

<---------------------------- Best with window at least this wide 
----------------------------------->

00000528 <__static_initialization_and_destruction_0>:
  528:	e1a0c00d 	mov	r12, sp
  52c:	e92dd800 	stmdb	sp!, {r11, r12, lr, pc}
  530:	e24cb004 	sub	r11, r12, #4	; 0x4
  534:	e24dd008 	sub	sp, sp, #8	; 0x8
  538:	e50b0010 	str	r0, [r11, -#16]
  53c:	e50b1014 	str	r1, [r11, -#20]
  540:	e51b3014 	ldr	r3, [r11, -#20]
  544:	e3a02cff 	mov	r2, #65280	; 0xff00
  548:	e28220ff 	add	r2, r2, #255	; 0xff
  54c:	e1530002 	cmp	r3, r2
  550:	1a000007 	bne	574 <__static_initialization_and_destruction_0+0x4c>
  554:	e51b3010 	ldr	r3, [r11, -#16]
  558:	e3530000 	cmp	r3, #0	; 0x0
  55c:	0a000004 	beq	574 <__static_initialization_and_destruction_0+0x4c>
  560:	e59f0014 	ldr	r0, [pc, #14]	; 57c 
<__static_initialization_and_destruction_0+0x54>
  564:	ebffffa0 	bl	3ec <__4ATCL>
  568:	e59f0010 	ldr	r0, [pc, #10]	; 580 
<__static_initialization_and_destruction_0+0x58>
  56c:	ebffff9e 	bl	3ec <__4ATCL>
  570:	eaffffff 	b	574 <__static_initialization_and_destruction_0+0x4c>
  574:	ea000002 	b	584 <__static_initialization_and_destruction_0+0x5c>
  578:	ea000001 	b	584 <__static_initialization_and_destruction_0+0x5c>
  57c:	000005cc 	andeq	r0, r0, r12, asr #11
  580:	000005d0 	ldreqd	r0, [r0], -r0
  584:	e91ba800 	ldmdb	r11, {r11, sp, pc}

In short: just trying to get constructors for static objects called.  I 
only use static objects so that I can avoid memory allocation and 
libraries, etc.

TIA for any help on this!


Chris Houghton
Astrometric Instruments, Inc.
Advanced telescope control systems
http://www.astrometric.com


------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com



More information about the crossgcc mailing list