mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.4 KiB
104 lines
2.4 KiB
/* 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); |
|
|
|
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_POINTER |
|
static 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; |
|
} |
|
#else |
|
static 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 */
|
|
|