linux/arch/mips/kernel/mcount.S
<<
>>
Prefs
   1/*
   2 * MIPS specific _mcount support
   3 *
   4 * This file is subject to the terms and conditions of the GNU General Public
   5 * License.  See the file "COPYING" in the main directory of this archive for
   6 * more details.
   7 *
   8 * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
   9 * Copyright (C) 2010 DSLab, Lanzhou University, China
  10 * Author: Wu Zhangjin <wuzhangjin@gmail.com>
  11 */
  12
  13#include <asm/export.h>
  14#include <asm/regdef.h>
  15#include <asm/stackframe.h>
  16#include <asm/ftrace.h>
  17
  18        .text
  19        .set noreorder
  20        .set noat
  21
  22        .macro MCOUNT_SAVE_REGS
  23        PTR_SUBU        sp, PT_SIZE
  24        PTR_S   ra, PT_R31(sp)
  25        PTR_S   AT, PT_R1(sp)
  26        PTR_S   a0, PT_R4(sp)
  27        PTR_S   a1, PT_R5(sp)
  28        PTR_S   a2, PT_R6(sp)
  29        PTR_S   a3, PT_R7(sp)
  30#ifdef CONFIG_64BIT
  31        PTR_S   a4, PT_R8(sp)
  32        PTR_S   a5, PT_R9(sp)
  33        PTR_S   a6, PT_R10(sp)
  34        PTR_S   a7, PT_R11(sp)
  35#endif
  36        .endm
  37
  38        .macro MCOUNT_RESTORE_REGS
  39        PTR_L   ra, PT_R31(sp)
  40        PTR_L   AT, PT_R1(sp)
  41        PTR_L   a0, PT_R4(sp)
  42        PTR_L   a1, PT_R5(sp)
  43        PTR_L   a2, PT_R6(sp)
  44        PTR_L   a3, PT_R7(sp)
  45#ifdef CONFIG_64BIT
  46        PTR_L   a4, PT_R8(sp)
  47        PTR_L   a5, PT_R9(sp)
  48        PTR_L   a6, PT_R10(sp)
  49        PTR_L   a7, PT_R11(sp)
  50#endif
  51        PTR_ADDIU       sp, PT_SIZE
  52        .endm
  53
  54        .macro RETURN_BACK
  55        jr ra
  56         move ra, AT
  57        .endm
  58
  59/*
  60 * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass
  61 * the location of the parent's return address.
  62 */
  63#define MCOUNT_RA_ADDRESS_REG   $12
  64
  65#ifdef CONFIG_DYNAMIC_FTRACE
  66
  67NESTED(ftrace_caller, PT_SIZE, ra)
  68        .globl _mcount
  69_mcount:
  70EXPORT_SYMBOL(_mcount)
  71        b       ftrace_stub
  72#ifdef CONFIG_32BIT
  73         addiu sp,sp,8
  74#else
  75         nop
  76#endif
  77
  78        /* When tracing is activated, it calls ftrace_caller+8 (aka here) */
  79        MCOUNT_SAVE_REGS
  80#ifdef KBUILD_MCOUNT_RA_ADDRESS
  81        PTR_S   MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
  82#endif
  83
  84        PTR_SUBU a0, ra, 8      /* arg1: self address */
  85        PTR_LA   t1, _stext
  86        sltu     t2, a0, t1     /* t2 = (a0 < _stext) */
  87        PTR_LA   t1, _etext
  88        sltu     t3, t1, a0     /* t3 = (a0 > _etext) */
  89        or       t1, t2, t3
  90        beqz     t1, ftrace_call
  91         nop
  92#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
  93        PTR_SUBU a0, a0, 16     /* arg1: adjust to module's recorded callsite */
  94#else
  95        PTR_SUBU a0, a0, 12
  96#endif
  97
  98        .globl ftrace_call
  99ftrace_call:
 100        nop     /* a placeholder for the call to a real tracing function */
 101         move   a1, AT          /* arg2: parent's return address */
 102
 103#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 104        .globl ftrace_graph_call
 105ftrace_graph_call:
 106        nop
 107         nop
 108#endif
 109
 110        MCOUNT_RESTORE_REGS
 111        .globl ftrace_stub
 112ftrace_stub:
 113        RETURN_BACK
 114        END(ftrace_caller)
 115
 116#else   /* ! CONFIG_DYNAMIC_FTRACE */
 117
 118NESTED(_mcount, PT_SIZE, ra)
 119EXPORT_SYMBOL(_mcount)
 120        PTR_LA  t1, ftrace_stub
 121        PTR_L   t2, ftrace_trace_function /* Prepare t2 for (1) */
 122        beq     t1, t2, fgraph_trace
 123         nop
 124
 125        MCOUNT_SAVE_REGS
 126
 127        move    a0, ra          /* arg1: self return address */
 128        jalr    t2              /* (1) call *ftrace_trace_function */
 129         move   a1, AT          /* arg2: parent's return address */
 130
 131        MCOUNT_RESTORE_REGS
 132
 133fgraph_trace:
 134#ifdef  CONFIG_FUNCTION_GRAPH_TRACER
 135        PTR_LA  t1, ftrace_stub
 136        PTR_L   t3, ftrace_graph_return
 137        bne     t1, t3, ftrace_graph_caller
 138         nop
 139        PTR_LA  t1, ftrace_graph_entry_stub
 140        PTR_L   t3, ftrace_graph_entry
 141        bne     t1, t3, ftrace_graph_caller
 142         nop
 143#endif
 144
 145#ifdef CONFIG_32BIT
 146        addiu sp, sp, 8
 147#endif
 148
 149        .globl ftrace_stub
 150ftrace_stub:
 151        RETURN_BACK
 152        END(_mcount)
 153
 154#endif  /* ! CONFIG_DYNAMIC_FTRACE */
 155
 156#ifdef CONFIG_FUNCTION_GRAPH_TRACER
 157
 158NESTED(ftrace_graph_caller, PT_SIZE, ra)
 159#ifndef CONFIG_DYNAMIC_FTRACE
 160        MCOUNT_SAVE_REGS
 161#endif
 162
 163        /* arg1: Get the location of the parent's return address */
 164#ifdef KBUILD_MCOUNT_RA_ADDRESS
 165#ifdef CONFIG_DYNAMIC_FTRACE
 166        PTR_L   a0, PT_R12(sp)
 167#else
 168        move    a0, MCOUNT_RA_ADDRESS_REG
 169#endif
 170        bnez    a0, 1f  /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */
 171         nop
 172#endif
 173        PTR_LA  a0, PT_R1(sp)   /* leaf func: the location in current stack */
 1741:
 175
 176        /* arg2: Get self return address */
 177#ifdef CONFIG_DYNAMIC_FTRACE
 178        PTR_L   a1, PT_R31(sp)
 179#else
 180        move    a1, ra
 181#endif
 182
 183        /* arg3: Get frame pointer of current stack */
 184#ifdef CONFIG_64BIT
 185        PTR_LA  a2, PT_SIZE(sp)
 186#else
 187        PTR_LA  a2, (PT_SIZE+8)(sp)
 188#endif
 189
 190        jal     prepare_ftrace_return
 191         nop
 192        MCOUNT_RESTORE_REGS
 193#ifndef CONFIG_DYNAMIC_FTRACE
 194#ifdef CONFIG_32BIT
 195        addiu sp, sp, 8
 196#endif
 197#endif
 198        RETURN_BACK
 199        END(ftrace_graph_caller)
 200
 201        .align  2
 202        .globl  return_to_handler
 203return_to_handler:
 204        PTR_SUBU        sp, PT_SIZE
 205        PTR_S   v0, PT_R2(sp)
 206
 207        jal     ftrace_return_to_handler
 208         PTR_S  v1, PT_R3(sp)
 209
 210        /* restore the real parent address: v0 -> ra */
 211        move    ra, v0
 212
 213        PTR_L   v0, PT_R2(sp)
 214        PTR_L   v1, PT_R3(sp)
 215        jr      ra
 216         PTR_ADDIU      sp, PT_SIZE
 217#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 218
 219        .set at
 220        .set reorder
 221