Calling C++ Constructors

All about the OSDev Wiki. Discussions about the organization and general structure of articles and how to use the wiki. Request changes here if you don't know how to use the wiki.
Post Reply
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Calling C++ Constructors

Post by AJ »

Hi,

I am looking at the C PlusPlus page, having just updated to GCC 4.3.0, specifically the 'Constructors' part, stating that global object constructors are found in the elf section 'ctors*', which is what I have always used. I used a construction function something along the following lines:

Code: Select all

void Construct()
{
	/*	construct global/static objects	*/
	void (**constructor)() = &start_ctors;
	void (**lastctor)() = &end_ctors;
	kprintf("Calling %#08x to %#08x\n", constructor, lastctor);
	if((constructor)>=(lastctor)) return;
	
	do
	{
		kprintf("Constructor (at %#08x) calling EIP %#08x\n", constructor, *constructor);
		(*constructor)();		
	}while((*++constructor)<(*lastctor));	
}
OK - I know it's messy, but I've just been playing around with it a lot. As you can see, I have added some debug output and I like my hex numbers padded :)

When compiling with G++ 4.3.0, the whole lot seems to be misaligned by a byte - in other words, I have to add one byte to 'start_ctors' in order to get things running. The value of the additional byte is zero. I am aware that GCC sometimes sets the first integer in the constructor list as the number of constructors present, but think that if it does this the integer should be a full 4 bytes?

Is there any reason why it should be exhibiting this new behaviour (my previous compiler was g++ 4.2.2 i586 elf - all that has changed is the version), or has something gone wrong with my linking?

Cheers,
Adam
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Hi,

Mine works on GCC 4.3.0 - we didn't have to make any changes so I suppose it's to do with your linking.

This is ours - it looks slightly different to yours...

Code: Select all

/// Calls the constructors for all global objects.
/// Call this before using any global objects.
void initialiseConstructors()
{
  // Constructor list is defined in the linker script.
  // The .ctors section is just an array of function pointers.
  // iterate through, calling each in turn.
  uintptr_t *iterator = reinterpret_cast<uintptr_t*>(&start_ctors);
  while (iterator < reinterpret_cast<uintptr_t*>(&end_ctors))
  {
    void (*fp)(void) = reinterpret_cast<void (*)(void)>(*iterator);
    fp();
    iterator++;
  }
}
Hope this helps,

James
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

OK, thanks - I'll dig deeper and see what I've done wrong. Your code certainly looks a better style to mine, even after you remove my debug rubbish!

I have been making a few stupid mistakes in my code recently, but the only change I can think I have made is the GCC update. I either need to get more sleep or have a break from my code for a few days and come back to it with fresh eyes :?

Cheers,
Adam
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Right - adjusting the location of the ctors and dtors lists in the link script solved the issue, but I'm still not happy - no idea why updating my toolchain should have caused the problem. This is especially the case because LD is part of binutils, of which I am still using the same version. There was obviously something slightly wrong that was just waiting to show itself with a slight compile-time change.

I hate it when I just have to cross my fingers and hope the problem doesn't arise again. Oh well :roll:

Cheers,
Adam
User avatar
kmcguire
Member
Member
Posts: 120
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post by kmcguire »

AJ wrote:I hate it when I just have to cross my fingers and hope the problem doesn't arise again. Oh well :roll:
You could always check the length of the section to make sure it is a multiple, and if not it would signify there is a problem and you could try the work around by adding one.
Post Reply