This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more information.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

How get constructors to run? (arm-elf)


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 at sources dot redhat dot com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]