Mon 07 Aug 2006 04:27:10 AM UTC, comment #1:
GCC gets smarter and smarter... When seeing this:
struct pseudo_descriptor
{
short pad;
unsigned short limit;
unsigned long linear_base;
}
MACH_INLINE void lgdt(struct pseudo_descriptor *pdesc)
{
__asm volatile("lgdt %0" : : "m" (pdesc->limit));
}
gdt_init() {
...
{
struct pseudo_descriptor pdesc;
pdesc.limit = sizeof(gdt)-1;
pdesc.linear_base = kvtolin(&gdt);
lgdt(&pdesc);
}
}
, it understands that filling the linear_base field is not needed, since we only give the limit field to the asm statement... The result it this:
gcc 4.0:
<gdt_init+102>: movw $0x57,0xfffffffa(%ebp)
<gdt_init+108>: movl $0xc0000000,0xfffffffc(%ebp)
<gdt_init+115>: lgdtl 0xfffffffa(%ebp)
gcc 4.1:
<gdt_init+102>: movw $0x57,0xfffffffa(%ebp)
<gdt_init+108>: lgdtl 0xfffffffa(%ebp)
it doesn't fill the linear_base field!
There are two possible fixes, that I'll attach:
- reorder the structure, pack it, and give it as a whole to the asm statement.
- clobber memory in the asm statement.
My preference goes to the first, since it explains to gcc what we exactly want. That supposes the support of the "packed" attribute, however.
|