linux/arch/x86/include/asm/stacktrace.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 *  Copyright (C) 1991, 1992  Linus Torvalds
   4 *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
   5 */
   6
   7#ifndef _ASM_X86_STACKTRACE_H
   8#define _ASM_X86_STACKTRACE_H
   9
  10#include <linux/uaccess.h>
  11#include <linux/ptrace.h>
  12
  13#include <asm/cpu_entry_area.h>
  14#include <asm/switch_to.h>
  15
  16enum stack_type {
  17        STACK_TYPE_UNKNOWN,
  18        STACK_TYPE_TASK,
  19        STACK_TYPE_IRQ,
  20        STACK_TYPE_SOFTIRQ,
  21        STACK_TYPE_ENTRY,
  22        STACK_TYPE_EXCEPTION,
  23        STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1,
  24};
  25
  26struct stack_info {
  27        enum stack_type type;
  28        unsigned long *begin, *end, *next_sp;
  29};
  30
  31bool in_task_stack(unsigned long *stack, struct task_struct *task,
  32                   struct stack_info *info);
  33
  34bool in_entry_stack(unsigned long *stack, struct stack_info *info);
  35
  36int get_stack_info(unsigned long *stack, struct task_struct *task,
  37                   struct stack_info *info, unsigned long *visit_mask);
  38bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task,
  39                            struct stack_info *info);
  40
  41const char *stack_type_name(enum stack_type type);
  42
  43static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
  44{
  45        void *begin = info->begin;
  46        void *end   = info->end;
  47
  48        return (info->type != STACK_TYPE_UNKNOWN &&
  49                addr >= begin && addr < end &&
  50                addr + len > begin && addr + len <= end);
  51}
  52
  53#ifdef CONFIG_X86_32
  54#define STACKSLOTS_PER_LINE 8
  55#else
  56#define STACKSLOTS_PER_LINE 4
  57#endif
  58
  59#ifdef CONFIG_FRAME_POINTER
  60static inline unsigned long *
  61get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
  62{
  63        if (regs)
  64                return (unsigned long *)regs->bp;
  65
  66        if (task == current)
  67                return __builtin_frame_address(0);
  68
  69        return &((struct inactive_task_frame *)task->thread.sp)->bp;
  70}
  71#else
  72static inline unsigned long *
  73get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
  74{
  75        return NULL;
  76}
  77#endif /* CONFIG_FRAME_POINTER */
  78
  79static inline unsigned long *
  80get_stack_pointer(struct task_struct *task, struct pt_regs *regs)
  81{
  82        if (regs)
  83                return (unsigned long *)regs->sp;
  84
  85        if (task == current)
  86                return __builtin_frame_address(0);
  87
  88        return (unsigned long *)task->thread.sp;
  89}
  90
  91/* The form of the top of the frame on the stack */
  92struct stack_frame {
  93        struct stack_frame *next_frame;
  94        unsigned long return_address;
  95};
  96
  97struct stack_frame_ia32 {
  98    u32 next_frame;
  99    u32 return_address;
 100};
 101
 102void show_opcodes(struct pt_regs *regs, const char *loglvl);
 103void show_ip(struct pt_regs *regs, const char *loglvl);
 104#endif /* _ASM_X86_STACKTRACE_H */
 105