Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
unwind_i.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co
3  * David Mosberger-Tang <[email protected]>
4  *
5  * Kernel unwind support.
6  */
7 
8 #define UNW_VER(x) ((x) >> 48)
9 #define UNW_FLAG_MASK 0x0000ffff00000000
10 #define UNW_FLAG_OSMASK 0x0000f00000000000
11 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
12 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
13 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
14 
16  /* primary unat: */
19 
20  /* register stack */
21  UNW_REG_BSP, /* register stack pointer */
23  UNW_REG_PFS, /* previous function state */
25  /* memory stack */
26  UNW_REG_PSP, /* previous memory stack pointer */
27  /* return pointer: */
29 
30  /* preserved registers: */
40 };
41 
44  u64 desc[0]; /* unwind descriptors */
45  /* personality routine and language-specific data follow behind descriptors */
46 };
47 
48 struct unw_table {
49  struct unw_table *next; /* must be first member! */
50  const char *name;
51  unsigned long gp; /* global pointer for this load-module */
52  unsigned long segment_base; /* base for offsets in the unwind table entries */
53  unsigned long start;
54  unsigned long end;
55  const struct unw_table_entry *array;
56  unsigned long length;
57 };
58 
59 enum unw_where {
60  UNW_WHERE_NONE, /* register isn't saved at all */
61  UNW_WHERE_GR, /* register is saved in a general register */
62  UNW_WHERE_FR, /* register is saved in a floating-point register */
63  UNW_WHERE_BR, /* register is saved in a branch register */
64  UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */
65  UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */
66  /*
67  * At the end of each prologue these locations get resolved to
68  * UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively:
69  */
70  UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */
71  UNW_WHERE_GR_SAVE /* register is saved in next general register */
72 };
73 
74 #define UNW_WHEN_NEVER 0x7fffffff
75 
76 struct unw_reg_info {
77  unsigned long val; /* save location: register number or offset */
78  enum unw_where where; /* where the register gets saved */
79  int when; /* when the register gets saved */
80 };
81 
82 struct unw_reg_state {
83  struct unw_reg_state *next; /* next (outer) element on state stack */
84  struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
85 };
86 
88  struct unw_labeled_state *next; /* next labeled state (or NULL) */
89  unsigned long label; /* label for this state */
91 };
92 
94  unsigned int first_region : 1; /* is this the first region? */
95  unsigned int done : 1; /* are we done scanning descriptors? */
96  unsigned int any_spills : 1; /* got any register spills? */
97  unsigned int in_body : 1; /* are we inside a body (as opposed to a prologue)? */
98  unsigned long flags; /* see UNW_FLAG_* in unwind.h */
99 
100  u8 *imask; /* imask of spill_mask record or NULL */
101  unsigned long pr_val; /* predicate values */
102  unsigned long pr_mask; /* predicate mask */
103  long spill_offset; /* psp-relative offset for spill base */
109 
110  u8 gr_save_loc; /* next general register to use for saving a register */
111  u8 return_link_reg; /* branch register in which the return link is passed */
112 
113  struct unw_labeled_state *labeled_states; /* list of all labeled states */
114  struct unw_reg_state curr; /* current state */
115 };
116 
118  UNW_NAT_NONE, /* NaT not represented */
119  UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */
120  UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */
121  UNW_NAT_REGSTK /* NaT is in rnat */
122 };
123 
125  UNW_INSN_ADD, /* s[dst] += val */
126  UNW_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */
127  UNW_INSN_ADD_SP, /* s[dst] = (s.sp + val) */
128  UNW_INSN_MOVE, /* s[dst] = s[val] */
129  UNW_INSN_MOVE2, /* s[dst] = s[val]; s[dst+1] = s[val+1] */
130  UNW_INSN_MOVE_STACKED, /* s[dst] = ia64_rse_skip(*s.bsp, val) */
131  UNW_INSN_SETNAT_MEMSTK, /* s[dst+1].nat.type = MEMSTK;
132  s[dst+1].nat.off = *s.pri_unat - s[dst] */
133  UNW_INSN_SETNAT_TYPE, /* s[dst+1].nat.type = val */
134  UNW_INSN_LOAD, /* s[dst] = *s[val] */
135  UNW_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */
136  UNW_INSN_MOVE_CONST, /* s[dst] = constant reg "val" */
137 };
138 
139 struct unw_insn {
140  unsigned int opc : 4;
141  unsigned int dst : 9;
142  signed int val : 19;
143 };
144 
145 /*
146  * Preserved general static registers (r4-r7) give rise to two script
147  * instructions; everything else yields at most one instruction; at
148  * the end of the script, the psp gets popped, accounting for one more
149  * instruction.
150  */
151 #define UNW_MAX_SCRIPT_LEN (UNW_NUM_REGS + 5)
152 
153 struct unw_script {
154  unsigned long ip; /* ip this script is for */
155  unsigned long pr_mask; /* mask of predicates script depends on */
156  unsigned long pr_val; /* predicate values this script is for */
158  unsigned int flags; /* see UNW_FLAG_* in unwind.h */
159  unsigned short lru_chain; /* used for least-recently-used chain */
160  unsigned short coll_chain; /* used for hash collisions */
161  unsigned short hint; /* hint for next script to try (or -1) */
162  unsigned short count; /* number of instructions in script */
164 };