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