Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115/* SPDX-License-Identifier: GPL-2.0 *//* * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs */
#ifndef _ASM_X86_STACKTRACE_H#define _ASM_X86_STACKTRACE_H
#include <linux/uaccess.h>#include <linux/ptrace.h>
#include <asm/cpu_entry_area.h>#include <asm/switch_to.h>
enum stack_type { STACK_TYPE_UNKNOWN, STACK_TYPE_TASK, STACK_TYPE_IRQ, STACK_TYPE_SOFTIRQ, STACK_TYPE_ENTRY, STACK_TYPE_EXCEPTION, STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1,};
struct stack_info { enum stack_type type; unsigned long *begin, *end, *next_sp;};
bool in_task_stack(unsigned long *stack, struct task_struct *task, struct stack_info *info);
bool in_entry_stack(unsigned long *stack, struct stack_info *info);
int get_stack_info(unsigned long *stack, struct task_struct *task, struct stack_info *info, unsigned long *visit_mask);bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, struct stack_info *info);
static __always_inlinebool get_stack_guard_info(unsigned long *stack, struct stack_info *info){ /* make sure it's not in the stack proper */ if (get_stack_info_noinstr(stack, current, info)) return false; /* but if it is in the page below it, we hit a guard */ return get_stack_info_noinstr((void *)stack + PAGE_SIZE, current, info);}
const char *stack_type_name(enum stack_type type);
static inline bool on_stack(struct stack_info *info, void *addr, size_t len){ void *begin = info->begin; void *end = info->end;
return (info->type != STACK_TYPE_UNKNOWN && addr >= begin && addr < end && addr + len > begin && addr + len <= end);}
#ifdef CONFIG_X86_32#define STACKSLOTS_PER_LINE 8#else#define STACKSLOTS_PER_LINE 4#endif
#ifdef CONFIG_FRAME_POINTERstatic inline unsigned long *get_frame_pointer(struct task_struct *task, struct pt_regs *regs){ if (regs) return (unsigned long *)regs->bp;
if (task == current) return __builtin_frame_address(0);
return &((struct inactive_task_frame *)task->thread.sp)->bp;}#elsestatic inline unsigned long *get_frame_pointer(struct task_struct *task, struct pt_regs *regs){ return NULL;}#endif /* CONFIG_FRAME_POINTER */
static inline unsigned long *get_stack_pointer(struct task_struct *task, struct pt_regs *regs){ if (regs) return (unsigned long *)regs->sp;
if (task == current) return __builtin_frame_address(0);
return (unsigned long *)task->thread.sp;}
/* The form of the top of the frame on the stack */struct stack_frame { struct stack_frame *next_frame; unsigned long return_address;};
struct stack_frame_ia32 { u32 next_frame; u32 return_address;};
void show_opcodes(struct pt_regs *regs, const char *loglvl);void show_ip(struct pt_regs *regs, const char *loglvl);#endif /* _ASM_X86_STACKTRACE_H */