MIPS: Fix sibling call handling in get_frame_info
authorTony Wu <tung7970@gmail.com>
Sun, 12 May 2013 15:04:29 +0000 (15:04 +0000)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 17 May 2013 18:59:28 +0000 (20:59 +0200)
commite7438c4b893e87311d2fb0facb3e6a0df17abe01
tree042fe9b7e10dc9e00181bc41f99e900f8f2b5b99
parentd552b233f692416d63bb93eb35bf24e5c95c7e0b
MIPS: Fix sibling call handling in get_frame_info

Given a function, get_frame_info() analyzes its instructions
to figure out frame size and return address. get_frame_info()
works as follows:

1. analyze up to 128 instructions if the function size is unknown
2. search for 'addiu/daddiu sp,sp,-immed' for frame size
3. search for 'sw ra,offset(sp)' for return address
4. end search when it sees jr/jal/jalr

This leads to an issue when the given function is a sibling
call, example shown as follows.

801ca110 <schedule>:
801ca110:       8f820000        lw      v0,0(gp)
801ca114:       8c420000        lw      v0,0(v0)
801ca118:       080726f0        j       801c9bc0 <__schedule>
801ca11c:       00000000        nop

801ca120 <io_schedule>:
801ca120:       27bdffe8        addiu   sp,sp,-24
801ca124:       3c028022        lui     v0,0x8022
801ca128:       afbf0014        sw      ra,20(sp)

In this case, get_frame_info() cannot properly detect schedule's
frame info, and eventually returns io_schedule's instead.

This patch adds 'j' to the end search condition to workaround
sibling call cases.

Signed-off-by: Tony Wu <tung7970@gmail.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/5236/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/kernel/process.c