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