Re: ftrace for MIPS

From: Wu Zhangjin
Date: Tue Oct 20 2009 - 11:31:26 EST


added CC to linux-mips and lkml.

> On Tue, 2009-10-20 at 07:39 +0800, Wu Zhangjin wrote:
>
> > 3. to handle the non-leaf function(hijack the return address), we need
> > to get the stack address of the return address, but it's not easy to get
> > it in MIPS, search the return address in the stack space is not
> > reliable, searching the text is dangerous(pagefault..., have tried
> > probe_kernel_read(), just hang there!), so, a clean solution maybe
> > hacking gcc via pushing ra to 0(sp) or another "fixed"(fixed offset)
> > stack address or recording the offset and transfer it to _mcount.
>
> Have you figured out why you can't find the text? If mcount is called,
> you most definitely must have stored ra somewhere.
>
> As for the hang with probe kernel read, I wonder if you need to disable
> tracing before using it. Or at least have a way not to recurs. I'm
> looking at probe_kernel_read, and it looks like it would also be traced.
>
> Looking at x86 and powerpc, we hand do the probing.
>

Just added tracing_stop() and tracing_start() around
probe_kernel_read(), it works(not hang again), and i can get the stack
address of the ra register(return address) now, but failed when trying
to hijack the return address via writing &return_to_handler in the stack
address:

I can write hijack some of the addresses, but failed with this error at
last:

Unable to handle kernel paging request at 0000000000000000, epc =
0000000000000000, ra = 000000000000.

Need to check which registers is missing when saving/restoring for
_mcount:


NESTED(ftrace_graph_caller, PT_SIZE, ra)
MCOUNT_SAVE_REGS
PTR_S v0, PT_R2(sp)

MCOUNT_SET_ARGS
jal prepare_ftrace_return
nop

/* overwrite the parent as &return_to_handler: v0 -> $1(at) */
move $1, v0

PTR_L v0, PT_R2(sp)
MCOUNT_RESTORE_REGS
RETURN_BACK
END(ftrace_graph_caller)

.align 2
.globl return_to_handler
return_to_handler:
PTR_SUBU sp, PT_SIZE
PTR_S v0, PT_R2(sp)

jal ftrace_return_to_handler
nop

/* restore the real parent address: v0 -> ra */
move ra, v0

PTR_L v0, PT_R2(sp)
PTR_ADDIU sp, PT_SIZE

jr ra

...

.macro MCOUNT_SAVE_REGS
PTR_SUBU sp, PT_SIZE
PTR_S ra, PT_R31(sp)
PTR_S AT, PT_R1(sp)
PTR_S a0, PT_R4(sp)
PTR_S a1, PT_R5(sp)
PTR_S a2, PT_R6(sp)
PTR_S a3, PT_R7(sp)
#ifdef CONFIG_64BIT
PTR_S a4, PT_R8(sp)
PTR_S a5, PT_R9(sp)
PTR_S a6, PT_R10(sp)
PTR_S a7, PT_R11(sp)
#endif
.endm

.macro MCOUNT_RESTORE_REGS
PTR_L ra, PT_R31(sp)
PTR_L AT, PT_R1(sp)
PTR_L a0, PT_R4(sp)
PTR_L a1, PT_R5(sp)
PTR_L a2, PT_R6(sp)
PTR_L a3, PT_R7(sp)
#ifdef CONFIG_64BIT
PTR_L a4, PT_R8(sp)
PTR_L a5, PT_R9(sp)
PTR_L a6, PT_R10(sp)
PTR_L a7, PT_R11(sp)
#endif
PTR_ADDIU sp, PT_SIZE

Regards,
Wu Zhangjin

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/