Skip to content
  • Wu Zhangjin's avatar
    MIPS: Tracing: Add function graph tracer support for MIPS · 29c5d346
    Wu Zhangjin authored
    
    
    The implementation of function graph tracer for MIPS is a little
    different from X86.
    
    in MIPS, gcc(with -pg) only transfer the caller's return address(at) and
    the _mcount's return address(ra) to us.
    
    For the kernel part without -mlong-calls:
    
    move at, ra
    jal _mcount
    
    For the module part with -mlong-calls:
    
    lui v1, hi16bit_of_mcount
    addiu v1, v1, low16bit_of_mcount
    move at, ra
    jal _mcount
    
    Without -mlong-calls,
    
    if the function is a leaf, it will not save the return address(ra):
    
    ffffffff80101298 <au1k_wait>:
    ffffffff80101298:       67bdfff0        daddiu  sp,sp,-16
    ffffffff8010129c:       ffbe0008        sd      s8,8(sp)
    ffffffff801012a0:       03a0f02d        move    s8,sp
    ffffffff801012a4:       03e0082d        move    at,ra
    ffffffff801012a8:       0c042930        jal     ffffffff8010a4c0 <_mcount>
    ffffffff801012ac:       00020021        nop
    
    so, we can hijack it directly in _mcount, but if the function is non-leaf, the
    return address is saved in the stack.
    
    ffffffff80133030 <copy_process>:
    ffffffff80133030:       67bdff50        daddiu  sp,sp,-176
    ffffffff80133034:       ffbe00a0        sd      s8,160(sp)
    ffffffff80133038:       03a0f02d        move    s8,sp
    ffffffff8013303c:       ffbf00a8        sd      ra,168(sp)
    ffffffff80133040:       ffb70098        sd      s7,152(sp)
    ffffffff80133044:       ffb60090        sd      s6,144(sp)
    ffffffff80133048:       ffb50088        sd      s5,136(sp)
    ffffffff8013304c:       ffb40080        sd      s4,128(sp)
    ffffffff80133050:       ffb30078        sd      s3,120(sp)
    ffffffff80133054:       ffb20070        sd      s2,112(sp)
    ffffffff80133058:       ffb10068        sd      s1,104(sp)
    ffffffff8013305c:       ffb00060        sd      s0,96(sp)
    ffffffff80133060:       03e0082d        move    at,ra
    ffffffff80133064:       0c042930        jal     ffffffff8010a4c0 <_mcount>
    ffffffff80133068:       00020021        nop
    
    but we can not get the exact stack address(which saved ra) directly in
    _mcount, we need to search the content of at register in the stack space
    or search the "s{d,w} ra, offset(sp)" instruction in the text. 'Cause we
    can not prove there is only a match in the stack space, so, we search
    the text instead.
    
    as we can see, if the first instruction above "move at, ra" is not a
    store instruction, there should be a leaf function, so we hijack the at
    register directly via putting &return_to_handler into it, otherwise, we
    search the "s{d,w} ra, offset(sp)" instruction to get the stack offset,
    and then the stack address. we use the above copy_process() as an
    example, we at last find "ffbf00a8", 0xa8 is the stack offset, we plus
    it with s8(fp), that is the stack address, we hijack the content via
    writing the &return_to_handler in.
    
    If with -mlong-calls, since there are two more instructions above "move
    at, ra", so, we can move the pointer to the position above "lui v1,
    hi16bit_of_mcount".
    
    Signed-off-by: default avatarWu Zhangjin <wuzhangjin@gmail.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Nicholas Mc Guire <der.herr@hofr.at>
    Cc: zhangfx@lemote.com
    Cc: Wu Zhangjin <wuzhangjin@gmail.com>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Frederic Weisbecker <fweisbec@gmail.com>
    Cc: linux-kernel@vger.kernel.org
    Cc: linux-mips@linux-mips.org
    Patchwork: http://patchwork.linux-mips.org/patch/677/
    
    
    Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
    29c5d346