]>
Commit | Line | Data |
---|---|---|
1 | /* SPDX-License-Identifier: GPL-2.0 */ | |
2 | #ifndef _UNWIND_H_ | |
3 | #define _UNWIND_H_ | |
4 | ||
5 | #include <linux/list.h> | |
6 | ||
7 | /* Max number of levels to backtrace */ | |
8 | #define MAX_UNWIND_ENTRIES 30 | |
9 | ||
10 | /* From ABI specifications */ | |
11 | struct unwind_table_entry { | |
12 | unsigned int region_start; | |
13 | unsigned int region_end; | |
14 | unsigned int Cannot_unwind:1; /* 0 */ | |
15 | unsigned int Millicode:1; /* 1 */ | |
16 | unsigned int Millicode_save_sr0:1; /* 2 */ | |
17 | unsigned int Region_description:2; /* 3..4 */ | |
18 | unsigned int reserved1:1; /* 5 */ | |
19 | unsigned int Entry_SR:1; /* 6 */ | |
20 | unsigned int Entry_FR:4; /* number saved *//* 7..10 */ | |
21 | unsigned int Entry_GR:5; /* number saved *//* 11..15 */ | |
22 | unsigned int Args_stored:1; /* 16 */ | |
23 | unsigned int Variable_Frame:1; /* 17 */ | |
24 | unsigned int Separate_Package_Body:1; /* 18 */ | |
25 | unsigned int Frame_Extension_Millicode:1; /* 19 */ | |
26 | unsigned int Stack_Overflow_Check:1; /* 20 */ | |
27 | unsigned int Two_Instruction_SP_Increment:1; /* 21 */ | |
28 | unsigned int Ada_Region:1; /* 22 */ | |
29 | unsigned int cxx_info:1; /* 23 */ | |
30 | unsigned int cxx_try_catch:1; /* 24 */ | |
31 | unsigned int sched_entry_seq:1; /* 25 */ | |
32 | unsigned int reserved2:1; /* 26 */ | |
33 | unsigned int Save_SP:1; /* 27 */ | |
34 | unsigned int Save_RP:1; /* 28 */ | |
35 | unsigned int Save_MRP_in_frame:1; /* 29 */ | |
36 | unsigned int extn_ptr_defined:1; /* 30 */ | |
37 | unsigned int Cleanup_defined:1; /* 31 */ | |
38 | ||
39 | unsigned int MPE_XL_interrupt_marker:1; /* 0 */ | |
40 | unsigned int HP_UX_interrupt_marker:1; /* 1 */ | |
41 | unsigned int Large_frame:1; /* 2 */ | |
42 | unsigned int Pseudo_SP_Set:1; /* 3 */ | |
43 | unsigned int reserved4:1; /* 4 */ | |
44 | unsigned int Total_frame_size:27; /* 5..31 */ | |
45 | }; | |
46 | ||
47 | struct unwind_table { | |
48 | struct list_head list; | |
49 | const char *name; | |
50 | unsigned long gp; | |
51 | unsigned long base_addr; | |
52 | unsigned long start; | |
53 | unsigned long end; | |
54 | const struct unwind_table_entry *table; | |
55 | unsigned long length; | |
56 | }; | |
57 | ||
58 | struct unwind_frame_info { | |
59 | struct task_struct *t; | |
60 | /* Eventually we would like to be able to get at any of the registers | |
61 | available; but for now we only try to get the sp and ip for each | |
62 | frame */ | |
63 | /* struct pt_regs regs; */ | |
64 | unsigned long sp, ip, rp, r31; | |
65 | unsigned long prev_sp, prev_ip; | |
66 | }; | |
67 | ||
68 | struct unwind_table * | |
69 | unwind_table_add(const char *name, unsigned long base_addr, | |
70 | unsigned long gp, void *start, void *end); | |
71 | void | |
72 | unwind_table_remove(struct unwind_table *table); | |
73 | ||
74 | void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, | |
75 | struct pt_regs *regs); | |
76 | void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t); | |
77 | void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs); | |
78 | int unwind_once(struct unwind_frame_info *info); | |
79 | int unwind_to_user(struct unwind_frame_info *info); | |
80 | ||
81 | int unwind_init(void); | |
82 | ||
83 | #endif |