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