This is the mail archive of the 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 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.

David Daney.

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