Question

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..

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top