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


Reply via email to