http://gcc.gnu.org/onlinedocs/gccint/In ... ation.html says that the list starts and ends with a non-function-pointer value. The examples don't skip them.
It seems unlikely to me that there would be a bug in a bare bones, since (I assume) they're the most view articles. Is the GCC documentation wrong?
Bug in C++ bare bones ctor/dtor examples?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Bug in C++ bare bones ctor/dtor examples?
As far as I can tell, it's an implementation detail. I define crtbegin.asm/crtend.asm as just a bunch of labels, which is something that not all linkers of all time might have liked. It would explain why there would be a necessity for leading and trailing "garbage". I couldn't be bothered however to locate the source for the crtbegin/crtend linux uses to see what's actually being put there.
In any case, barebones doesn't need it, I don't need it, you may find no reason to need it either.
In any case, barebones doesn't need it, I don't need it, you may find no reason to need it either.
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: Bug in C++ bare bones ctor/dtor examples?
I guess one can easily test whether gcc produces this "garbage" by having a look at the contents of the ctor/dtor lists. No matter whether it is necessary for one kernel or not for another - if it is present, one must be careful not to call something that is not a constructor. According to the gcc docs,
So it seems that there is indeed a bug in the barebones tutorial. However, I wonder why nobody has noticed it yet... Calling some invalid address right at the beginning of any kernel code should almost inevitably lead to a triple fault.
I don't use global C++ objects in my kernel, so it would take me some time to write some simple test code, but I remember that I once worked on an OS named Trion, which actually relied on the first entry of the ctor/dtor list being the number of ctors/dtors, as you can see from this code:gcc wrote:Each list always begins with an ignored function pointer (which may hold 0, −1, or a count of the function pointers after it, depending on the environment). This is followed by a series of zero or more function pointers to constructors (or destructors), followed by a function pointer containing zero.
Code: Select all
// Walk and call the constructors in the ctor_list
void ExecuteConstructors(void)
{
// Get a copy of the contructor list
void (**constructor)(void) = &ctorStart;
// The constructor list first contains an integer
// containing the number of ctors, and then the
// actual list begins...
int total = *(int *)constructor;
constructor++ ;
while(total--)
{
(*constructor)() ;
constructor++ ;
}
}
void ExecuteDestructors(void)
{
void (**deconstructor)(void) = &dtorStart;
int total = *(int *)deconstructor ;
deconstructor++ ;
while(total--)
{
(*deconstructor)() ;
deconstructor++ ;
}
}
Last edited by xenos on Mon Jan 31, 2011 4:25 am, edited 1 time in total.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Bug in C++ bare bones ctor/dtor examples?
The "garbage" comes from a combination of crtbegin.o/crtend.o and your system's linker script, and is therefore only present if you add it there.
Barebones is not wrong.
Edit: The stock crosscompiler does not have this behaviour either.
Barebones is not wrong.
Edit: The stock crosscompiler does not have this behaviour either.
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: Bug in C++ bare bones ctor/dtor examples?
It took me quite a while how this "garbage" gets into the Trion kernel, which does not refer to crtbegin.o/crtend.o at all. I just had a look at the Trion kernel binary and I found the following contents (translated to asm code):
So indeed the ctor/dtor list are preceded by their lengths, and followed by a zery dword. But in this case it is not surprising because these values are generated in the linker script!
I also had a look at crtbegin.o and crtend.o and both of them contain a single dword in the .ctors and .dtors sections - so I suppose that this is where the "garbage" comes from when these files are linked into the output binary. Another look at crtstuff.c and libgcc2.c from the gcc sources revealed that they actually rely on the presence of the "garbage" when they traverse the ctor/dtor lists.
However, as Combuster correctly explained, the "garbage" is not included by default by a plain cross compiler and (in general) not needed in an OS kernel, so the barebones example is correct.
Code: Select all
ctorStart:
dd 0x02
dd 0x103bf0
dd 0x105fa0
dd 0x00
ctorEnd:
dtorStart:
dd 0x01
dd 0x105fc0
dd 0x00
dtorEnd:
Code: Select all
SECTIONS {
.text 0x00100000 :{
textStart = .;
*(.text)
*(.text.*)
*(.stub)
*(.rodata*)
*(.gnu.linkonce.t.*)
*(.gnu.linkonce.r.*)
*(.gcc_except_table)
*(.eh_frame)
}
textEnd = .;
.data :{
ctorStart = .;
LONG((ctorEnd - ctorStart) / 4 - 2)
*(.ctors)
LONG(0) ctorEnd = .;
dtorStart = .;
LONG((dtorEnd - dtorStart) / 4 - 2)
*(.dtors)
LONG(0) dtorEnd = .;
*(.data*)
*(.gnu.linkonce.d.*)
}
dataEnd = .;
.bss :{
*(.common)
*(.bss*)
*(.gnu.linkonce.b.*)
}
bssEnd = .;
}
However, as Combuster correctly explained, the "garbage" is not included by default by a plain cross compiler and (in general) not needed in an OS kernel, so the barebones example is correct.
Re: Bug in C++ bare bones ctor/dtor examples?
Okay. That clears it up.
I wasn't concerned by the fact it wasn't there, I was just concerned that if it was there, it would screw stuff up, obviously. I didn't know this "feature" isn't enabled by default for cross compilers. But, since it's not there, there's no reason to care.
Thanks.
I wasn't concerned by the fact it wasn't there, I was just concerned that if it was there, it would screw stuff up, obviously. I didn't know this "feature" isn't enabled by default for cross compilers. But, since it's not there, there's no reason to care.
Thanks.