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