This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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: Bad MIPS address arithmetic


On 05/10/2010 02:17 PM, Paul Koning wrote:
I spotted this in binutils 2.18.

Given the source file:

foo:	ld	$v0,40000($sp)
	jr	$ra

The resulting code is:

	lui	v0, 1
	addu	v0, v0, sp
	jr	ra
	ld	v0, -25536(sp)

The problem is that this produces wrong addresses in machines with 64
bit registers, if the current sp is 0x7fff0000 or higher.  If so, the
addu produces 0xffffffff8000nnnn in v0, and the ld then references
0xffffffff7fffnnnn which is not likely to be a valid address.


Well things get tricky up there near the top of USEG. That is why the Linux kernel never places the stack in that region.


It seems that daddu rather than addu should be used here, for O64 (and
probably N32) ABIs.


This is what I get:


$ cat koning.s
foo:	ld	$v0,40000($sp)
	jr	$ra

$ mips64-linux-as --version
GNU assembler (GNU Binutils) 2.20
Copyright 2009 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `mips64-linux'.
$ mips64-linux-as -o koning.o koning.s
$ mips64-linux-objdump -d -r koning.o

koning.o: file format elf32-ntradbigmips


Disassembly of section .text:


00000000 <foo>:
   0:	3c020001 	lui	v0,0x1
   4:	005d1021 	addu	v0,v0,sp
   8:	03e00008 	jr	ra
   c:	dc429c40 	ld	v0,-25536(v0)

$ mips64-linux-as -mabi=32 -o koning.o koning.s
$ mips64-linux-objdump -d -r koning.o

koning.o: file format elf32-tradbigmips


Disassembly of section .text:


00000000 <foo>:
   0:	3c010001 	lui	at,0x1
   4:	03a10821 	addu	at,sp,at
   8:	8c229c40 	lw	v0,-25536(at)
   c:	8c239c44 	lw	v1,-25532(at)
  10:	03e00008 	jr	ra
  14:	00000000 	nop
	...

$ mips64-linux-as -mabi=64 -o koning.o koning.s
$ mips64-linux-objdump -d -r koning.o

koning.o: file format elf64-tradbigmips


Disassembly of section .text:


0000000000000000 <foo>:
   0:	3c020001 	lui	v0,0x1
   4:	005d102d 	daddu	v0,v0,sp
   8:	03e00008 	jr	ra
   c:	dc429c40 	ld	v0,-25536(v0)


So I think it is working as it was intended. For the default n32 ABI, the ADDU is the proper instruction to use for pointer arithmetic. Other ABIs do different things. If you want code for n64, you should specify that when invoking the assembler. You can also add '.set nomacro' if you don't want it to do these weird things.


In MIPS assembly, what you think is an instruction often isn't, the ABI and other things have a big influence.

David Daney


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