#define UNW_VER(x) ((x) >> 48)
#define UNW_FLAG_MASK 0x0000ffff00000000L
#define UNW_FLAG_OSMASK 0x0000f00000000000L
#define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
#define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
#define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
struct uwtable_ent {
uint64_t start;
uint64_t end;
char *infoptr;
};
enum regrecord_type{
UNSAVED,
IMMED,
BRREL,
GRREL,
SPREL,
PSPREL
};
struct regstate {
enum regrecord_type where;
uint64_t when;
#define INVALID -1UL
uint64_t offset;
};
struct staterecord {
struct regstate bsp;
struct regstate psp;
struct regstate rp;
struct regstate pfs;
};
struct unwind_frame {
uint64_t bsp;
uint64_t psp;
uint64_t rp;
uint64_t pfs;
uint64_t sp;
};
void buildrecordchain(uint64_t, struct recordchain *);
void initrecord(struct staterecord *);
void modifyrecord(struct staterecord *, struct recordchain *, uint64_t);
void pushrecord(struct staterecord *);
void poprecord(struct staterecord *, int);
void dump_staterecord(struct staterecord *);
void clonerecordstack(u_int);
void switchrecordstack(u_int);
struct uwtable_ent *get_unwind_table_entry(uint64_t);
void patchunwindframe(struct unwind_frame *, uint64_t, uint64_t);
void updateregs(struct unwind_frame *uwf, struct staterecord *, uint64_t);
struct uwtable_ent * get_unwind_table_entry(uint64_t ip);
struct staterecord *buildrecordstack(struct recordchain *, uint64_t);
void dump_recordchain(struct recordchain *);
#define IA64_CFM_SOF(x) ((x) & 0x7f)
#define IA64_CFM_SOL(x) (((x) >> 7) & 0x7f)
#define IA64_CFM_SOR(x) (((x) >> 14) & 0x0f)
#define IA64_CFM_RRB_GR(x) (((x) >> 18) & 0x7f)
#define IA64_CFM_RRB_FR(x) (((x) >> 25) & 0x7f)
#define IA64_CFM_RRB_PR(x) (((x) >> 32) & 0x3f)
#define IA64_RNATINDEX(x) (((x) & 0x1f8) >> 3)
#define ia64_rnat_adjust ia64_bsp_adjust_call
static __inline uint64_t
ia64_bsp_adjust_call(uint64_t bsp, int sol)
{
bsp += ((sol + (IA64_RNATINDEX(bsp) + sol) / 63) << 3);
return bsp;
}
static __inline uint64_t
ia64_bsp_adjust_ret(uint64_t bsp, int sol)
{
bsp -= ((sol + (62 - IA64_RNATINDEX(bsp) + sol) / 63) << 3);
return bsp;
}
static __inline uint64_t
ia64_getrse_gr(uint64_t bsp, uint64_t gr)
{
bsp = ia64_bsp_adjust_call(bsp, gr);
return *(uint64_t *) bsp;
}