LCOV - code coverage report
Current view: top level - arch/x86/include/asm - ptrace.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 8 43 18.6 %
Date: 2022-04-01 14:35:51 Functions: 0 2 0.0 %
Branches: 12 127 9.4 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0 */
       2                 :            : #ifndef _ASM_X86_PTRACE_H
       3                 :            : #define _ASM_X86_PTRACE_H
       4                 :            : 
       5                 :            : #include <asm/segment.h>
       6                 :            : #include <asm/page_types.h>
       7                 :            : #include <uapi/asm/ptrace.h>
       8                 :            : 
       9                 :            : #ifndef __ASSEMBLY__
      10                 :            : #ifdef __i386__
      11                 :            : 
      12                 :            : struct pt_regs {
      13                 :            :         /*
      14                 :            :          * NB: 32-bit x86 CPUs are inconsistent as what happens in the
      15                 :            :          * following cases (where %seg represents a segment register):
      16                 :            :          *
      17                 :            :          * - pushl %seg: some do a 16-bit write and leave the high
      18                 :            :          *   bits alone
      19                 :            :          * - movl %seg, [mem]: some do a 16-bit write despite the movl
      20                 :            :          * - IDT entry: some (e.g. 486) will leave the high bits of CS
      21                 :            :          *   and (if applicable) SS undefined.
      22                 :            :          *
      23                 :            :          * Fortunately, x86-32 doesn't read the high bits on POP or IRET,
      24                 :            :          * so we can just treat all of the segment registers as 16-bit
      25                 :            :          * values.
      26                 :            :          */
      27                 :            :         unsigned long bx;
      28                 :            :         unsigned long cx;
      29                 :            :         unsigned long dx;
      30                 :            :         unsigned long si;
      31                 :            :         unsigned long di;
      32                 :            :         unsigned long bp;
      33                 :            :         unsigned long ax;
      34                 :            :         unsigned short ds;
      35                 :            :         unsigned short __dsh;
      36                 :            :         unsigned short es;
      37                 :            :         unsigned short __esh;
      38                 :            :         unsigned short fs;
      39                 :            :         unsigned short __fsh;
      40                 :            :         /* On interrupt, gs and __gsh store the vector number. */
      41                 :            :         unsigned short gs;
      42                 :            :         unsigned short __gsh;
      43                 :            :         /* On interrupt, this is the error code. */
      44                 :            :         unsigned long orig_ax;
      45                 :            :         unsigned long ip;
      46                 :            :         unsigned short cs;
      47                 :            :         unsigned short __csh;
      48                 :            :         unsigned long flags;
      49                 :            :         unsigned long sp;
      50                 :            :         unsigned short ss;
      51                 :            :         unsigned short __ssh;
      52                 :            : };
      53                 :            : 
      54                 :            : #else /* __i386__ */
      55                 :            : 
      56                 :            : struct pt_regs {
      57                 :            : /*
      58                 :            :  * C ABI says these regs are callee-preserved. They aren't saved on kernel entry
      59                 :            :  * unless syscall needs a complete, fully filled "struct pt_regs".
      60                 :            :  */
      61                 :            :         unsigned long r15;
      62                 :            :         unsigned long r14;
      63                 :            :         unsigned long r13;
      64                 :            :         unsigned long r12;
      65                 :            :         unsigned long bp;
      66                 :            :         unsigned long bx;
      67                 :            : /* These regs are callee-clobbered. Always saved on kernel entry. */
      68                 :            :         unsigned long r11;
      69                 :            :         unsigned long r10;
      70                 :            :         unsigned long r9;
      71                 :            :         unsigned long r8;
      72                 :            :         unsigned long ax;
      73                 :            :         unsigned long cx;
      74                 :            :         unsigned long dx;
      75                 :            :         unsigned long si;
      76                 :            :         unsigned long di;
      77                 :            : /*
      78                 :            :  * On syscall entry, this is syscall#. On CPU exception, this is error code.
      79                 :            :  * On hw interrupt, it's IRQ number:
      80                 :            :  */
      81                 :            :         unsigned long orig_ax;
      82                 :            : /* Return frame for iretq */
      83                 :            :         unsigned long ip;
      84                 :            :         unsigned long cs;
      85                 :            :         unsigned long flags;
      86                 :            :         unsigned long sp;
      87                 :            :         unsigned long ss;
      88                 :            : /* top of stack page */
      89                 :            : };
      90                 :            : 
      91                 :            : #endif /* !__i386__ */
      92                 :            : 
      93                 :            : #ifdef CONFIG_PARAVIRT
      94                 :            : #include <asm/paravirt_types.h>
      95                 :            : #endif
      96                 :            : 
      97                 :            : struct cpuinfo_x86;
      98                 :            : struct task_struct;
      99                 :            : 
     100                 :            : extern unsigned long profile_pc(struct pt_regs *regs);
     101                 :            : 
     102                 :            : extern unsigned long
     103                 :            : convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
     104                 :            : extern void send_sigtrap(struct pt_regs *regs, int error_code, int si_code);
     105                 :            : 
     106                 :            : 
     107                 :          0 : static inline unsigned long regs_return_value(struct pt_regs *regs)
     108                 :            : {
     109                 :          0 :         return regs->ax;
     110                 :            : }
     111                 :            : 
     112                 :            : static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
     113                 :            : {
     114                 :            :         regs->ax = rc;
     115                 :            : }
     116                 :            : 
     117                 :            : /*
     118                 :            :  * user_mode(regs) determines whether a register set came from user
     119                 :            :  * mode.  On x86_32, this is true if V8086 mode was enabled OR if the
     120                 :            :  * register set was from protected mode with RPL-3 CS value.  This
     121                 :            :  * tricky test checks that with one comparison.
     122                 :            :  *
     123                 :            :  * On x86_64, vm86 mode is mercifully nonexistent, and we don't need
     124                 :            :  * the extra check.
     125                 :            :  */
     126                 :   21902243 : static inline int user_mode(struct pt_regs *regs)
     127                 :            : {
     128                 :            : #ifdef CONFIG_X86_32
     129                 :            :         return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
     130                 :            : #else
     131   [ +  +  +  +  :   21902243 :         return !!(regs->cs & 3);
          +  +  -  -  -  
          -  -  +  -  +  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
                   -  - ]
     132                 :            : #endif
     133                 :            : }
     134                 :            : 
     135                 :      49686 : static inline int v8086_mode(struct pt_regs *regs)
     136                 :            : {
     137                 :            : #ifdef CONFIG_X86_32
     138                 :            :         return (regs->flags & X86_VM_MASK);
     139                 :            : #else
     140   [ -  +  #  #  :      49686 :         return 0;       /* No V86 mode support in long mode */
                   #  # ]
     141                 :            : #endif
     142                 :            : }
     143                 :            : 
     144                 :      49686 : static inline bool user_64bit_mode(struct pt_regs *regs)
     145                 :            : {
     146                 :            : #ifdef CONFIG_X86_64
     147                 :            : #ifndef CONFIG_PARAVIRT_XXL
     148                 :            :         /*
     149                 :            :          * On non-paravirt systems, this is the only long mode CPL 3
     150                 :            :          * selector.  We do not allow long mode selectors in the LDT.
     151                 :            :          */
     152   [ +  -  -  -  :      49686 :         return regs->cs == __USER_CS;
          #  #  #  #  #  
                      # ]
     153                 :            : #else
     154                 :            :         /* Headers are too twisted for this to go in paravirt.h. */
     155                 :            :         return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
     156                 :            : #endif
     157                 :            : #else /* !CONFIG_X86_64 */
     158                 :            :         return false;
     159                 :            : #endif
     160                 :            : }
     161                 :            : 
     162                 :            : /*
     163                 :            :  * Determine whether the register set came from any context that is running in
     164                 :            :  * 64-bit mode.
     165                 :            :  */
     166                 :          0 : static inline bool any_64bit_mode(struct pt_regs *regs)
     167                 :            : {
     168                 :            : #ifdef CONFIG_X86_64
     169   [ #  #  #  #  :          0 :         return !user_mode(regs) || user_64bit_mode(regs);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     170                 :            : #else
     171                 :            :         return false;
     172                 :            : #endif
     173                 :            : }
     174                 :            : 
     175                 :            : #ifdef CONFIG_X86_64
     176                 :            : #define current_user_stack_pointer()    current_pt_regs()->sp
     177                 :            : #define compat_user_stack_pointer()     current_pt_regs()->sp
     178                 :            : #endif
     179                 :            : 
     180                 :          0 : static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
     181                 :            : {
     182                 :          0 :         return regs->sp;
     183                 :            : }
     184                 :            : 
     185                 :      54367 : static inline unsigned long instruction_pointer(struct pt_regs *regs)
     186                 :            : {
     187         [ #  # ]:      54367 :         return regs->ip;
     188                 :            : }
     189                 :            : 
     190                 :          0 : static inline void instruction_pointer_set(struct pt_regs *regs,
     191                 :            :                 unsigned long val)
     192                 :            : {
     193                 :          0 :         regs->ip = val;
     194                 :          0 : }
     195                 :            : 
     196                 :            : static inline unsigned long frame_pointer(struct pt_regs *regs)
     197                 :            : {
     198                 :            :         return regs->bp;
     199                 :            : }
     200                 :            : 
     201                 :          0 : static inline unsigned long user_stack_pointer(struct pt_regs *regs)
     202                 :            : {
     203   [ #  #  #  #  :          0 :         return regs->sp;
                      # ]
     204                 :            : }
     205                 :            : 
     206                 :            : static inline void user_stack_pointer_set(struct pt_regs *regs,
     207                 :            :                 unsigned long val)
     208                 :            : {
     209                 :            :         regs->sp = val;
     210                 :            : }
     211                 :            : 
     212                 :            : /* Query offset/name of register from its name/offset */
     213                 :            : extern int regs_query_register_offset(const char *name);
     214                 :            : extern const char *regs_query_register_name(unsigned int offset);
     215                 :            : #define MAX_REG_OFFSET (offsetof(struct pt_regs, ss))
     216                 :            : 
     217                 :            : /**
     218                 :            :  * regs_get_register() - get register value from its offset
     219                 :            :  * @regs:       pt_regs from which register value is gotten.
     220                 :            :  * @offset:     offset number of the register.
     221                 :            :  *
     222                 :            :  * regs_get_register returns the value of a register. The @offset is the
     223                 :            :  * offset of the register in struct pt_regs address which specified by @regs.
     224                 :            :  * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
     225                 :            :  */
     226                 :          0 : static inline unsigned long regs_get_register(struct pt_regs *regs,
     227                 :            :                                               unsigned int offset)
     228                 :            : {
     229   [ #  #  #  #  :          0 :         if (unlikely(offset > MAX_REG_OFFSET))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     230                 :            :                 return 0;
     231                 :            : #ifdef CONFIG_X86_32
     232                 :            :         /* The selector fields are 16-bit. */
     233                 :            :         if (offset == offsetof(struct pt_regs, cs) ||
     234                 :            :             offset == offsetof(struct pt_regs, ss) ||
     235                 :            :             offset == offsetof(struct pt_regs, ds) ||
     236                 :            :             offset == offsetof(struct pt_regs, es) ||
     237                 :            :             offset == offsetof(struct pt_regs, fs) ||
     238                 :            :             offset == offsetof(struct pt_regs, gs)) {
     239                 :            :                 return *(u16 *)((unsigned long)regs + offset);
     240                 :            : 
     241                 :            :         }
     242                 :            : #endif
     243                 :          0 :         return *(unsigned long *)((unsigned long)regs + offset);
     244                 :            : }
     245                 :            : 
     246                 :            : /**
     247                 :            :  * regs_within_kernel_stack() - check the address in the stack
     248                 :            :  * @regs:       pt_regs which contains kernel stack pointer.
     249                 :            :  * @addr:       address which is checked.
     250                 :            :  *
     251                 :            :  * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
     252                 :            :  * If @addr is within the kernel stack, it returns true. If not, returns false.
     253                 :            :  */
     254                 :          0 : static inline int regs_within_kernel_stack(struct pt_regs *regs,
     255                 :            :                                            unsigned long addr)
     256                 :            : {
     257                 :          0 :         return ((addr & ~(THREAD_SIZE - 1)) == (regs->sp & ~(THREAD_SIZE - 1)));
     258                 :            : }
     259                 :            : 
     260                 :            : /**
     261                 :            :  * regs_get_kernel_stack_nth_addr() - get the address of the Nth entry on stack
     262                 :            :  * @regs:       pt_regs which contains kernel stack pointer.
     263                 :            :  * @n:          stack entry number.
     264                 :            :  *
     265                 :            :  * regs_get_kernel_stack_nth() returns the address of the @n th entry of the
     266                 :            :  * kernel stack which is specified by @regs. If the @n th entry is NOT in
     267                 :            :  * the kernel stack, this returns NULL.
     268                 :            :  */
     269                 :          0 : static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs, unsigned int n)
     270                 :            : {
     271                 :          0 :         unsigned long *addr = (unsigned long *)regs->sp;
     272                 :            : 
     273                 :          0 :         addr += n;
     274                 :          0 :         if (regs_within_kernel_stack(regs, (unsigned long)addr))
     275                 :            :                 return addr;
     276                 :            :         else
     277                 :            :                 return NULL;
     278                 :            : }
     279                 :            : 
     280                 :            : /* To avoid include hell, we can't include uaccess.h */
     281                 :            : extern long probe_kernel_read(void *dst, const void *src, size_t size);
     282                 :            : 
     283                 :            : /**
     284                 :            :  * regs_get_kernel_stack_nth() - get Nth entry of the stack
     285                 :            :  * @regs:       pt_regs which contains kernel stack pointer.
     286                 :            :  * @n:          stack entry number.
     287                 :            :  *
     288                 :            :  * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
     289                 :            :  * is specified by @regs. If the @n th entry is NOT in the kernel stack
     290                 :            :  * this returns 0.
     291                 :            :  */
     292                 :          0 : static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
     293                 :            :                                                       unsigned int n)
     294                 :            : {
     295                 :          0 :         unsigned long *addr;
     296                 :          0 :         unsigned long val;
     297                 :          0 :         long ret;
     298                 :            : 
     299         [ #  # ]:          0 :         addr = regs_get_kernel_stack_nth_addr(regs, n);
     300         [ #  # ]:          0 :         if (addr) {
     301                 :          0 :                 ret = probe_kernel_read(&val, addr, sizeof(val));
     302         [ #  # ]:          0 :                 if (!ret)
     303                 :          0 :                         return val;
     304                 :            :         }
     305                 :            :         return 0;
     306                 :            : }
     307                 :            : 
     308                 :            : /**
     309                 :            :  * regs_get_kernel_argument() - get Nth function argument in kernel
     310                 :            :  * @regs:       pt_regs of that context
     311                 :            :  * @n:          function argument number (start from 0)
     312                 :            :  *
     313                 :            :  * regs_get_argument() returns @n th argument of the function call.
     314                 :            :  * Note that this chooses most probably assignment, in some case
     315                 :            :  * it can be incorrect.
     316                 :            :  * This is expected to be called from kprobes or ftrace with regs
     317                 :            :  * where the top of stack is the return address.
     318                 :            :  */
     319                 :          0 : static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
     320                 :            :                                                      unsigned int n)
     321                 :            : {
     322                 :          0 :         static const unsigned int argument_offs[] = {
     323                 :            : #ifdef __i386__
     324                 :            :                 offsetof(struct pt_regs, ax),
     325                 :            :                 offsetof(struct pt_regs, cx),
     326                 :            :                 offsetof(struct pt_regs, dx),
     327                 :            : #define NR_REG_ARGUMENTS 3
     328                 :            : #else
     329                 :            :                 offsetof(struct pt_regs, di),
     330                 :            :                 offsetof(struct pt_regs, si),
     331                 :            :                 offsetof(struct pt_regs, dx),
     332                 :            :                 offsetof(struct pt_regs, cx),
     333                 :            :                 offsetof(struct pt_regs, r8),
     334                 :            :                 offsetof(struct pt_regs, r9),
     335                 :            : #define NR_REG_ARGUMENTS 6
     336                 :            : #endif
     337                 :            :         };
     338                 :            : 
     339         [ #  # ]:          0 :         if (n >= NR_REG_ARGUMENTS) {
     340                 :          0 :                 n -= NR_REG_ARGUMENTS - 1;
     341                 :          0 :                 return regs_get_kernel_stack_nth(regs, n);
     342                 :            :         } else
     343         [ #  # ]:          0 :                 return regs_get_register(regs, argument_offs[n]);
     344                 :            : }
     345                 :            : 
     346                 :            : #define arch_has_single_step()  (1)
     347                 :            : #ifdef CONFIG_X86_DEBUGCTLMSR
     348                 :            : #define arch_has_block_step()   (1)
     349                 :            : #else
     350                 :            : #define arch_has_block_step()   (boot_cpu_data.x86 >= 6)
     351                 :            : #endif
     352                 :            : 
     353                 :            : #define ARCH_HAS_USER_SINGLE_STEP_REPORT
     354                 :            : 
     355                 :            : struct user_desc;
     356                 :            : extern int do_get_thread_area(struct task_struct *p, int idx,
     357                 :            :                               struct user_desc __user *info);
     358                 :            : extern int do_set_thread_area(struct task_struct *p, int idx,
     359                 :            :                               struct user_desc __user *info, int can_allocate);
     360                 :            : 
     361                 :            : #ifdef CONFIG_X86_64
     362                 :            : # define do_set_thread_area_64(p, s, t) do_arch_prctl_64(p, s, t)
     363                 :            : #else
     364                 :            : # define do_set_thread_area_64(p, s, t) (0)
     365                 :            : #endif
     366                 :            : 
     367                 :            : #endif /* !__ASSEMBLY__ */
     368                 :            : #endif /* _ASM_X86_PTRACE_H */

Generated by: LCOV version 1.14