uwx.h revision 120925
1/* 2 * Copyright (c) 2002,2003 Hewlett-Packard Company 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 */ 22 23#ifndef _KERNEL 24#include <stdlib.h> 25#include <inttypes.h> 26#else 27#include <sys/param.h> 28#include <sys/systm.h> 29#endif 30 31/* Unwind environment structure (opaque) */ 32struct uwx_env; 33 34/* Allocate and free callbacks */ 35typedef void *(*alloc_cb)(size_t size); 36typedef void (*free_cb)(void *ptr); 37extern int uwx_register_alloc_cb(alloc_cb alloc, free_cb free); 38 39/* Allocate and initialize an unwind environment */ 40extern struct uwx_env *uwx_init(void); 41 42/* Free an unwind environment */ 43extern int uwx_free(struct uwx_env *env); 44 45/* Put unwind express into cross-process mode */ 46extern int uwx_set_remote(struct uwx_env *env, int is_big_endian_target); 47 48/* Copy-in callback */ 49typedef int (*copyin_cb)( 50 int request, /* request code (see below) */ 51 char *loc, /* local (destination) address */ 52 uint64_t rem, /* remote (source) address */ 53 int len, /* number of bytes to copy */ 54 intptr_t tok); /* callback token */ 55 56/* Lookup IP callback */ 57typedef int (*lookupip_cb)( 58 int request, /* request code (see below) */ 59 uint64_t ip, /* IP of current frame */ 60 intptr_t tok, /* callback token */ 61 uint64_t **vecp); /* parameter vector (in/out) */ 62 63/* Register copy-in and lookup IP callbacks */ 64extern int uwx_register_callbacks( 65 struct uwx_env *env, /* unwind environment */ 66 intptr_t tok, /* callback token */ 67 copyin_cb copyin, /* copy-in callback */ 68 lookupip_cb lookupip); /* lookup IP callback */ 69 70/* Initialize a context with the basic info needed to start an unwind */ 71extern int uwx_init_context( 72 struct uwx_env *env, /* unwind environment */ 73 uint64_t ip, /* IP (instruction pointer) */ 74 uint64_t sp, /* SP (stack pointer) */ 75 uint64_t bsp, /* BSP (backing store pointer) */ 76 uint64_t cfm); /* CFM (current frame marker) */ 77 78/* Set the value of a specific register in the current context (non fp) */ 79extern int uwx_set_reg( 80 struct uwx_env *env, /* unwind environment */ 81 int regid, /* register id (see below) */ 82 uint64_t val); /* register value */ 83 84/* Set the value of a floating-point register in the current context */ 85extern int uwx_set_fr( 86 struct uwx_env *env, /* unwind environment */ 87 int regid, /* register id (see below) */ 88 uint64_t *val); /* register value (ptr to 16 bytes) */ 89 /* (memory spill format) */ 90 91/* Initialize the unwind history */ 92extern int uwx_init_history(struct uwx_env *env); 93 94/* Step one frame */ 95extern int uwx_step(struct uwx_env *env); 96 97/* Get symbol information, if available, for current frame */ 98extern int uwx_get_sym_info( 99 struct uwx_env *env, /* unwind environment */ 100 char **modp, /* load module name (out) */ 101 char **symp, /* function name (out) */ 102 uint64_t *offsetp); /* offset from start of function (out) */ 103 104/* Get the value of a register from the current context */ 105extern int uwx_get_reg( 106 struct uwx_env *env, /* unwind environment */ 107 int regid, /* register id (see below) */ 108 uint64_t *valp); /* register value (out) */ 109 110/* Get the NaT bit of a GR from the current context */ 111extern int uwx_get_nat( 112 struct uwx_env *env, /* unwind environment */ 113 int regid, /* register id (see below) */ 114 int *natp); /* NaT value (out: 0 or 1) */ 115 116/* Get the spill location for a register in the current context */ 117extern int uwx_get_spill_loc( 118 struct uwx_env *env, /* unwind environment */ 119 int regid, /* register id (see below) */ 120 uint64_t *dispp); /* disposition code (see below) (out) */ 121 122/* Get the ABI context code (if uwx_step returned UWX_ABI_FRAME) */ 123extern int uwx_get_abi_context_code(struct uwx_env *env); 124 125/* Return status codes for uwx_ APIs */ 126#define UWX_OK 0 127#define UWX_BOTTOM 1 /* Hit bottom of stack */ 128#define UWX_ABI_FRAME 2 /* Hit ABI-dependent frame */ 129#define UWX_ERR_NOENV (-1) /* No uwx_env allocated */ 130#define UWX_ERR_IPNOTFOUND (-2) /* Lookup IP c/b returned NOTFOUND */ 131#define UWX_ERR_LOOKUPERR (-3) /* Lookup IP c/b returned ERR */ 132#define UWX_ERR_BADKEY (-4) /* Bad result vector key */ 133#define UWX_ERR_COPYIN_UTBL (-5) /* Error reading unwind table */ 134#define UWX_ERR_COPYIN_UINFO (-6) /* Error reading unwind info */ 135#define UWX_ERR_COPYIN_MSTK (-7) /* Error reading memory stack */ 136#define UWX_ERR_COPYIN_RSTK (-8) /* Error reading register stack */ 137#define UWX_ERR_COPYIN_REG (-9) /* Error reading context register */ 138#define UWX_ERR_NOUENTRY (-10) /* No unwind table entry for ip */ 139#define UWX_ERR_NOUDESC (-11) /* No unwind descriptor covers ip */ 140#define UWX_ERR_BADUDESC (-12) /* Bad unwind descriptor */ 141#define UWX_ERR_NOMEM (-13) /* Out of memory */ 142#define UWX_ERR_PROLOG_UF (-14) /* Prologue underflow */ 143#define UWX_ERR_UNDEFLABEL (-15) /* Undefined label in copy_state */ 144#define UWX_ERR_BADREGID (-16) /* Bad register identifier */ 145#define UWX_ERR_CANTUNWIND (-17) /* Can't unwind */ 146#define UWX_ERR_NOCALLBACKS (-18) /* No callbacks registered */ 147#define UWX_ERR_NOCONTEXT (-19) /* Context not initialized */ 148 149/* Request codes for copyin callback */ 150#define UWX_COPYIN_UINFO 1 /* Reading unwind info */ 151#define UWX_COPYIN_MSTACK 2 /* Reading memory stack */ 152#define UWX_COPYIN_RSTACK 3 /* Reading RSE backing store */ 153#define UWX_COPYIN_REG 4 /* Reading initial register state */ 154 155/* Request codes for lookup IP callback */ 156#define UWX_LKUP_LOOKUP 1 /* Lookup IP */ 157#define UWX_LKUP_FREE 2 /* Free result vector */ 158#define UWX_LKUP_SYMBOLS 3 /* Lookup symbolic information */ 159 160/* Return status codes for lookup IP callback */ 161#define UWX_LKUP_NOTFOUND 0 /* IP not found */ 162#define UWX_LKUP_ERR 1 /* Other error */ 163#define UWX_LKUP_UTABLE 2 /* Returned ref to unwind table */ 164#define UWX_LKUP_FDESC 3 /* Returned frame description */ 165#define UWX_LKUP_SYMINFO 4 /* Returned symbolic information */ 166 167/* The lookup IP callback receives a parameter vector, and returns */ 168/* one on success. This vector is a series of key/value pairs; each */ 169/* even-numbered slot is a key, and each odd-numbered slot is a */ 170/* corresponding value. The vector is terminated by a pair whose */ 171/* key is 0. */ 172#define UWX_KEY_END 0 /* End of vector */ 173 174/* Keys passed to lookup IP callback */ 175#define UWX_KEY_PREDS 1 /* Predicate registers */ 176 177/* Keys returned with UWX_LKUP_UTABLE */ 178/* These key/value pairs describe the unwind table corresponding */ 179/* to the load module in which the current IP resides. */ 180#define UWX_KEY_TBASE 1 /* Base address of text seg */ 181#define UWX_KEY_UFLAGS 2 /* Unwind flags */ 182#define UWX_KEY_USTART 3 /* Base of unwind tbl */ 183#define UWX_KEY_UEND 4 /* End of unwind tbl */ 184 185/* Keys returned with UWX_LKUP_FDESC */ 186/* These key/value pairs describe the state of the frame at the */ 187/* given IP. They are typically used for dynamically-generated code. */ 188#define UWX_KEY_FSIZE 1 /* Frame size */ 189#define UWX_KEY_SPILL(reg_id) (2 | ((reg_id) << 4)) /* Reg spilled */ 190#define UWX_KEY_CONTEXT 3 /* ABI-dep. context */ 191 192/* Keys returned with UWX_LKUP_FDESC or UWX_LKUP_SYMINFO */ 193#define UWX_KEY_MODULE 5 /* Name of load module */ 194#define UWX_KEY_FUNC 6 /* Name of function */ 195#define UWX_KEY_FUNCSTART 7 /* Address of start of function */ 196 197/* Register identifiers */ 198/* For use in UWX_LKUP_FDESC result vectors and context access APIs. */ 199/* "no spill info": These regs aren't spilled directly, so */ 200/* result vectors must not describe these registers. */ 201/* The result vector must describe the related register or */ 202/* pseudo register instead (ip:rp, sp:psp, bsp/cfm:pfs). */ 203/* "pseudo register": Not a machine register, but treated as */ 204/* one for unwind purposes. */ 205#define UWX_REG_IP 0 /* ip (no spill info) */ 206#define UWX_REG_SP 1 /* sp (no spill info) */ 207#define UWX_REG_BSP 2 /* ar.bsp (no spill info) */ 208#define UWX_REG_CFM 3 /* cfm (no spill info) */ 209#define UWX_REG_RP 4 /* rp (pseudo-register) */ 210#define UWX_REG_PSP 5 /* psp (pseudo-register) */ 211#define UWX_REG_PFS 6 /* pfs (pseudo-register) */ 212#define UWX_REG_PREDS 7 /* p0 - p63 */ 213#define UWX_REG_PRIUNAT 8 /* primary unat (pseudo-register) */ 214#define UWX_REG_AR_PFS 9 /* ar.pfs */ 215#define UWX_REG_AR_BSPSTORE 10 /* ar.bspstore */ 216#define UWX_REG_AR_RNAT 11 /* ar.rnat */ 217#define UWX_REG_AR_UNAT 12 /* ar.unat */ 218#define UWX_REG_AR_FPSR 13 /* ar.fpsr */ 219#define UWX_REG_AR_LC 14 /* ar.lc */ 220#define UWX_REG_GR(gr) (0x100 | (gr)) 221#define UWX_REG_FR(fr) (0x200 | (fr)) 222#define UWX_REG_BR(br) (0x300 | (br)) 223 224/* for backwards compatibility with previous releases... */ 225#define UWX_REG_BSPSTORE UWX_REG_AR_BSPSTORE 226#define UWX_REG_RNAT UWX_REG_AR_RNAT 227#define UWX_REG_UNAT UWX_REG_AR_UNAT 228#define UWX_REG_FPSR UWX_REG_AR_FPSR 229#define UWX_REG_LC UWX_REG_AR_LC 230 231/* Values corresponding to UWX_KEY_SPILL keys indicate the disposition */ 232/* of the spilled register -- either in the memory stack or in another */ 233/* register. The PSP register may also have a disposition of "SPPLUS", */ 234/* indicating that its value is SP plus a fixed constant. */ 235#define UWX_DISP_NONE 0 /* Not spilled */ 236#define UWX_DISP_SPPLUS(k) (1 | (k)) /* PSP = SP+constant */ 237#define UWX_DISP_SPREL(disp) (2 | (disp)) /* Spilled at [SP+disp] */ 238#define UWX_DISP_PSPREL(disp) (3 | (disp)) /* Spilled at [PSP+16-disp] */ 239#define UWX_DISP_REG(reg) (4 | ((reg) << 4)) /* Saved to another reg. */ 240 241/* The uwx_get_spill_loc() routine returns a spill location for a */ 242/* given register in the current context. It will return a disposition */ 243/* code of UWX_DISP_NONE, UWX_DISP_REG(reg), or one of the following */ 244/* to indicate that the spilled value can be found in the memory */ 245/* stack or the register stack backing store. */ 246#define UWX_DISP_MSTK(addr) (5 | (addr)) /* Spilled in mem. stack */ 247#define UWX_DISP_RSTK(addr) (6 | (addr)) /* Spilled in reg. stack */ 248 249/* Extract the disposition code, offset, address, or register id */ 250/* from a disposition returned from uwx_get_spill_loc(). */ 251/* Compare the extracted disp code against UWX_DISP_REG(0), etc. */ 252#define UWX_GET_DISP_CODE(disp) ((int)(disp) & 0x07) 253#define UWX_GET_DISP_OFFSET(disp) ((disp) & ~(uint64_t)0x07) 254#define UWX_GET_DISP_ADDR(disp) ((disp) & ~(uint64_t)0x07) 255#define UWX_GET_DISP_REGID(disp) ((int)(disp) >> 4) 256