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