LCOV - code coverage report
Current view: top level - include/linux - tracehook.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 3 4 75.0 %
Date: 2014-02-18 Functions: 0 0 -
Branches: 3 4 75.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Tracing hooks
       3                 :            :  *
       4                 :            :  * Copyright (C) 2008-2009 Red Hat, Inc.  All rights reserved.
       5                 :            :  *
       6                 :            :  * This copyrighted material is made available to anyone wishing to use,
       7                 :            :  * modify, copy, or redistribute it subject to the terms and conditions
       8                 :            :  * of the GNU General Public License v.2.
       9                 :            :  *
      10                 :            :  * This file defines hook entry points called by core code where
      11                 :            :  * user tracing/debugging support might need to do something.  These
      12                 :            :  * entry points are called tracehook_*().  Each hook declared below
      13                 :            :  * has a detailed kerneldoc comment giving the context (locking et
      14                 :            :  * al) from which it is called, and the meaning of its return value.
      15                 :            :  *
      16                 :            :  * Each function here typically has only one call site, so it is ok
      17                 :            :  * to have some nontrivial tracehook_*() inlines.  In all cases, the
      18                 :            :  * fast path when no tracing is enabled should be very short.
      19                 :            :  *
      20                 :            :  * The purpose of this file and the tracehook_* layer is to consolidate
      21                 :            :  * the interface that the kernel core and arch code uses to enable any
      22                 :            :  * user debugging or tracing facility (such as ptrace).  The interfaces
      23                 :            :  * here are carefully documented so that maintainers of core and arch
      24                 :            :  * code do not need to think about the implementation details of the
      25                 :            :  * tracing facilities.  Likewise, maintainers of the tracing code do not
      26                 :            :  * need to understand all the calling core or arch code in detail, just
      27                 :            :  * documented circumstances of each call, such as locking conditions.
      28                 :            :  *
      29                 :            :  * If the calling core code changes so that locking is different, then
      30                 :            :  * it is ok to change the interface documented here.  The maintainer of
      31                 :            :  * core code changing should notify the maintainers of the tracing code
      32                 :            :  * that they need to work out the change.
      33                 :            :  *
      34                 :            :  * Some tracehook_*() inlines take arguments that the current tracing
      35                 :            :  * implementations might not necessarily use.  These function signatures
      36                 :            :  * are chosen to pass in all the information that is on hand in the
      37                 :            :  * caller and might conceivably be relevant to a tracer, so that the
      38                 :            :  * core code won't have to be updated when tracing adds more features.
      39                 :            :  * If a call site changes so that some of those parameters are no longer
      40                 :            :  * already on hand without extra work, then the tracehook_* interface
      41                 :            :  * can change so there is no make-work burden on the core code.  The
      42                 :            :  * maintainer of core code changing should notify the maintainers of the
      43                 :            :  * tracing code that they need to work out the change.
      44                 :            :  */
      45                 :            : 
      46                 :            : #ifndef _LINUX_TRACEHOOK_H
      47                 :            : #define _LINUX_TRACEHOOK_H      1
      48                 :            : 
      49                 :            : #include <linux/sched.h>
      50                 :            : #include <linux/ptrace.h>
      51                 :            : #include <linux/security.h>
      52                 :            : #include <linux/task_work.h>
      53                 :            : struct linux_binprm;
      54                 :            : 
      55                 :            : /*
      56                 :            :  * ptrace report for syscall entry and exit looks identical.
      57                 :            :  */
      58                 :            : static inline int ptrace_report_syscall(struct pt_regs *regs)
      59                 :            : {
      60                 :            :         int ptrace = current->ptrace;
      61                 :            : 
      62                 :            :         if (!(ptrace & PT_PTRACED))
      63                 :            :                 return 0;
      64                 :            : 
      65                 :            :         ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
      66                 :            : 
      67                 :            :         /*
      68                 :            :          * this isn't the same as continuing with a signal, but it will do
      69                 :            :          * for normal use.  strace only continues with a signal if the
      70                 :            :          * stopping signal is not SIGTRAP.  -brl
      71                 :            :          */
      72                 :            :         if (current->exit_code) {
      73                 :            :                 send_sig(current->exit_code, current, 1);
      74                 :            :                 current->exit_code = 0;
      75                 :            :         }
      76                 :            : 
      77                 :            :         return fatal_signal_pending(current);
      78                 :            : }
      79                 :            : 
      80                 :            : /**
      81                 :            :  * tracehook_report_syscall_entry - task is about to attempt a system call
      82                 :            :  * @regs:               user register state of current task
      83                 :            :  *
      84                 :            :  * This will be called if %TIF_SYSCALL_TRACE has been set, when the
      85                 :            :  * current task has just entered the kernel for a system call.
      86                 :            :  * Full user register state is available here.  Changing the values
      87                 :            :  * in @regs can affect the system call number and arguments to be tried.
      88                 :            :  * It is safe to block here, preventing the system call from beginning.
      89                 :            :  *
      90                 :            :  * Returns zero normally, or nonzero if the calling arch code should abort
      91                 :            :  * the system call.  That must prevent normal entry so no system call is
      92                 :            :  * made.  If @task ever returns to user mode after this, its register state
      93                 :            :  * is unspecified, but should be something harmless like an %ENOSYS error
      94                 :            :  * return.  It should preserve enough information so that syscall_rollback()
      95                 :            :  * can work (see asm-generic/syscall.h).
      96                 :            :  *
      97                 :            :  * Called without locks, just after entering kernel mode.
      98                 :            :  */
      99                 :            : static inline __must_check int tracehook_report_syscall_entry(
     100                 :            :         struct pt_regs *regs)
     101                 :            : {
     102                 :            :         return ptrace_report_syscall(regs);
     103                 :            : }
     104                 :            : 
     105                 :            : /**
     106                 :            :  * tracehook_report_syscall_exit - task has just finished a system call
     107                 :            :  * @regs:               user register state of current task
     108                 :            :  * @step:               nonzero if simulating single-step or block-step
     109                 :            :  *
     110                 :            :  * This will be called if %TIF_SYSCALL_TRACE has been set, when the
     111                 :            :  * current task has just finished an attempted system call.  Full
     112                 :            :  * user register state is available here.  It is safe to block here,
     113                 :            :  * preventing signals from being processed.
     114                 :            :  *
     115                 :            :  * If @step is nonzero, this report is also in lieu of the normal
     116                 :            :  * trap that would follow the system call instruction because
     117                 :            :  * user_enable_block_step() or user_enable_single_step() was used.
     118                 :            :  * In this case, %TIF_SYSCALL_TRACE might not be set.
     119                 :            :  *
     120                 :            :  * Called without locks, just before checking for pending signals.
     121                 :            :  */
     122                 :            : static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
     123                 :            : {
     124                 :            :         if (step) {
     125                 :            :                 siginfo_t info;
     126                 :            :                 user_single_step_siginfo(current, regs, &info);
     127                 :            :                 force_sig_info(SIGTRAP, &info, current);
     128                 :            :                 return;
     129                 :            :         }
     130                 :            : 
     131                 :            :         ptrace_report_syscall(regs);
     132                 :            : }
     133                 :            : 
     134                 :            : /**
     135                 :            :  * tracehook_signal_handler - signal handler setup is complete
     136                 :            :  * @sig:                number of signal being delivered
     137                 :            :  * @info:               siginfo_t of signal being delivered
     138                 :            :  * @ka:                 sigaction setting that chose the handler
     139                 :            :  * @regs:               user register state
     140                 :            :  * @stepping:           nonzero if debugger single-step or block-step in use
     141                 :            :  *
     142                 :            :  * Called by the arch code after a signal handler has been set up.
     143                 :            :  * Register and stack state reflects the user handler about to run.
     144                 :            :  * Signal mask changes have already been made.
     145                 :            :  *
     146                 :            :  * Called without locks, shortly before returning to user mode
     147                 :            :  * (or handling more signals).
     148                 :            :  */
     149                 :            : static inline void tracehook_signal_handler(int sig, siginfo_t *info,
     150                 :            :                                             const struct k_sigaction *ka,
     151                 :            :                                             struct pt_regs *regs, int stepping)
     152                 :            : {
     153         [ -  + ]:    1323454 :         if (stepping)
     154                 :          0 :                 ptrace_notify(SIGTRAP);
     155                 :            : }
     156                 :            : 
     157                 :            : /**
     158                 :            :  * set_notify_resume - cause tracehook_notify_resume() to be called
     159                 :            :  * @task:               task that will call tracehook_notify_resume()
     160                 :            :  *
     161                 :            :  * Calling this arranges that @task will call tracehook_notify_resume()
     162                 :            :  * before returning to user mode.  If it's already running in user mode,
     163                 :            :  * it will enter the kernel and call tracehook_notify_resume() soon.
     164                 :            :  * If it's blocked, it will not be woken.
     165                 :            :  */
     166                 :            : static inline void set_notify_resume(struct task_struct *task)
     167                 :            : {
     168                 :            : #ifdef TIF_NOTIFY_RESUME
     169         [ +  + ]:    4985467 :         if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME))
     170                 :    3316052 :                 kick_process(task);
     171                 :            : #endif
     172                 :            : }
     173                 :            : 
     174                 :            : /**
     175                 :            :  * tracehook_notify_resume - report when about to return to user mode
     176                 :            :  * @regs:               user-mode registers of @current task
     177                 :            :  *
     178                 :            :  * This is called when %TIF_NOTIFY_RESUME has been set.  Now we are
     179                 :            :  * about to return to user mode, and the user state in @regs can be
     180                 :            :  * inspected or adjusted.  The caller in arch code has cleared
     181                 :            :  * %TIF_NOTIFY_RESUME before the call.  If the flag gets set again
     182                 :            :  * asynchronously, this will be called again before we return to
     183                 :            :  * user mode.
     184                 :            :  *
     185                 :            :  * Called without locks.
     186                 :            :  */
     187                 :            : static inline void tracehook_notify_resume(struct pt_regs *regs)
     188                 :            : {
     189                 :            :         /*
     190                 :            :          * The caller just cleared TIF_NOTIFY_RESUME. This barrier
     191                 :            :          * pairs with task_work_add()->set_notify_resume() after
     192                 :            :          * hlist_add_head(task->task_works);
     193                 :            :          */
     194                 :            :         smp_mb__after_clear_bit();
     195                 :            :         if (unlikely(current->task_works))
     196                 :            :                 task_work_run();
     197                 :            : }
     198                 :            : 
     199                 :            : #endif  /* <linux/tracehook.h> */

Generated by: LCOV version 1.9