1 /* $NetBSD: stackframe.h,v 1.2 2010/02/28 15:52:16 snj Exp $ */ 2 3 /* 4 * Contributed to the NetBSD foundation by Cherry G. Mathew 5 */ 6 7 #define UNW_VER(x) ((x) >> 48) 8 #define UNW_FLAG_MASK 0x0000ffff00000000L 9 #define UNW_FLAG_OSMASK 0x0000f00000000000L 10 #define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L) 11 #define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L) 12 #define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL) 13 14 /* Unwind table entry. */ 15 struct uwtable_ent { 16 uint64_t start; 17 uint64_t end; 18 char *infoptr; 19 }; 20 21 22 enum regrecord_type{ 23 UNSAVED, /* Register contents live ( and therefore untouched ). */ 24 IMMED, /* .offset field is the saved content. */ 25 BRREL, /* Register saved in one of the Branch Registers. */ 26 GRREL, /* Register saved in one of the Stacked GRs 27 * regstate.offset contains GR number (usually >= 32) 28 */ 29 SPREL, /* Register saved on the memory stack frame. 30 * regstate.offset is in words; ie; location == (sp + 4 * spoff). 31 */ 32 PSPREL /* Register saved on the memory stack frame but offseted via psp 33 * regstate.offset is in words; ie; location == (psp + 16 �– 4 * pspoff) 34 */ 35 }; 36 37 38 struct regstate { 39 enum regrecord_type where; 40 uint64_t when; 41 42 #define INVALID -1UL /* Indicates uninitialised offset value. */ 43 uint64_t offset; 44 }; 45 46 47 /* A staterecord contains the net state of 48 * sequentially parsing unwind descriptors. 49 * The entry state of the current prologue region 50 * is the exit state of the previous region. 51 * We record info about registers we care about 52 * ie; just enough to re-construct an unwind frame, 53 * and ignore the rest. 54 * Initial state is where = UNSAVED for all .where fields. 55 */ 56 57 struct staterecord { 58 struct regstate bsp; 59 struct regstate psp; 60 struct regstate rp; 61 struct regstate pfs; 62 }; 63 64 /* The unwind frame is a simpler version of the trap frame 65 * and contains a subset of preserved registers, which are 66 * useful in unwinding an ia64 stack frame. 67 * Keep this in sync with the staterecord. See: stackframe.c:updateregs() 68 */ 69 70 struct unwind_frame { 71 uint64_t bsp; /* Base of the RSE. !!! XXX: Stack Frame discontinuities */ 72 uint64_t psp; /* Mem stack (variable size) base. */ 73 uint64_t rp; /* Return Pointer */ 74 uint64_t pfs; /* Previous Frame size info */ 75 76 /* Don't mirror anything below this line with struct staterecord */ 77 uint64_t sp; 78 }; 79 80 81 void buildrecordchain(uint64_t, struct recordchain *); 82 void initrecord(struct staterecord *); 83 void modifyrecord(struct staterecord *, struct recordchain *, uint64_t); 84 void pushrecord(struct staterecord *); 85 void poprecord(struct staterecord *, int); 86 void dump_staterecord(struct staterecord *); 87 void clonerecordstack(u_int); 88 void switchrecordstack(u_int); 89 90 struct uwtable_ent * 91 get_unwind_table_entry(uint64_t); 92 void 93 patchunwindframe(struct unwind_frame *, uint64_t, uint64_t); 94 void 95 updateregs(struct unwind_frame *uwf, struct staterecord *, uint64_t) ; 96 struct uwtable_ent * get_unwind_table_entry(uint64_t ip); 97 98 struct staterecord * 99 buildrecordstack(struct recordchain *, uint64_t); 100 void dump_recordchain(struct recordchain *); 101 102 /* Convenience macros to decompose CFM & ar.pfs. */ 103 #define IA64_CFM_SOF(x) ((x) & 0x7f) 104 #define IA64_CFM_SOL(x) (((x) >> 7) & 0x7f) 105 #define IA64_CFM_SOR(x) (((x) >> 14) & 0x0f) 106 #define IA64_CFM_RRB_GR(x) (((x) >> 18) & 0x7f) 107 #define IA64_CFM_RRB_FR(x) (((x) >> 25) & 0x7f) 108 #define IA64_CFM_RRB_PR(x) (((x) >> 32) & 0x3f) 109 110 #define IA64_RNATINDEX(x) (((x) & 0x1f8) >> 3) 111 112 /* Obeys Table 6:2 RSE Operation Instructions and State Modification */ 113 114 /* These functions adjust for RSE rnat saves to bsp in the forward and 115 * reverse directions respectively. 116 */ 117 #define ia64_rnat_adjust ia64_bsp_adjust_call 118 119 static __inline uint64_t 120 ia64_bsp_adjust_call(uint64_t bsp, int sol) 121 { 122 bsp += ((sol + (IA64_RNATINDEX(bsp) + sol) / 63) << 3); 123 return bsp; 124 } 125 126 static __inline uint64_t 127 ia64_bsp_adjust_ret(uint64_t bsp, int sol) 128 { 129 bsp -= ((sol + (62 - IA64_RNATINDEX(bsp) + sol) / 63) << 3); 130 return bsp; 131 } 132 133 static __inline uint64_t 134 ia64_getrse_gr(uint64_t bsp, uint64_t gr) 135 { 136 bsp = ia64_bsp_adjust_call(bsp, gr); 137 return *(uint64_t *) bsp; 138 } 139