This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: MIPS: Trouble with address calculation near the useg/kseg boundary


On 02/16/2011 02:10 PM, Paul Koning wrote:

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?



What is the state of your C0_Status[{KX,SX,UX}] bits?


It is not really a compiler bug, but rather a defect in the n32 ABI. When using 32-bit pointers you can only do 32-bit operations on them. To do otherwise raises the possibility of generating addresses that fall outside of the allowed range.

But as you have found, there is this 64kb region centered on the split where behavior can become undefined.

The only real way to avoid it would be to prohibit GCC from generating non-zero offsets for load/store instructions, the resulting code would be slower and bigger than the current behavior of using the offsets in address calculations.

So to answer your question:

I think your 'compiler bug' is a false predicate. And yes, I do suggest that you modify your kernel.

David Daney.


paul





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]