1115013Smarcel/*
2160157SmarcelCopyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
3121642SmarcelPermission is hereby granted, free of charge, to any person
4121642Smarcelobtaining a copy of this software and associated documentation
5121642Smarcelfiles (the "Software"), to deal in the Software without
6121642Smarcelrestriction, including without limitation the rights to use,
7121642Smarcelcopy, modify, merge, publish, distribute, sublicense, and/or sell
8121642Smarcelcopies of the Software, and to permit persons to whom the
9121642SmarcelSoftware is furnished to do so, subject to the following
10121642Smarcelconditions:
11115013Smarcel
12121642SmarcelThe above copyright notice and this permission notice shall be
13121642Smarcelincluded in all copies or substantial portions of the Software.
14121642Smarcel
15121642SmarcelTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16121642SmarcelEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17121642SmarcelOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18121642SmarcelNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19121642SmarcelHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20121642SmarcelWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21121642SmarcelFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22121642SmarcelOTHER DEALINGS IN THE SOFTWARE.
23121642Smarcel*/
24121642Smarcel
25129059Smarcel#ifndef __UWX_INCLUDED
26129059Smarcel#define __UWX_INCLUDED 1
27129059Smarcel
28160163Smarcel#ifndef _KERNEL
29115013Smarcel#include <stdlib.h>
30115013Smarcel#include <inttypes.h>
31160163Smarcel#else
32160163Smarcel#include <sys/param.h>
33160163Smarcel#include <sys/systm.h>
34160163Smarcel#endif
35115013Smarcel
36129059Smarcel#if defined(__cplusplus)
37129059Smarcel#define __EXTERN_C extern "C"
38129059Smarcel#else
39129059Smarcel#define __EXTERN_C extern
40129059Smarcel#endif
41129059Smarcel
42160157Smarcel#define UWX_VERSION 3		/* Version id for callback interfaces */
43129059Smarcel
44115013Smarcel/* Unwind environment structure (opaque) */
45115013Smarcelstruct uwx_env;
46115013Smarcel
47160157Smarcel/* Symbol Cache for uwx_find_symbol (opaque) */
48160157Smarcelstruct uwx_symbol_cache;
49160157Smarcel
50115013Smarcel/* Allocate and free callbacks */
51115013Smarceltypedef void *(*alloc_cb)(size_t size);
52115013Smarceltypedef void (*free_cb)(void *ptr);
53129059Smarcel__EXTERN_C int uwx_register_alloc_cb(alloc_cb alloc, free_cb free);
54115013Smarcel
55115013Smarcel/* Allocate and initialize an unwind environment */
56129059Smarcel__EXTERN_C struct uwx_env *uwx_init(void);
57115013Smarcel
58115013Smarcel/* Free an unwind environment */
59129059Smarcel__EXTERN_C int uwx_free(struct uwx_env *env);
60115013Smarcel
61115013Smarcel/* Put unwind express into cross-process mode */
62129059Smarcel__EXTERN_C int uwx_set_remote(struct uwx_env *env, int is_big_endian_target);
63115013Smarcel
64160157Smarcel/* Put unwind express into reduced-context mode (no floating-point regs) */
65160157Smarcel__EXTERN_C int uwx_set_nofr(struct uwx_env *env);
66160157Smarcel
67115013Smarcel/* Copy-in callback */
68115013Smarceltypedef int (*copyin_cb)(
69115013Smarcel    int request,		/* request code (see below) */
70115013Smarcel    char *loc,			/* local (destination) address */
71115013Smarcel    uint64_t rem,		/* remote (source) address */
72115013Smarcel    int len,			/* number of bytes to copy */
73115013Smarcel    intptr_t tok);		/* callback token */
74115013Smarcel
75115013Smarcel/* Lookup IP callback */
76115013Smarceltypedef int (*lookupip_cb)(
77115013Smarcel    int request,		/* request code (see below) */
78115013Smarcel    uint64_t ip,		/* IP of current frame */
79115013Smarcel    intptr_t tok,		/* callback token */
80115013Smarcel    uint64_t **vecp);		/* parameter vector (in/out) */
81115013Smarcel
82115013Smarcel/* Register copy-in and lookup IP callbacks */
83129059Smarcel__EXTERN_C int uwx_register_callbacks(
84115013Smarcel    struct uwx_env *env,	/* unwind environment */
85115013Smarcel    intptr_t tok,		/* callback token */
86115013Smarcel    copyin_cb copyin,		/* copy-in callback */
87115013Smarcel    lookupip_cb lookupip);	/* lookup IP callback */
88115013Smarcel
89115013Smarcel/* Initialize a context with the basic info needed to start an unwind */
90129059Smarcel__EXTERN_C int uwx_init_context(
91115013Smarcel    struct uwx_env *env,	/* unwind environment */
92115013Smarcel    uint64_t ip,		/* IP (instruction pointer) */
93115013Smarcel    uint64_t sp,		/* SP (stack pointer) */
94115013Smarcel    uint64_t bsp,		/* BSP (backing store pointer) */
95115013Smarcel    uint64_t cfm);		/* CFM (current frame marker) */
96115013Smarcel
97115013Smarcel/* Set the value of a specific register in the current context (non fp) */
98129059Smarcel__EXTERN_C int uwx_set_reg(
99115013Smarcel    struct uwx_env *env,	/* unwind environment */
100115013Smarcel    int regid,			/* register id (see below) */
101115013Smarcel    uint64_t val);		/* register value */
102115013Smarcel
103115013Smarcel/* Set the value of a floating-point register in the current context */
104129059Smarcel__EXTERN_C int uwx_set_fr(
105115013Smarcel    struct uwx_env *env,	/* unwind environment */
106115013Smarcel    int regid,			/* register id (see below) */
107115013Smarcel    uint64_t *val);		/* register value (ptr to 16 bytes) */
108115013Smarcel				/*   (memory spill format) */
109115013Smarcel
110115013Smarcel/* Initialize the unwind history */
111129059Smarcel__EXTERN_C int uwx_init_history(struct uwx_env *env);
112115013Smarcel
113115013Smarcel/* Step one frame */
114129059Smarcel__EXTERN_C int uwx_step(struct uwx_env *env);
115115013Smarcel
116160157Smarcel/* Get module name and text base, if available, for current frame */
117160157Smarcel__EXTERN_C int uwx_get_module_info(
118160157Smarcel    struct uwx_env *env,	/* unwind environment */
119160157Smarcel    char **modp,		/* load module name (out)  */
120160157Smarcel    uint64_t *text_base);	/* base address of text segment (out)  */
121160157Smarcel
122160157Smarcel/* Get function start address for current frame */
123160157Smarcel__EXTERN_C int uwx_get_funcstart(
124160157Smarcel    struct uwx_env *env,	/* unwind environment */
125160157Smarcel    uint64_t *funcstart);	/* function start address (out)  */
126160157Smarcel
127115013Smarcel/* Get symbol information, if available, for current frame */
128129059Smarcel__EXTERN_C int uwx_get_sym_info(
129115013Smarcel    struct uwx_env *env,	/* unwind environment */
130115013Smarcel    char **modp,		/* load module name (out)  */
131115013Smarcel    char **symp,		/* function name (out)  */
132115013Smarcel    uint64_t *offsetp);		/* offset from start of function (out)  */
133115013Smarcel
134160157Smarcel/* Get symbol information, given module name and IP */
135160157Smarcel__EXTERN_C int uwx_find_symbol(
136160157Smarcel    struct uwx_env *env,	/* unwind environment */
137160157Smarcel    struct uwx_symbol_cache **cachep,
138160157Smarcel				/* ptr to symbol cache ptr (in/out) */
139160157Smarcel    char *mod,			/* load module name */
140160157Smarcel    uint64_t relip,		/* IP, relative to text segment  */
141160157Smarcel    char **symp,		/* function name (out) */
142160157Smarcel    uint64_t *offsetp);		/* offset from start of function (out) */
143160157Smarcel
144160157Smarcel/* Release memory used by symbol cache */
145160157Smarcel__EXTERN_C void uwx_release_symbol_cache(
146160157Smarcel    struct uwx_env *env,	/* unwind environment */
147160157Smarcel    struct uwx_symbol_cache *symbol_cache);
148160157Smarcel				/* symbol cache ptr */
149160157Smarcel
150115013Smarcel/* Get the value of a register from the current context */
151129059Smarcel__EXTERN_C int uwx_get_reg(
152115013Smarcel    struct uwx_env *env,	/* unwind environment */
153115013Smarcel    int regid,			/* register id (see below) */
154115013Smarcel    uint64_t *valp);		/* register value (out) */
155115013Smarcel
156115013Smarcel/* Get the NaT bit of a GR from the current context */
157129059Smarcel__EXTERN_C int uwx_get_nat(
158115013Smarcel    struct uwx_env *env,	/* unwind environment */
159115013Smarcel    int regid,			/* register id (see below) */
160115013Smarcel    int *natp);			/* NaT value (out: 0 or 1) */
161115013Smarcel
162115013Smarcel/* Get the spill location for a register in the current context */
163129059Smarcel__EXTERN_C int uwx_get_spill_loc(
164115013Smarcel    struct uwx_env *env,	/* unwind environment */
165115013Smarcel    int regid,			/* register id (see below) */
166115013Smarcel    uint64_t *dispp);		/* disposition code (see below) (out) */
167115013Smarcel
168115013Smarcel/* Get the ABI context code (if uwx_step returned UWX_ABI_FRAME) */
169129059Smarcel__EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
170115013Smarcel
171160157Smarcel/* Increment/Decrement the bsp by a number of slots */
172160157Smarcel/* (accounts for NaT collections) */
173160157Smarcel__EXTERN_C uint64_t uwx_add_to_bsp(uint64_t bsp, int nslots);
174160157Smarcel
175115013Smarcel/* Return status codes for uwx_ APIs */
176115013Smarcel#define UWX_OK			0
177115013Smarcel#define UWX_BOTTOM		1	/* Hit bottom of stack */
178115013Smarcel#define UWX_ABI_FRAME		2	/* Hit ABI-dependent frame */
179115013Smarcel#define UWX_ERR_NOENV		(-1)	/* No uwx_env allocated */
180115013Smarcel#define UWX_ERR_IPNOTFOUND	(-2)	/* Lookup IP c/b returned NOTFOUND */
181115013Smarcel#define UWX_ERR_LOOKUPERR	(-3)	/* Lookup IP c/b returned ERR */
182115013Smarcel#define UWX_ERR_BADKEY		(-4)	/* Bad result vector key */
183115013Smarcel#define UWX_ERR_COPYIN_UTBL	(-5)	/* Error reading unwind table */
184115013Smarcel#define UWX_ERR_COPYIN_UINFO	(-6)	/* Error reading unwind info */
185115013Smarcel#define UWX_ERR_COPYIN_MSTK	(-7)	/* Error reading memory stack */
186115013Smarcel#define UWX_ERR_COPYIN_RSTK	(-8)	/* Error reading register stack */
187115013Smarcel#define UWX_ERR_COPYIN_REG	(-9)	/* Error reading context register */
188115013Smarcel#define UWX_ERR_NOUENTRY	(-10)	/* No unwind table entry for ip */
189115013Smarcel#define UWX_ERR_NOUDESC		(-11)	/* No unwind descriptor covers ip */
190115013Smarcel#define UWX_ERR_BADUDESC	(-12)	/* Bad unwind descriptor */
191115013Smarcel#define UWX_ERR_NOMEM		(-13)	/* Out of memory */
192115013Smarcel#define UWX_ERR_PROLOG_UF	(-14)	/* Prologue underflow */
193115013Smarcel#define UWX_ERR_UNDEFLABEL	(-15)	/* Undefined label in copy_state */
194115013Smarcel#define UWX_ERR_BADREGID	(-16)	/* Bad register identifier */
195115013Smarcel#define UWX_ERR_CANTUNWIND	(-17)	/* Can't unwind */
196115013Smarcel#define UWX_ERR_NOCALLBACKS	(-18)	/* No callbacks registered */
197115013Smarcel#define UWX_ERR_NOCONTEXT	(-19)	/* Context not initialized */
198160157Smarcel#define UWX_ERR_UCACCESS	(-20)	/* Failure in libuca */
199160157Smarcel#define UWX_ERR_NOSYM		(-21)	/* Symbol not found */
200115013Smarcel
201115013Smarcel/* Request codes for copyin callback */
202115013Smarcel#define UWX_COPYIN_UINFO	1	/* Reading unwind info */
203115013Smarcel#define UWX_COPYIN_MSTACK	2	/* Reading memory stack */
204115013Smarcel#define UWX_COPYIN_RSTACK	3	/* Reading RSE backing store */
205115013Smarcel#define UWX_COPYIN_REG		4	/* Reading initial register state */
206115013Smarcel
207115013Smarcel/* Request codes for lookup IP callback */
208115013Smarcel#define UWX_LKUP_LOOKUP		1	/* Lookup IP */
209115013Smarcel#define UWX_LKUP_FREE		2	/* Free result vector */
210115013Smarcel#define UWX_LKUP_SYMBOLS	3	/* Lookup symbolic information */
211160157Smarcel#define UWX_LKUP_MODULE		4	/* Get module name */
212115013Smarcel
213115013Smarcel/* Return status codes for lookup IP callback */
214115013Smarcel#define UWX_LKUP_NOTFOUND	0	/* IP not found */
215115013Smarcel#define UWX_LKUP_ERR		1	/* Other error */
216115013Smarcel#define UWX_LKUP_UTABLE		2	/* Returned ref to unwind table */
217115013Smarcel#define UWX_LKUP_FDESC		3	/* Returned frame description */
218115013Smarcel#define UWX_LKUP_SYMINFO	4	/* Returned symbolic information */
219129059Smarcel#define UWX_LKUP_REMAP		5	/* Returned remapped IP */
220129059Smarcel#define UWX_LKUP_UINFO		6	/* Returned unw info block ptr */
221115013Smarcel
222115013Smarcel/* The lookup IP callback receives a parameter vector, and returns */
223115013Smarcel/* one on success. This vector is a series of key/value pairs; each */
224115013Smarcel/* even-numbered slot is a key, and each odd-numbered slot is a */
225115013Smarcel/* corresponding value. The vector is terminated by a pair whose */
226115013Smarcel/* key is 0. */
227115013Smarcel#define UWX_KEY_END		0	/* End of vector */
228115013Smarcel
229115013Smarcel/* Keys passed to lookup IP callback */
230115013Smarcel#define UWX_KEY_PREDS		1	/* Predicate registers */
231129059Smarcel#define UWX_KEY_VERSION		2	/* Version id of unwind engine */
232129059Smarcel/* UWX_KEY_FUNCSTART (below) may also be passed with the UWX_LKUP_SYMINFO */
233129059Smarcel/* request. */
234115013Smarcel
235115013Smarcel/* Keys returned with UWX_LKUP_UTABLE */
236115013Smarcel/* These key/value pairs describe the unwind table corresponding */
237115013Smarcel/* to the load module in which the current IP resides. */
238115013Smarcel#define UWX_KEY_TBASE		1	/* Base address of text seg */
239129059Smarcel#define UWX_KEY_UFLAGS		2	/* Unwind flags (optional) */
240115013Smarcel#define UWX_KEY_USTART		3	/* Base of unwind tbl */
241115013Smarcel#define UWX_KEY_UEND		4	/* End of unwind tbl */
242160157Smarcel#define UWX_KEY_GP		7	/* GP value for module */
243115013Smarcel
244115013Smarcel/* Keys returned with UWX_LKUP_FDESC */
245115013Smarcel/* These key/value pairs describe the state of the frame at the */
246115013Smarcel/* given IP. They are typically used for dynamically-generated code. */
247129059Smarcel/* If UWX_KEY_CONTEXT is returned, it must be the only key returned. */
248160157Smarcel/* Use UWX_KEY_GP for the module's gp value. */
249115013Smarcel#define UWX_KEY_FSIZE		1			/* Frame size */
250115013Smarcel#define UWX_KEY_SPILL(reg_id)	(2 | ((reg_id) << 4))	/* Reg spilled */
251115013Smarcel#define UWX_KEY_CONTEXT		3 			/* ABI-dep. context */
252115013Smarcel
253129059Smarcel/* Keys returned with UWX_LKUP_REMAP */
254129059Smarcel#define UWX_KEY_NEWIP		5	/* Remapped IP */
255115013Smarcel
256129059Smarcel/* Keys returned with UWX_LKUP_UINFO */
257160157Smarcel/* Use UWX_KEY_GP for the module's gp value. */
258129059Smarcel/* Use UWX_KEY_FUNCSTART for the start address of the function */
259129059Smarcel/* Use UWX_KEY_UFLAGS for the unwind flags (optional) */
260129059Smarcel#define UWX_KEY_UINFO 		6	/* Address of unwind info block */
261129059Smarcel
262129059Smarcel/* Keys returned with UWX_LKUP_SYMINFO */
263129059Smarcel/* These keys may be returned with UWX_LKUP_FDESC or UWX_LKUP_UINFO, */
264129059Smarcel/* if the information is cheap to obtain. */
265160157Smarcel/* Use UWX_KEY_TBASE for the base of the text segment */
266129059Smarcel#define UWX_KEY_MODULE		17	/* Name of load module */
267129059Smarcel#define UWX_KEY_FUNC		18	/* Name of function */
268129059Smarcel#define UWX_KEY_FUNCSTART	19	/* Address of start of function */
269129059Smarcel
270115013Smarcel/* Register identifiers */
271115013Smarcel/* For use in UWX_LKUP_FDESC result vectors and context access APIs. */
272115013Smarcel/* "no spill info": These regs aren't spilled directly, so */
273115013Smarcel/*    result vectors must not describe these registers. */
274115013Smarcel/*    The result vector must describe the related register or */
275115013Smarcel/*    pseudo register instead (ip:rp, sp:psp, bsp/cfm:pfs). */
276115013Smarcel/* "pseudo register": Not a machine register, but treated as */
277115013Smarcel/*    one for unwind purposes. */
278115013Smarcel#define UWX_REG_IP		0	/* ip (no spill info) */
279115013Smarcel#define UWX_REG_SP		1	/* sp (no spill info) */
280115013Smarcel#define UWX_REG_BSP		2	/* ar.bsp (no spill info) */
281115013Smarcel#define UWX_REG_CFM		3	/* cfm (no spill info) */
282115013Smarcel#define UWX_REG_RP		4	/* rp (pseudo-register) */
283115013Smarcel#define UWX_REG_PSP		5	/* psp (pseudo-register) */
284120925Smarcel#define UWX_REG_PFS		6	/* pfs (pseudo-register) */
285115013Smarcel#define UWX_REG_PREDS		7	/* p0 - p63 */
286115013Smarcel#define UWX_REG_PRIUNAT		8	/* primary unat (pseudo-register) */
287121642Smarcel#define UWX_REG_AR_BSPSTORE	9	/* ar.bspstore */
288121642Smarcel#define UWX_REG_AR_RNAT		10	/* ar.rnat */
289121642Smarcel#define UWX_REG_AR_UNAT		11	/* ar.unat */
290121642Smarcel#define UWX_REG_AR_FPSR		12	/* ar.fpsr */
291121642Smarcel#define UWX_REG_AR_LC		13	/* ar.lc */
292121642Smarcel#define UWX_REG_AR_PFS		14	/* ar.pfs */
293160157Smarcel#define UWX_REG_GP		15	/* gp (pseudo-register) */
294115013Smarcel#define UWX_REG_GR(gr)		(0x100 | (gr))
295115013Smarcel#define UWX_REG_FR(fr)		(0x200 | (fr))
296115013Smarcel#define UWX_REG_BR(br)		(0x300 | (br))
297115013Smarcel
298120925Smarcel/* for backwards compatibility with previous releases... */
299120925Smarcel#define UWX_REG_BSPSTORE	UWX_REG_AR_BSPSTORE
300120925Smarcel#define UWX_REG_RNAT		UWX_REG_AR_RNAT
301120925Smarcel#define UWX_REG_UNAT		UWX_REG_AR_UNAT
302120925Smarcel#define UWX_REG_FPSR		UWX_REG_AR_FPSR
303120925Smarcel#define UWX_REG_LC		UWX_REG_AR_LC
304120925Smarcel
305115013Smarcel/* Values corresponding to UWX_KEY_SPILL keys indicate the disposition */
306115013Smarcel/* of the spilled register -- either in the memory stack or in another */
307115013Smarcel/* register. The PSP register may also have a disposition of "SPPLUS", */
308115013Smarcel/* indicating that its value is SP plus a fixed constant. */
309115013Smarcel#define UWX_DISP_NONE		0		/* Not spilled */
310115013Smarcel#define UWX_DISP_SPPLUS(k)	(1 | (k))	/* PSP = SP+constant */
311115013Smarcel#define UWX_DISP_SPREL(disp)	(2 | (disp))	/* Spilled at [SP+disp] */
312115013Smarcel#define UWX_DISP_PSPREL(disp)	(3 | (disp))	/* Spilled at [PSP+16-disp] */
313115013Smarcel#define UWX_DISP_REG(reg)	(4 | ((reg) << 4)) /* Saved to another reg. */
314115013Smarcel
315115013Smarcel/* The uwx_get_spill_loc() routine returns a spill location for a */
316115013Smarcel/* given register in the current context. It will return a disposition */
317115013Smarcel/* code of UWX_DISP_NONE, UWX_DISP_REG(reg), or one of the following */
318115013Smarcel/* to indicate that the spilled value can be found in the memory */
319115013Smarcel/* stack or the register stack backing store. */
320115013Smarcel#define UWX_DISP_MSTK(addr)	(5 | (addr))	/* Spilled in mem. stack */
321115013Smarcel#define UWX_DISP_RSTK(addr)	(6 | (addr))	/* Spilled in reg. stack */
322115013Smarcel
323115013Smarcel/* Extract the disposition code, offset, address, or register id */
324115013Smarcel/* from a disposition returned from uwx_get_spill_loc(). */
325115013Smarcel/* Compare the extracted disp code against UWX_DISP_REG(0), etc. */
326115013Smarcel#define UWX_GET_DISP_CODE(disp)		((int)(disp) & 0x07)
327115013Smarcel#define UWX_GET_DISP_OFFSET(disp)	((disp) & ~(uint64_t)0x07)
328115013Smarcel#define UWX_GET_DISP_ADDR(disp)		((disp) & ~(uint64_t)0x07)
329115013Smarcel#define UWX_GET_DISP_REGID(disp)	((int)(disp) >> 4)
330129059Smarcel
331129059Smarcel#undef __EXTERN_C
332129059Smarcel
333129059Smarcel#if defined(__cplusplus)
334129059Smarcel
335129059Smarcelclass UnwindExpress {
336129059Smarcel
337129059Smarcelpublic:
338129059Smarcel
339129059Smarcel    UnwindExpress() {
340129059Smarcel	env = uwx_init();
341129059Smarcel    }
342129059Smarcel
343129059Smarcel    ~UnwindExpress() {
344129059Smarcel	if (env != 0)
345129059Smarcel	    uwx_free(env);
346129059Smarcel	env = 0;
347129059Smarcel    }
348129059Smarcel
349129059Smarcel    int init_context(uint64_t ip, uint64_t sp, uint64_t bsp, uint64_t cfm) {
350129059Smarcel	return uwx_init_context(env, ip, sp, bsp, cfm);
351129059Smarcel    }
352129059Smarcel
353129059Smarcel    int init_history() {
354129059Smarcel	return uwx_init_history(env);
355129059Smarcel    }
356129059Smarcel
357129059Smarcel    int set_reg(int regid, uint64_t val) {
358129059Smarcel	return uwx_set_reg(env, regid, val);
359129059Smarcel    }
360129059Smarcel
361129059Smarcel    int set_fr(int regid, uint64_t *valp) {
362129059Smarcel	return uwx_set_fr(env, regid, valp);
363129059Smarcel    }
364129059Smarcel
365129059Smarcel    int step() {
366129059Smarcel	return uwx_step(env);
367129059Smarcel    }
368129059Smarcel
369160157Smarcel    int get_module_info(char **modp, uint64_t *text_base_p) {
370160157Smarcel	return uwx_get_module_info(env, modp, text_base_p);
371160157Smarcel    }
372160157Smarcel
373160157Smarcel    int get_funcstart(uint64_t *funcstart) {
374160157Smarcel	return uwx_get_funcstart(env, funcstart);
375160157Smarcel    }
376160157Smarcel
377129059Smarcel    int get_sym_info(char **modp, char **symp, uint64_t *offsetp) {
378129059Smarcel	return uwx_get_sym_info(env, modp, symp, offsetp);
379129059Smarcel    }
380129059Smarcel
381160157Smarcel    int find_symbol(struct uwx_symbol_cache **cachep,
382160157Smarcel		char *mod, uint64_t relip, char **symp, uint64_t *offsetp) {
383160157Smarcel	return uwx_find_symbol(env, cachep, mod, relip, symp, offsetp);
384160157Smarcel    }
385160157Smarcel
386160157Smarcel    void release_symbol_cache(struct uwx_symbol_cache *symbol_cache) {
387160157Smarcel	uwx_release_symbol_cache(env, symbol_cache);
388160157Smarcel    }
389160157Smarcel
390129059Smarcel    int get_reg(int regid, uint64_t *valp) {
391129059Smarcel	return uwx_get_reg(env, regid, valp);
392129059Smarcel    }
393129059Smarcel
394129059Smarcel    int get_nat(int regid, int *natp) {
395129059Smarcel	return uwx_get_nat(env, regid, natp);
396129059Smarcel    }
397129059Smarcel
398129059Smarcel    int get_spill_loc(int regid, uint64_t *dispp) {
399129059Smarcel	return uwx_get_spill_loc(env, regid, dispp);
400129059Smarcel    }
401129059Smarcel
402129059Smarcel    int get_abi_context_code() {
403129059Smarcel	return uwx_get_abi_context_code(env);
404129059Smarcel    }
405129059Smarcel
406129059Smarcel    struct uwx_env *get_env() {
407129059Smarcel	return env;
408129059Smarcel    }
409129059Smarcel
410129059Smarcelprotected:
411129059Smarcel
412129059Smarcel    struct uwx_env *env;
413129059Smarcel
414129059Smarcel};
415129059Smarcel
416129059Smarcel#endif /* __cplusplus */
417129059Smarcel
418129059Smarcel#endif /* __UWX_INCLUDED */
419