]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/blame - arch/x86/include/asm/stacktrace.h
Merge tag 'xtensa-20190201' of git://github.com/jcmvbkbc/linux-xtensa
[mirror_ubuntu-disco-kernel.git] / arch / x86 / include / asm / stacktrace.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
c9cf4dbb
FW
2/*
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
5 */
6
1965aae3
PA
7#ifndef _ASM_X86_STACKTRACE_H
8#define _ASM_X86_STACKTRACE_H
c0b766f1 9
c9cf4dbb 10#include <linux/uaccess.h>
9c0729dc 11#include <linux/ptrace.h>
7b32aead 12#include <asm/switch_to.h>
c9cf4dbb 13
cb76c939
JP
14enum stack_type {
15 STACK_TYPE_UNKNOWN,
16 STACK_TYPE_TASK,
17 STACK_TYPE_IRQ,
18 STACK_TYPE_SOFTIRQ,
4fe2d8b1 19 STACK_TYPE_ENTRY,
cb76c939
JP
20 STACK_TYPE_EXCEPTION,
21 STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1,
22};
23
24struct stack_info {
25 enum stack_type type;
26 unsigned long *begin, *end, *next_sp;
27};
28
29bool in_task_stack(unsigned long *stack, struct task_struct *task,
30 struct stack_info *info);
31
4fe2d8b1 32bool in_entry_stack(unsigned long *stack, struct stack_info *info);
33a2f1a6 33
cb76c939
JP
34int get_stack_info(unsigned long *stack, struct task_struct *task,
35 struct stack_info *info, unsigned long *visit_mask);
36
3d02a9c4 37const char *stack_type_name(enum stack_type type);
cb76c939
JP
38
39static inline bool on_stack(struct stack_info *info, void *addr, size_t len)
40{
41 void *begin = info->begin;
42 void *end = info->end;
43
44 return (info->type != STACK_TYPE_UNKNOWN &&
45 addr >= begin && addr < end &&
46 addr + len > begin && addr + len <= end);
47}
48
c9cf4dbb
FW
49#ifdef CONFIG_X86_32
50#define STACKSLOTS_PER_LINE 8
c9cf4dbb
FW
51#else
52#define STACKSLOTS_PER_LINE 4
c9cf4dbb
FW
53#endif
54
9c0729dc 55#ifdef CONFIG_FRAME_POINTER
4b8afafb
JP
56static inline unsigned long *
57get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
9c0729dc 58{
9c0729dc 59 if (regs)
4b8afafb 60 return (unsigned long *)regs->bp;
9c0729dc 61
81539169 62 if (task == current)
4b8afafb 63 return __builtin_frame_address(0);
9c0729dc 64
2c96b2fe 65 return &((struct inactive_task_frame *)task->thread.sp)->bp;
9c0729dc
SSP
66}
67#else
4b8afafb
JP
68static inline unsigned long *
69get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
9c0729dc 70{
4b8afafb
JP
71 return NULL;
72}
73#endif /* CONFIG_FRAME_POINTER */
74
75static inline unsigned long *
76get_stack_pointer(struct task_struct *task, struct pt_regs *regs)
77{
78 if (regs)
79 return (unsigned long *)kernel_stack_pointer(regs);
80
81539169 81 if (task == current)
4b8afafb
JP
82 return __builtin_frame_address(0);
83
84 return (unsigned long *)task->thread.sp;
9c0729dc 85}
9c0729dc 86
e18bcccd
JP
87void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
88 unsigned long *stack, char *log_lvl);
c9cf4dbb 89
c9cf4dbb
FW
90/* The form of the top of the frame on the stack */
91struct stack_frame {
92 struct stack_frame *next_frame;
93 unsigned long return_address;
94};
95
96struct stack_frame_ia32 {
97 u32 next_frame;
98 u32 return_address;
99};
100
b0f82b81 101static inline unsigned long caller_frame_pointer(void)
c9cf4dbb
FW
102{
103 struct stack_frame *frame;
104
4b8afafb 105 frame = __builtin_frame_address(0);
c9cf4dbb
FW
106
107#ifdef CONFIG_FRAME_POINTER
b0f82b81 108 frame = frame->next_frame;
c9cf4dbb
FW
109#endif
110
111 return (unsigned long)frame;
112}
113
342db04a 114void show_opcodes(struct pt_regs *regs, const char *loglvl);
7cccf072 115void show_ip(struct pt_regs *regs, const char *loglvl);
1965aae3 116#endif /* _ASM_X86_STACKTRACE_H */