linux/arch/riscv/include/asm/ptrace.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright (C) 2012 Regents of the University of California
   4 */
   5
   6#ifndef _ASM_RISCV_PTRACE_H
   7#define _ASM_RISCV_PTRACE_H
   8
   9#include <uapi/asm/ptrace.h>
  10#include <asm/csr.h>
  11#include <linux/compiler.h>
  12
  13#ifndef __ASSEMBLY__
  14
  15struct pt_regs {
  16        unsigned long epc;
  17        unsigned long ra;
  18        unsigned long sp;
  19        unsigned long gp;
  20        unsigned long tp;
  21        unsigned long t0;
  22        unsigned long t1;
  23        unsigned long t2;
  24        unsigned long s0;
  25        unsigned long s1;
  26        unsigned long a0;
  27        unsigned long a1;
  28        unsigned long a2;
  29        unsigned long a3;
  30        unsigned long a4;
  31        unsigned long a5;
  32        unsigned long a6;
  33        unsigned long a7;
  34        unsigned long s2;
  35        unsigned long s3;
  36        unsigned long s4;
  37        unsigned long s5;
  38        unsigned long s6;
  39        unsigned long s7;
  40        unsigned long s8;
  41        unsigned long s9;
  42        unsigned long s10;
  43        unsigned long s11;
  44        unsigned long t3;
  45        unsigned long t4;
  46        unsigned long t5;
  47        unsigned long t6;
  48        /* Supervisor/Machine CSRs */
  49        unsigned long status;
  50        unsigned long badaddr;
  51        unsigned long cause;
  52        /* a0 value before the syscall */
  53        unsigned long orig_a0;
  54};
  55
  56#ifdef CONFIG_64BIT
  57#define REG_FMT "%016lx"
  58#else
  59#define REG_FMT "%08lx"
  60#endif
  61
  62#define user_mode(regs) (((regs)->status & SR_PP) == 0)
  63
  64#define MAX_REG_OFFSET offsetof(struct pt_regs, orig_a0)
  65
  66/* Helpers for working with the instruction pointer */
  67static inline unsigned long instruction_pointer(struct pt_regs *regs)
  68{
  69        return regs->epc;
  70}
  71static inline void instruction_pointer_set(struct pt_regs *regs,
  72                                           unsigned long val)
  73{
  74        regs->epc = val;
  75}
  76
  77#define profile_pc(regs) instruction_pointer(regs)
  78
  79/* Helpers for working with the user stack pointer */
  80static inline unsigned long user_stack_pointer(struct pt_regs *regs)
  81{
  82        return regs->sp;
  83}
  84static inline void user_stack_pointer_set(struct pt_regs *regs,
  85                                          unsigned long val)
  86{
  87        regs->sp =  val;
  88}
  89
  90/* Valid only for Kernel mode traps. */
  91static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
  92{
  93        return regs->sp;
  94}
  95
  96/* Helpers for working with the frame pointer */
  97static inline unsigned long frame_pointer(struct pt_regs *regs)
  98{
  99        return regs->s0;
 100}
 101static inline void frame_pointer_set(struct pt_regs *regs,
 102                                     unsigned long val)
 103{
 104        regs->s0 = val;
 105}
 106
 107static inline unsigned long regs_return_value(struct pt_regs *regs)
 108{
 109        return regs->a0;
 110}
 111
 112static inline void regs_set_return_value(struct pt_regs *regs,
 113                                         unsigned long val)
 114{
 115        regs->a0 = val;
 116}
 117
 118extern int regs_query_register_offset(const char *name);
 119extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
 120                                               unsigned int n);
 121
 122void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
 123                           unsigned long frame_pointer);
 124int do_syscall_trace_enter(struct pt_regs *regs);
 125void do_syscall_trace_exit(struct pt_regs *regs);
 126
 127/**
 128 * regs_get_register() - get register value from its offset
 129 * @regs:       pt_regs from which register value is gotten
 130 * @offset:     offset of the register.
 131 *
 132 * regs_get_register returns the value of a register whose offset from @regs.
 133 * The @offset is the offset of the register in struct pt_regs.
 134 * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
 135 */
 136static inline unsigned long regs_get_register(struct pt_regs *regs,
 137                                              unsigned int offset)
 138{
 139        if (unlikely(offset > MAX_REG_OFFSET))
 140                return 0;
 141
 142        return *(unsigned long *)((unsigned long)regs + offset);
 143}
 144
 145/**
 146 * regs_get_kernel_argument() - get Nth function argument in kernel
 147 * @regs:       pt_regs of that context
 148 * @n:          function argument number (start from 0)
 149 *
 150 * regs_get_argument() returns @n th argument of the function call.
 151 *
 152 * Note you can get the parameter correctly if the function has no
 153 * more than eight arguments.
 154 */
 155static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
 156                                                unsigned int n)
 157{
 158        static const int nr_reg_arguments = 8;
 159        static const unsigned int argument_offs[] = {
 160                offsetof(struct pt_regs, a0),
 161                offsetof(struct pt_regs, a1),
 162                offsetof(struct pt_regs, a2),
 163                offsetof(struct pt_regs, a3),
 164                offsetof(struct pt_regs, a4),
 165                offsetof(struct pt_regs, a5),
 166                offsetof(struct pt_regs, a6),
 167                offsetof(struct pt_regs, a7),
 168        };
 169
 170        if (n < nr_reg_arguments)
 171                return regs_get_register(regs, argument_offs[n]);
 172        return 0;
 173}
 174
 175#endif /* __ASSEMBLY__ */
 176
 177#endif /* _ASM_RISCV_PTRACE_H */
 178