Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get current PC register value on MIPS arch?

I'd like to do backtrace on MIPS. Then, I face one problem: how do I get the current PC register value, since it doesn't belong to 32 normal registers.. Thanks for your suggestion..

like image 751
Randy Avatar asked Mar 11 '13 04:03

Randy


3 Answers

Make a subroutine that looks somewhat like:

.text 
.globl GetIP 

GetIP:
move $v0, $ra
jr $ra

And then call the routine; it'll give you the address of the first instruction after the call.

like image 130
Zach Riggle Avatar answered Sep 20 '22 19:09

Zach Riggle


after a jal call it will be copied to the ra register... so you could store ra, then jal to the next line, read ra, restore ra.

like image 44
Grady Player Avatar answered Sep 18 '22 19:09

Grady Player


Although this question isn't tagged c, I figured it might be useful to share a solution utilizing inline assembly in gcc.

__attribute__((noinline)) static void *get_pc(void)
{
    void *pc;
    asm volatile ("move %0, $ra" : "=r"(pc));
    return pc;
}

Of course, the gist of the solution is the same as the currently accepted answer. Since the function is very small, it is a good candidate for inlining when optimization is turned on. However, if that function were inlined, its return value would be invalid : it would simply return some value of ra in the calling function, since a jal or jalr wouldn't be generated, and ra thus not set to the instruction following jal/jalr. This is why __attribute__((noinline)) is essential in this case.

like image 39
Daniel Kamil Kozar Avatar answered Sep 19 '22 19:09

Daniel Kamil Kozar