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