On Feb 16, 2011, at 5:08 PM, David Daney wrote: > On 02/16/2011 01:44 PM, Paul Koning wrote: >> I'm running into a crash caused by mishandling of address calculation of an >> array element address when that array is near the bottom of kseg0 >> (0xffffffff80000000). >> >> The code essentially does this >> foo = v[i - 2].elem; >> where i is current zero. >> >> Assume for now the negative array offset is valid -- data structure elements >> in question exist to both sides of the label "v". >> >> The generated code looks like this: >> >> /* i is in v0 */ >> addiu v0, -2 >> sll v0, 3 >> lui v1, 0x8000 >> addu v0, v1 >> lbu a1, 7110(v0) >> >> What's going on here is that&v[0].elem is 0xfffffffff80007110. The >> reference is valid -- array elements are 8 bytes so element -2 is still in >> kseg0. >> >> However, the addu produces value 0000000007ffffff0 in v0 -- the result of >> adding -16 to the 32 bit value 0x800000000. >> >> Given that I have an ABI with 64 bit registers -- even though it has 32 bit >> pointers -- I would say the address adjustment should have been done with >> daddu; if that had been done I would have gotten the correct address. >> >> GCC is 4.5.1, NetBSD target. >> > > This is why it is a bad idea to place anything in the 2^16 byte region > centered on the split. > > The Linux kernel works around this by not using the lower 32kb of ckseg0. It > also never user the top 32kb of useg when in 32bit mode.
Ok, so are you suggesting I have to modify my kernel in order to work around this compiler bug? paul