linux/arch/sh/include/asm/ptrace.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Copyright (C) 1999, 2000  Niibe Yutaka
   4 */
   5#ifndef __ASM_SH_PTRACE_H
   6#define __ASM_SH_PTRACE_H
   7
   8
   9#include <linux/stringify.h>
  10#include <linux/stddef.h>
  11#include <linux/thread_info.h>
  12#include <asm/addrspace.h>
  13#include <asm/page.h>
  14#include <uapi/asm/ptrace.h>
  15
  16#define user_mode(regs)                 (((regs)->sr & 0x40000000)==0)
  17#define kernel_stack_pointer(_regs)     ((unsigned long)(_regs)->regs[15])
  18
  19static inline unsigned long instruction_pointer(struct pt_regs *regs)
  20{
  21        return regs->pc;
  22}
  23static inline void instruction_pointer_set(struct pt_regs *regs,
  24                unsigned long val)
  25{
  26        regs->pc = val;
  27}
  28
  29static inline unsigned long frame_pointer(struct pt_regs *regs)
  30{
  31        return regs->regs[14];
  32}
  33
  34static inline unsigned long user_stack_pointer(struct pt_regs *regs)
  35{
  36        return regs->regs[15];
  37}
  38
  39static inline void user_stack_pointer_set(struct pt_regs *regs,
  40                unsigned long val)
  41{
  42        regs->regs[15] = val;
  43}
  44
  45#define arch_has_single_step()  (1)
  46
  47/*
  48 * kprobe-based event tracer support
  49 */
  50struct pt_regs_offset {
  51        const char *name;
  52        int offset;
  53};
  54
  55#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
  56#define REGS_OFFSET_NAME(num)   \
  57        {.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])}
  58#define TREGS_OFFSET_NAME(num)  \
  59        {.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])}
  60#define REG_OFFSET_END {.name = NULL, .offset = 0}
  61
  62/* Query offset/name of register from its name/offset */
  63extern int regs_query_register_offset(const char *name);
  64extern const char *regs_query_register_name(unsigned int offset);
  65
  66extern const struct pt_regs_offset regoffset_table[];
  67
  68/**
  69 * regs_get_register() - get register value from its offset
  70 * @regs:       pt_regs from which register value is gotten.
  71 * @offset:     offset number of the register.
  72 *
  73 * regs_get_register returns the value of a register. The @offset is the
  74 * offset of the register in struct pt_regs address which specified by @regs.
  75 * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
  76 */
  77static inline unsigned long regs_get_register(struct pt_regs *regs,
  78                                              unsigned int offset)
  79{
  80        if (unlikely(offset > MAX_REG_OFFSET))
  81                return 0;
  82        return *(unsigned long *)((unsigned long)regs + offset);
  83}
  84
  85/**
  86 * regs_within_kernel_stack() - check the address in the stack
  87 * @regs:       pt_regs which contains kernel stack pointer.
  88 * @addr:       address which is checked.
  89 *
  90 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
  91 * If @addr is within the kernel stack, it returns true. If not, returns false.
  92 */
  93static inline int regs_within_kernel_stack(struct pt_regs *regs,
  94                                           unsigned long addr)
  95{
  96        return ((addr & ~(THREAD_SIZE - 1))  ==
  97                (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
  98}
  99
 100/**
 101 * regs_get_kernel_stack_nth() - get Nth entry of the stack
 102 * @regs:       pt_regs which contains kernel stack pointer.
 103 * @n:          stack entry number.
 104 *
 105 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
 106 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
 107 * this returns 0.
 108 */
 109static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
 110                                                      unsigned int n)
 111{
 112        unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
 113        addr += n;
 114        if (regs_within_kernel_stack(regs, (unsigned long)addr))
 115                return *addr;
 116        else
 117                return 0;
 118}
 119
 120struct perf_event;
 121struct perf_sample_data;
 122
 123extern void ptrace_triggered(struct perf_event *bp,
 124                      struct perf_sample_data *data, struct pt_regs *regs);
 125
 126#define task_pt_regs(task) \
 127        ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
 128
 129static inline unsigned long profile_pc(struct pt_regs *regs)
 130{
 131        unsigned long pc = regs->pc;
 132
 133        if (virt_addr_uncached(pc))
 134                return CAC_ADDR(pc);
 135
 136        return pc;
 137}
 138
 139#endif /* __ASM_SH_PTRACE_H */
 140