[Midnightbsd-cvs] src [10140] trunk/sys/contrib/ia64: add ia64

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Mon May 28 14:56:41 EDT 2018


Revision: 10140
          http://svnweb.midnightbsd.org/src/?rev=10140
Author:   laffer1
Date:     2018-05-28 14:56:41 -0400 (Mon, 28 May 2018)
Log Message:
-----------
add ia64

Added Paths:
-----------
    trunk/sys/contrib/ia64/
    trunk/sys/contrib/ia64/libuwx/
    trunk/sys/contrib/ia64/libuwx/src/
    trunk/sys/contrib/ia64/libuwx/src/Makefile
    trunk/sys/contrib/ia64/libuwx/src/uwx.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_context.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_context.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_env.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_env.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_self.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_self.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_self_context.s
    trunk/sys/contrib/ia64/libuwx/src/uwx_self_info.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_step.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_step.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_str.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_str.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_swap.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_swap.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_trace.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_trace.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.h
    trunk/sys/contrib/ia64/libuwx/src/uwx_utable.c
    trunk/sys/contrib/ia64/libuwx/src/uwx_utable.h
    trunk/sys/contrib/ia64/libuwx/test/
    trunk/sys/contrib/ia64/libuwx/test/Makefile
    trunk/sys/contrib/ia64/libuwx/test/dump_context.c
    trunk/sys/contrib/ia64/libuwx/test/dumpmyself.c
    trunk/sys/contrib/ia64/libuwx/test/primeregs.s

Added: trunk/sys/contrib/ia64/libuwx/src/Makefile
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/Makefile	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/Makefile	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,72 @@
+# $MidnightBSD$
+# Makefile for IPF unwind express library, libuwx.
+#
+# To build a cross-unwind library (i.e., one hosted on a
+# non-IPF, non-HP-UX system), omit the "self" callbacks
+# and the dependency on libuca by setting SELFOBJS and
+# SELFLIBS to empty strings.
+
+AR = ar
+RANLIB = :
+
+OTHERCFLAGS =
+# OTHERCFLAGS = -DUWX_TRACE_ENABLE	# Enables trace output
+# OTHERCFLAGS = +DD64			# Builds 64-bit library
+
+CFLAGS = -O $(OTHERCFLAGS)
+
+OBJS =		uwx_bstream.o uwx_context.o uwx_env.o uwx_scoreboard.o \
+		uwx_step.o uwx_str.o uwx_swap.o uwx_symbols.o \
+		uwx_trace.o uwx_uinfo.o uwx_utable.o
+
+# SELFOBJS =				# For cross-unwind library
+# SELFOBJS = 	uwx_self.o uwx_self_context.o uwx_ttrace.o
+SELFOBJS = 	uwx_self.o uwx_self_context.o
+
+# SELFLIBS =				# For cross-unwind library
+SELFLIBS =	-luca
+
+libuwx.a:	$(OBJS) $(SELFOBJS)
+	$(AR) rv libuwx.a $?
+	$(RANLIB) libuwx.a
+
+libuwx.so:	$(OBJS) $(SELFOBJS)
+	ld -b -o libuwx.so $(OBJS) $(SELFOBJS) $(SELFLIBS)
+
+libuwx.sl:	$(OBJS) $(SELFOBJS)
+	ld -b -o libuwx.sl $(OBJS) $(SELFOBJS) $(SELFLIBS)
+
+clean:
+	rm -f $(OBJS) $(SELFOBJS) libuwx.a libuwx.so libuwx.sl
+
+uwx_bstream.o:	uwx.h uwx_env.h uwx_bstream.h
+
+uwx_context.o:	uwx.h uwx_env.h uwx_scoreboard.h uwx_step.h uwx_trace.h
+
+uwx_env.o:	uwx.h uwx_env.h uwx_scoreboard.h uwx_str.h uwx_trace.h
+
+uwx_scoreboard.o: uwx.h uwx_env.h uwx_scoreboard.h uwx_trace.h
+
+uwx_step.o:	uwx.h uwx_env.h uwx_context.h uwx_utable.h \
+		uwx_uinfo.h uwx_scoreboard.h uwx_str.h uwx_trace.h
+
+uwx_str.o:	uwx.h uwx_env.h uwx_str.h
+
+uwx_swap.o:	uwx.h uwx_env.h uwx_swap.h
+
+uwx_symbols.o:	uwx.h uwx_env.h uwx_symbols.h
+
+uwx_trace.o:	uwx.h uwx_env.h uwx_uinfo.h uwx_scoreboard.h uwx_trace.h
+
+uwx_uinfo.o:	uwx.h uwx_env.h uwx_uinfo.h uwx_utable.h \
+		uwx_scoreboard.h uwx_bstream.h uwx_trace.h
+
+uwx_utable.o:	uwx.h uwx_env.h uwx_utable.h uwx_swap.h uwx_trace.h
+
+uwx_self.o:	uwx.h uwx_env.h uwx_context.h uwx_trace.h uwx_self.h \
+		uwx_symbols.h
+
+uwx_self_context.o:	uwx_self_context.s
+	$(CC) -c $(CFLAGS) -o uwx_self_context.o uwx_self_context.s
+
+uwx_ttrace.o:	uwx.h uwx_env.h uwx_context.h uwx_trace.h uwx_ttrace.h


Property changes on: trunk/sys/contrib/ia64/libuwx/src/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,419 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef __UWX_INCLUDED
+#define __UWX_INCLUDED 1
+
+#ifndef _KERNEL
+#include <stdlib.h>
+#include <inttypes.h>
+#else
+#include <sys/param.h>
+#include <sys/systm.h>
+#endif
+
+#if defined(__cplusplus)
+#define __EXTERN_C extern "C"
+#else
+#define __EXTERN_C extern
+#endif
+
+#define UWX_VERSION 3		/* Version id for callback interfaces */
+
+/* Unwind environment structure (opaque) */
+struct uwx_env;
+
+/* Symbol Cache for uwx_find_symbol (opaque) */
+struct uwx_symbol_cache;
+
+/* Allocate and free callbacks */
+typedef void *(*alloc_cb)(size_t size);
+typedef void (*free_cb)(void *ptr);
+__EXTERN_C int uwx_register_alloc_cb(alloc_cb alloc, free_cb free);
+
+/* Allocate and initialize an unwind environment */
+__EXTERN_C struct uwx_env *uwx_init(void);
+
+/* Free an unwind environment */
+__EXTERN_C int uwx_free(struct uwx_env *env);
+
+/* Put unwind express into cross-process mode */
+__EXTERN_C int uwx_set_remote(struct uwx_env *env, int is_big_endian_target);
+
+/* Put unwind express into reduced-context mode (no floating-point regs) */
+__EXTERN_C int uwx_set_nofr(struct uwx_env *env);
+
+/* Copy-in callback */
+typedef int (*copyin_cb)(
+    int request,		/* request code (see below) */
+    char *loc,			/* local (destination) address */
+    uint64_t rem,		/* remote (source) address */
+    int len,			/* number of bytes to copy */
+    intptr_t tok);		/* callback token */
+
+/* Lookup IP callback */
+typedef int (*lookupip_cb)(
+    int request,		/* request code (see below) */
+    uint64_t ip,		/* IP of current frame */
+    intptr_t tok,		/* callback token */
+    uint64_t **vecp);		/* parameter vector (in/out) */
+
+/* Register copy-in and lookup IP callbacks */
+__EXTERN_C int uwx_register_callbacks(
+    struct uwx_env *env,	/* unwind environment */
+    intptr_t tok,		/* callback token */
+    copyin_cb copyin,		/* copy-in callback */
+    lookupip_cb lookupip);	/* lookup IP callback */
+
+/* Initialize a context with the basic info needed to start an unwind */
+__EXTERN_C int uwx_init_context(
+    struct uwx_env *env,	/* unwind environment */
+    uint64_t ip,		/* IP (instruction pointer) */
+    uint64_t sp,		/* SP (stack pointer) */
+    uint64_t bsp,		/* BSP (backing store pointer) */
+    uint64_t cfm);		/* CFM (current frame marker) */
+
+/* Set the value of a specific register in the current context (non fp) */
+__EXTERN_C int uwx_set_reg(
+    struct uwx_env *env,	/* unwind environment */
+    int regid,			/* register id (see below) */
+    uint64_t val);		/* register value */
+
+/* Set the value of a floating-point register in the current context */
+__EXTERN_C int uwx_set_fr(
+    struct uwx_env *env,	/* unwind environment */
+    int regid,			/* register id (see below) */
+    uint64_t *val);		/* register value (ptr to 16 bytes) */
+				/*   (memory spill format) */
+
+/* Initialize the unwind history */
+__EXTERN_C int uwx_init_history(struct uwx_env *env);
+
+/* Step one frame */
+__EXTERN_C int uwx_step(struct uwx_env *env);
+
+/* Get module name and text base, if available, for current frame */
+__EXTERN_C int uwx_get_module_info(
+    struct uwx_env *env,	/* unwind environment */
+    char **modp,		/* load module name (out)  */
+    uint64_t *text_base);	/* base address of text segment (out)  */
+
+/* Get function start address for current frame */
+__EXTERN_C int uwx_get_funcstart(
+    struct uwx_env *env,	/* unwind environment */
+    uint64_t *funcstart);	/* function start address (out)  */
+
+/* Get symbol information, if available, for current frame */
+__EXTERN_C int uwx_get_sym_info(
+    struct uwx_env *env,	/* unwind environment */
+    char **modp,		/* load module name (out)  */
+    char **symp,		/* function name (out)  */
+    uint64_t *offsetp);		/* offset from start of function (out)  */
+
+/* Get symbol information, given module name and IP */
+__EXTERN_C int uwx_find_symbol(
+    struct uwx_env *env,	/* unwind environment */
+    struct uwx_symbol_cache **cachep,
+				/* ptr to symbol cache ptr (in/out) */
+    char *mod,			/* load module name */
+    uint64_t relip,		/* IP, relative to text segment  */
+    char **symp,		/* function name (out) */
+    uint64_t *offsetp);		/* offset from start of function (out) */
+
+/* Release memory used by symbol cache */
+__EXTERN_C void uwx_release_symbol_cache(
+    struct uwx_env *env,	/* unwind environment */
+    struct uwx_symbol_cache *symbol_cache);
+				/* symbol cache ptr */
+
+/* Get the value of a register from the current context */
+__EXTERN_C int uwx_get_reg(
+    struct uwx_env *env,	/* unwind environment */
+    int regid,			/* register id (see below) */
+    uint64_t *valp);		/* register value (out) */
+
+/* Get the NaT bit of a GR from the current context */
+__EXTERN_C int uwx_get_nat(
+    struct uwx_env *env,	/* unwind environment */
+    int regid,			/* register id (see below) */
+    int *natp);			/* NaT value (out: 0 or 1) */
+
+/* Get the spill location for a register in the current context */
+__EXTERN_C int uwx_get_spill_loc(
+    struct uwx_env *env,	/* unwind environment */
+    int regid,			/* register id (see below) */
+    uint64_t *dispp);		/* disposition code (see below) (out) */
+
+/* Get the ABI context code (if uwx_step returned UWX_ABI_FRAME) */
+__EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
+
+/* Increment/Decrement the bsp by a number of slots */
+/* (accounts for NaT collections) */
+__EXTERN_C uint64_t uwx_add_to_bsp(uint64_t bsp, int nslots);
+
+/* Return status codes for uwx_ APIs */
+#define UWX_OK			0
+#define UWX_BOTTOM		1	/* Hit bottom of stack */
+#define UWX_ABI_FRAME		2	/* Hit ABI-dependent frame */
+#define UWX_ERR_NOENV		(-1)	/* No uwx_env allocated */
+#define UWX_ERR_IPNOTFOUND	(-2)	/* Lookup IP c/b returned NOTFOUND */
+#define UWX_ERR_LOOKUPERR	(-3)	/* Lookup IP c/b returned ERR */
+#define UWX_ERR_BADKEY		(-4)	/* Bad result vector key */
+#define UWX_ERR_COPYIN_UTBL	(-5)	/* Error reading unwind table */
+#define UWX_ERR_COPYIN_UINFO	(-6)	/* Error reading unwind info */
+#define UWX_ERR_COPYIN_MSTK	(-7)	/* Error reading memory stack */
+#define UWX_ERR_COPYIN_RSTK	(-8)	/* Error reading register stack */
+#define UWX_ERR_COPYIN_REG	(-9)	/* Error reading context register */
+#define UWX_ERR_NOUENTRY	(-10)	/* No unwind table entry for ip */
+#define UWX_ERR_NOUDESC		(-11)	/* No unwind descriptor covers ip */
+#define UWX_ERR_BADUDESC	(-12)	/* Bad unwind descriptor */
+#define UWX_ERR_NOMEM		(-13)	/* Out of memory */
+#define UWX_ERR_PROLOG_UF	(-14)	/* Prologue underflow */
+#define UWX_ERR_UNDEFLABEL	(-15)	/* Undefined label in copy_state */
+#define UWX_ERR_BADREGID	(-16)	/* Bad register identifier */
+#define UWX_ERR_CANTUNWIND	(-17)	/* Can't unwind */
+#define UWX_ERR_NOCALLBACKS	(-18)	/* No callbacks registered */
+#define UWX_ERR_NOCONTEXT	(-19)	/* Context not initialized */
+#define UWX_ERR_UCACCESS	(-20)	/* Failure in libuca */
+#define UWX_ERR_NOSYM		(-21)	/* Symbol not found */
+
+/* Request codes for copyin callback */
+#define UWX_COPYIN_UINFO	1	/* Reading unwind info */
+#define UWX_COPYIN_MSTACK	2	/* Reading memory stack */
+#define UWX_COPYIN_RSTACK	3	/* Reading RSE backing store */
+#define UWX_COPYIN_REG		4	/* Reading initial register state */
+
+/* Request codes for lookup IP callback */
+#define UWX_LKUP_LOOKUP		1	/* Lookup IP */
+#define UWX_LKUP_FREE		2	/* Free result vector */
+#define UWX_LKUP_SYMBOLS	3	/* Lookup symbolic information */
+#define UWX_LKUP_MODULE		4	/* Get module name */
+
+/* Return status codes for lookup IP callback */
+#define UWX_LKUP_NOTFOUND	0	/* IP not found */
+#define UWX_LKUP_ERR		1	/* Other error */
+#define UWX_LKUP_UTABLE		2	/* Returned ref to unwind table */
+#define UWX_LKUP_FDESC		3	/* Returned frame description */
+#define UWX_LKUP_SYMINFO	4	/* Returned symbolic information */
+#define UWX_LKUP_REMAP		5	/* Returned remapped IP */
+#define UWX_LKUP_UINFO		6	/* Returned unw info block ptr */
+
+/* The lookup IP callback receives a parameter vector, and returns */
+/* one on success. This vector is a series of key/value pairs; each */
+/* even-numbered slot is a key, and each odd-numbered slot is a */
+/* corresponding value. The vector is terminated by a pair whose */
+/* key is 0. */
+#define UWX_KEY_END		0	/* End of vector */
+
+/* Keys passed to lookup IP callback */
+#define UWX_KEY_PREDS		1	/* Predicate registers */
+#define UWX_KEY_VERSION		2	/* Version id of unwind engine */
+/* UWX_KEY_FUNCSTART (below) may also be passed with the UWX_LKUP_SYMINFO */
+/* request. */
+
+/* Keys returned with UWX_LKUP_UTABLE */
+/* These key/value pairs describe the unwind table corresponding */
+/* to the load module in which the current IP resides. */
+#define UWX_KEY_TBASE		1	/* Base address of text seg */
+#define UWX_KEY_UFLAGS		2	/* Unwind flags (optional) */
+#define UWX_KEY_USTART		3	/* Base of unwind tbl */
+#define UWX_KEY_UEND		4	/* End of unwind tbl */
+#define UWX_KEY_GP		7	/* GP value for module */
+
+/* Keys returned with UWX_LKUP_FDESC */
+/* These key/value pairs describe the state of the frame at the */
+/* given IP. They are typically used for dynamically-generated code. */
+/* If UWX_KEY_CONTEXT is returned, it must be the only key returned. */
+/* Use UWX_KEY_GP for the module's gp value. */
+#define UWX_KEY_FSIZE		1			/* Frame size */
+#define UWX_KEY_SPILL(reg_id)	(2 | ((reg_id) << 4))	/* Reg spilled */
+#define UWX_KEY_CONTEXT		3 			/* ABI-dep. context */
+
+/* Keys returned with UWX_LKUP_REMAP */
+#define UWX_KEY_NEWIP		5	/* Remapped IP */
+
+/* Keys returned with UWX_LKUP_UINFO */
+/* Use UWX_KEY_GP for the module's gp value. */
+/* Use UWX_KEY_FUNCSTART for the start address of the function */
+/* Use UWX_KEY_UFLAGS for the unwind flags (optional) */
+#define UWX_KEY_UINFO 		6	/* Address of unwind info block */
+
+/* Keys returned with UWX_LKUP_SYMINFO */
+/* These keys may be returned with UWX_LKUP_FDESC or UWX_LKUP_UINFO, */
+/* if the information is cheap to obtain. */
+/* Use UWX_KEY_TBASE for the base of the text segment */
+#define UWX_KEY_MODULE		17	/* Name of load module */
+#define UWX_KEY_FUNC		18	/* Name of function */
+#define UWX_KEY_FUNCSTART	19	/* Address of start of function */
+
+/* Register identifiers */
+/* For use in UWX_LKUP_FDESC result vectors and context access APIs. */
+/* "no spill info": These regs aren't spilled directly, so */
+/*    result vectors must not describe these registers. */
+/*    The result vector must describe the related register or */
+/*    pseudo register instead (ip:rp, sp:psp, bsp/cfm:pfs). */
+/* "pseudo register": Not a machine register, but treated as */
+/*    one for unwind purposes. */
+#define UWX_REG_IP		0	/* ip (no spill info) */
+#define UWX_REG_SP		1	/* sp (no spill info) */
+#define UWX_REG_BSP		2	/* ar.bsp (no spill info) */
+#define UWX_REG_CFM		3	/* cfm (no spill info) */
+#define UWX_REG_RP		4	/* rp (pseudo-register) */
+#define UWX_REG_PSP		5	/* psp (pseudo-register) */
+#define UWX_REG_PFS		6	/* pfs (pseudo-register) */
+#define UWX_REG_PREDS		7	/* p0 - p63 */
+#define UWX_REG_PRIUNAT		8	/* primary unat (pseudo-register) */
+#define UWX_REG_AR_BSPSTORE	9	/* ar.bspstore */
+#define UWX_REG_AR_RNAT		10	/* ar.rnat */
+#define UWX_REG_AR_UNAT		11	/* ar.unat */
+#define UWX_REG_AR_FPSR		12	/* ar.fpsr */
+#define UWX_REG_AR_LC		13	/* ar.lc */
+#define UWX_REG_AR_PFS		14	/* ar.pfs */
+#define UWX_REG_GP		15	/* gp (pseudo-register) */
+#define UWX_REG_GR(gr)		(0x100 | (gr))
+#define UWX_REG_FR(fr)		(0x200 | (fr))
+#define UWX_REG_BR(br)		(0x300 | (br))
+
+/* for backwards compatibility with previous releases... */
+#define UWX_REG_BSPSTORE	UWX_REG_AR_BSPSTORE
+#define UWX_REG_RNAT		UWX_REG_AR_RNAT
+#define UWX_REG_UNAT		UWX_REG_AR_UNAT
+#define UWX_REG_FPSR		UWX_REG_AR_FPSR
+#define UWX_REG_LC		UWX_REG_AR_LC
+
+/* Values corresponding to UWX_KEY_SPILL keys indicate the disposition */
+/* of the spilled register -- either in the memory stack or in another */
+/* register. The PSP register may also have a disposition of "SPPLUS", */
+/* indicating that its value is SP plus a fixed constant. */
+#define UWX_DISP_NONE		0		/* Not spilled */
+#define UWX_DISP_SPPLUS(k)	(1 | (k))	/* PSP = SP+constant */
+#define UWX_DISP_SPREL(disp)	(2 | (disp))	/* Spilled at [SP+disp] */
+#define UWX_DISP_PSPREL(disp)	(3 | (disp))	/* Spilled at [PSP+16-disp] */
+#define UWX_DISP_REG(reg)	(4 | ((reg) << 4)) /* Saved to another reg. */
+
+/* The uwx_get_spill_loc() routine returns a spill location for a */
+/* given register in the current context. It will return a disposition */
+/* code of UWX_DISP_NONE, UWX_DISP_REG(reg), or one of the following */
+/* to indicate that the spilled value can be found in the memory */
+/* stack or the register stack backing store. */
+#define UWX_DISP_MSTK(addr)	(5 | (addr))	/* Spilled in mem. stack */
+#define UWX_DISP_RSTK(addr)	(6 | (addr))	/* Spilled in reg. stack */
+
+/* Extract the disposition code, offset, address, or register id */
+/* from a disposition returned from uwx_get_spill_loc(). */
+/* Compare the extracted disp code against UWX_DISP_REG(0), etc. */
+#define UWX_GET_DISP_CODE(disp)		((int)(disp) & 0x07)
+#define UWX_GET_DISP_OFFSET(disp)	((disp) & ~(uint64_t)0x07)
+#define UWX_GET_DISP_ADDR(disp)		((disp) & ~(uint64_t)0x07)
+#define UWX_GET_DISP_REGID(disp)	((int)(disp) >> 4)
+
+#undef __EXTERN_C
+
+#if defined(__cplusplus)
+
+class UnwindExpress {
+
+public:
+
+    UnwindExpress() {
+	env = uwx_init();
+    }
+
+    ~UnwindExpress() {
+	if (env != 0)
+	    uwx_free(env);
+	env = 0;
+    }
+
+    int init_context(uint64_t ip, uint64_t sp, uint64_t bsp, uint64_t cfm) { 
+	return uwx_init_context(env, ip, sp, bsp, cfm);
+    }
+
+    int init_history() {
+	return uwx_init_history(env);
+    }
+
+    int set_reg(int regid, uint64_t val) {
+	return uwx_set_reg(env, regid, val);
+    }
+
+    int set_fr(int regid, uint64_t *valp) {
+	return uwx_set_fr(env, regid, valp);
+    }
+
+    int step() {
+	return uwx_step(env);
+    }
+
+    int get_module_info(char **modp, uint64_t *text_base_p) {
+	return uwx_get_module_info(env, modp, text_base_p);
+    }
+
+    int get_funcstart(uint64_t *funcstart) {
+	return uwx_get_funcstart(env, funcstart);
+    }
+
+    int get_sym_info(char **modp, char **symp, uint64_t *offsetp) {
+	return uwx_get_sym_info(env, modp, symp, offsetp);
+    }
+
+    int find_symbol(struct uwx_symbol_cache **cachep,
+		char *mod, uint64_t relip, char **symp, uint64_t *offsetp) {
+	return uwx_find_symbol(env, cachep, mod, relip, symp, offsetp);
+    }
+
+    void release_symbol_cache(struct uwx_symbol_cache *symbol_cache) {
+	uwx_release_symbol_cache(env, symbol_cache);
+    }
+
+    int get_reg(int regid, uint64_t *valp) {
+	return uwx_get_reg(env, regid, valp);
+    }
+
+    int get_nat(int regid, int *natp) {
+	return uwx_get_nat(env, regid, natp);
+    }
+
+    int get_spill_loc(int regid, uint64_t *dispp) {
+	return uwx_get_spill_loc(env, regid, dispp);
+    }
+
+    int get_abi_context_code() {
+	return uwx_get_abi_context_code(env);
+    }
+
+    struct uwx_env *get_env() {
+	return env;
+    }
+
+protected:
+
+    struct uwx_env *env;
+
+};
+
+#endif /* __cplusplus */
+
+#endif /* __UWX_INCLUDED */


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,182 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx_env.h"
+#include "uwx_bstream.h"
+
+
+/* uwx_init_bstream: initialize a byte stream for reading */
+
+void uwx_init_bstream(
+    struct uwx_bstream *bstream,
+    struct uwx_env *env,
+    uint64_t source,
+    unsigned int len,
+    int request)
+{
+    bstream->buf = 0;
+    if (env->remote) {
+	bstream->source = source;
+	bstream->bufp = (unsigned char *) &bstream->buf;
+	bstream->nbuf = 0;
+	bstream->copyin = env->copyin;
+	bstream->cb_token = env->cb_token;
+	bstream->request = request;
+    }
+    else {
+	bstream->source = 0;
+	bstream->bufp = (unsigned char *) (intptr_t) source;
+	bstream->nbuf = len;
+	bstream->copyin = 0;
+	bstream->cb_token = 0;
+	bstream->request = 0;
+    }
+    bstream->ntotal = len;
+    bstream->peekc = -1;
+}
+
+
+/* uwx_get_byte: read the next byte from the byte stream */
+
+int uwx_get_byte(struct uwx_bstream *bstream)
+{
+    int len;
+    int n;
+    int b;
+
+    if (bstream->peekc >= 0) {
+	b = bstream->peekc;
+	bstream->peekc = -1;
+	return b;
+    }
+    if (bstream->ntotal <= 0)
+	return -1;
+    if (bstream->nbuf <= 0) {
+	if (bstream->source & 0x7 || bstream->ntotal < sizeof(uint64_t))
+	    len = sizeof(uint32_t);
+	else
+	    len = sizeof(uint64_t);
+	n = (*bstream->copyin)(bstream->request, (char *)&bstream->buf,
+		bstream->source, len, bstream->cb_token);
+	if (n != len)
+	    return -1;
+	bstream->bufp = (unsigned char *) &bstream->buf;
+	bstream->nbuf = n;
+	bstream->source += n;
+    }
+
+    b = *bstream->bufp++;
+    bstream->nbuf--;
+    bstream->ntotal--;
+    return b;
+}
+
+
+/* uwx_unget_byte: push a byte back onto the byte stream */
+
+int uwx_unget_byte(struct uwx_bstream *bstream, int b)
+{
+    bstream->peekc = b;
+    return 0;
+}
+
+
+/* uwx_get_uleb128: read a ULEB128 value from the byte stream */
+
+int uwx_get_uleb128(struct uwx_bstream *bstream, uint64_t *valp)
+{
+    uint64_t val;
+    int i;
+    int b;
+
+    b = uwx_get_byte(bstream);
+    val = (uint64_t)(b & 0x7f) << 56;
+    for (i = 0; i < 8; i++) {
+	val = val >> 7;
+	if (b & 0x80) {
+	    b = uwx_get_byte(bstream);
+	    val |= (uint64_t)(b & 0x7f) << 56;
+	}
+    }
+    if (b & 0x80) {
+	b = uwx_get_byte(bstream);
+	val |= (uint64_t)(b & 0x7f) << 63;
+    }
+    if (b & 0x80)
+	return -1;
+    *valp = val;
+    return 0;
+}
+
+#if 0
+int uwx_get_uleb128_alt(struct uwx_bstream *bstream, uint64_t *valp)
+{
+    uint64_t val;
+    int b;
+
+    b = uwx_get_byte(bstream);
+    val = b & 0x7f;
+    if (b & 0x80) {
+	b = uwx_get_byte(bstream);
+	val |= (uint64_t)(b & 0x7f) << 7;
+	if (b & 0x80) {
+	    b = uwx_get_byte(bstream);
+	    val |= (uint64_t)(b & 0x7f) << 14;
+	    if (b & 0x80) {
+		b = uwx_get_byte(bstream);
+		val |= (uint64_t)(b & 0x7f) << 21;
+		if (b & 0x80) {
+		    b = uwx_get_byte(bstream);
+		    val |= (uint64_t)(b & 0x7f) << 28;
+		    if (b & 0x80) {
+			b = uwx_get_byte(bstream);
+			val |= (uint64_t)(b & 0x7f) << 35;
+			if (b & 0x80) {
+			    b = uwx_get_byte(bstream);
+			    val |= (uint64_t)(b & 0x7f) << 42;
+			    if (b & 0x80) {
+				b = uwx_get_byte(bstream);
+				val |= (uint64_t)(b & 0x7f) << 49;
+				if (b & 0x80) {
+				    b = uwx_get_byte(bstream);
+				    val |= (uint64_t)(b & 0x7f) << 56;
+				    if (b & 0x80) {
+					b = uwx_get_byte(bstream);
+					val |= (uint64_t)(b & 0x7f) << 63;
+					if (b & 0x80)
+					    return -1;
+				    }
+				}
+			    }
+			}
+		    }
+		}
+	    }
+	}
+    }
+    *valp = val;
+    return 0;
+}
+#endif


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,60 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+struct uwx_bstream {
+    copyin_cb copyin;
+    intptr_t cb_token;
+    uint64_t source;
+    uint64_t buf;
+    unsigned char *bufp;
+    int nbuf;
+    unsigned int ntotal;
+    int request;
+    int peekc;
+};
+
+/* uwx_init_bstream: initialize a byte stream for reading */
+
+extern void uwx_init_bstream(
+    struct uwx_bstream *bstream,
+    struct uwx_env *env,
+    uint64_t source,
+    unsigned int len,
+    int request);
+
+
+/* uwx_get_byte: read the next byte from the byte stream */
+
+extern int uwx_get_byte(struct uwx_bstream *bstream);
+
+
+/* uwx_unget_byte: push a byte back onto the byte stream */
+
+extern int uwx_unget_byte(struct uwx_bstream *bstream, int b);
+
+
+/* uwx_get_uleb128: read a ULEB128 value from the byte stream */
+
+extern int uwx_get_uleb128(struct uwx_bstream *bstream, uint64_t *val);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_bstream.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_context.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_context.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_context.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,409 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx_env.h"
+#include "uwx_scoreboard.h"
+#include "uwx_step.h"
+#include "uwx_trace.h"
+
+int uwx_init_context(
+    struct uwx_env *env,
+    uint64_t ip,
+    uint64_t sp,
+    uint64_t bsp,
+    uint64_t cfm)
+{
+    int i;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    env->context.special[UWX_REG_IP] = ip;
+    env->context.special[UWX_REG_SP] = sp;
+    env->context.special[UWX_REG_BSP] = bsp;
+    env->context.special[UWX_REG_CFM] = cfm;
+    for (i = UWX_REG_RP; i < NSPECIALREG; i++)
+	env->context.special[i] = 0;
+    for (i = 0; i < NPRESERVEDGR; i++)
+	env->context.gr[i] = 0;
+    env->context.valid_regs = VALID_BASIC4;
+    env->context.valid_frs = 0;
+    env->rstate = 0;
+    (void)uwx_init_history(env);
+    return UWX_OK;
+}
+
+int uwx_get_reg(struct uwx_env *env, int regid, uint64_t *valp)
+{
+    int status;
+    int sor;
+    int rrb_gr;
+    uint64_t bsp;
+    int n;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    status = UWX_OK;
+
+    if (regid == UWX_REG_GR(12))
+	regid = UWX_REG_SP;
+    if (regid < NSPECIALREG && (env->context.valid_regs & (1 << regid)))
+	*valp = env->context.special[regid];
+    else if (regid == UWX_REG_PSP || regid == UWX_REG_RP ||
+					regid == UWX_REG_PFS) {
+	status = uwx_restore_markers(env);
+	if (status != UWX_OK)
+	    return status;
+	*valp = env->context.special[regid];
+    }
+    else if (regid >= UWX_REG_GR(4) && regid <= UWX_REG_GR(7) &&
+		(env->context.valid_regs &
+		    (1 << (regid - UWX_REG_GR(4) + VALID_GR_SHIFT))) )
+	*valp = env->context.gr[regid - UWX_REG_GR(4)];
+    else if (regid >= UWX_REG_GR(32) && regid <= UWX_REG_GR(127)) {
+	if (env->copyin == 0)
+	    return UWX_ERR_NOCALLBACKS;
+	bsp = env->context.special[UWX_REG_BSP];
+	TRACE_C_GET_REG(regid, bsp)
+	regid -= UWX_REG_GR(32);
+	sor = (((int) env->context.special[UWX_REG_CFM] >> 14) & 0x0f) * 8;
+	rrb_gr = ((int) env->context.special[UWX_REG_CFM] >> 18) & 0x7f;
+	if (sor != 0 && rrb_gr != 0 && regid < sor) {
+	    TRACE_C_ROTATE_GR(regid, sor, rrb_gr, (regid+rrb_gr)%sor)
+	    regid = (regid + rrb_gr) % sor;
+	}
+	bsp = uwx_add_to_bsp(bsp, regid);
+	n = (*env->copyin)(UWX_COPYIN_RSTACK, (char *)valp,
+		    bsp, DWORDSZ, env->cb_token);
+	if (n != DWORDSZ)
+	    status = UWX_ERR_COPYIN_RSTK;
+    }
+    else if (regid == UWX_REG_GR(0))
+	*valp = 0;
+    else if (regid >= UWX_REG_BR(1) && regid <= UWX_REG_BR(5) &&
+		(env->context.valid_regs &
+		    (1 << (regid - UWX_REG_BR(1) + VALID_BR_SHIFT))) )
+	*valp = env->context.br[regid - UWX_REG_BR(1)];
+    else if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(5) &&
+	    (env->context.valid_frs & (1 << (regid - UWX_REG_FR(2)))) ) {
+	valp[0] = env->context.fr[regid - UWX_REG_FR(2)].part0;
+	valp[1] = env->context.fr[regid - UWX_REG_FR(2)].part1;
+    }
+    else if (regid >= UWX_REG_FR(16) && regid <= UWX_REG_FR(31) &&
+	    (env->context.valid_frs & (1 << (regid - UWX_REG_FR(16) + 4))) ) {
+	valp[0] = env->context.fr[regid - UWX_REG_FR(16) + 4].part0;
+	valp[1] = env->context.fr[regid - UWX_REG_FR(16) + 4].part1;
+    }
+    else if ( (regid < NSPECIALREG) ||
+		(regid >= UWX_REG_GR(1) && regid <= UWX_REG_GR(31)) ||
+		(regid >= UWX_REG_BR(0) && regid <= UWX_REG_BR(7)) ) {
+	if (env->copyin == 0)
+	    return UWX_ERR_NOCALLBACKS;
+	n = (*env->copyin)(UWX_COPYIN_REG, (char *)valp,
+			    regid, DWORDSZ, env->cb_token);
+	if (n != DWORDSZ)
+	    status = UWX_ERR_COPYIN_REG;
+    }
+    else if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(127)) {
+	if (env->copyin == 0)
+	    return UWX_ERR_NOCALLBACKS;
+	n = (*env->copyin)(UWX_COPYIN_REG, (char *)valp,
+			    regid, 2*DWORDSZ, env->cb_token);
+	if (n != 2*DWORDSZ)
+	    status = UWX_ERR_COPYIN_REG;
+    }
+    else if (regid == UWX_REG_FR(0)) {
+	valp[0] = 0;
+	valp[1] = 0;
+    }
+    else if (regid == UWX_REG_FR(1)) {
+	valp[0] = 0x000000000000ffffULL;
+	valp[1] = 0x8000000000000000ULL;
+    }
+    else
+	status = UWX_ERR_BADREGID;
+    return status;
+}
+
+int uwx_get_nat(struct uwx_env *env, int regid, int *natp)
+{
+    int status;
+    int sor;
+    int rrb_gr;
+    uint64_t bsp;
+    uint64_t natcollp;
+    uint64_t natcoll;
+    int n;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    status = UWX_OK;
+
+    if (regid >= UWX_REG_GR(4) && regid <= UWX_REG_GR(7) &&
+		(env->context.valid_regs &
+		    (1 << (regid - UWX_REG_GR(4) + VALID_GR_SHIFT))) ) {
+	*natp = (env->context.special[UWX_REG_PRIUNAT] >>
+				(regid - UWX_REG_GR(4)) ) & 0x01;
+    }
+    else if (regid >= UWX_REG_GR(32) && regid <= UWX_REG_GR(127)) {
+	if (env->copyin == 0)
+	    return UWX_ERR_NOCALLBACKS;
+	bsp = env->context.special[UWX_REG_BSP];
+	regid -= UWX_REG_GR(32);
+	sor = (((int) env->context.special[UWX_REG_CFM] >> 14) & 0x0f) * 8;
+	rrb_gr = ((int) env->context.special[UWX_REG_CFM] >> 18) & 0x7f;
+	if (sor != 0 && rrb_gr != 0 && regid < sor) {
+	    regid = (regid + rrb_gr) % sor;
+	}
+	bsp = uwx_add_to_bsp(bsp, regid);
+	natcollp = bsp | 0x01f8;
+	n = (*env->copyin)(UWX_COPYIN_RSTACK, (char *)&natcoll,
+			natcollp, DWORDSZ, env->cb_token);
+	if (n != DWORDSZ)
+	    return UWX_ERR_COPYIN_RSTK;
+	*natp = (int)(natcoll >> (((int)bsp >> 3) & 0x3f)) & 0x01;
+    }
+    else if (regid == UWX_REG_GR(0))
+	*natp = 0;
+    else
+	status = UWX_ERR_BADREGID;
+    return status;
+}
+
+int uwx_get_spill_loc(struct uwx_env *env, int regid, uint64_t *dispp)
+{
+    int status;
+    int sor;
+    int rrb_gr;
+    uint64_t bsp;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    status = UWX_OK;
+
+    if (regid == UWX_REG_GR(12))
+	regid = UWX_REG_SP;
+    if (regid < NSPECIALREG) {
+	if (regid == UWX_REG_PSP || regid == UWX_REG_RP ||
+						regid == UWX_REG_PFS) {
+	    if (!(env->context.valid_regs & (1 << regid))) {
+		status = uwx_restore_markers(env);
+		if (status != UWX_OK)
+		    return status;
+	    }
+	}
+	*dispp = env->history.special[regid];
+    }
+    else if (regid >= UWX_REG_GR(4) && regid <= UWX_REG_GR(7))
+	*dispp = env->history.gr[regid - UWX_REG_GR(4)];
+    else if (regid >= UWX_REG_GR(32) && regid <= UWX_REG_GR(127)) {
+	bsp = env->context.special[UWX_REG_BSP];
+	regid -= UWX_REG_GR(32);
+	sor = (((int) env->context.special[UWX_REG_CFM] >> 14) & 0x0f) * 8;
+	rrb_gr = ((int) env->context.special[UWX_REG_CFM] >> 18) & 0x7f;
+	if (sor != 0 && rrb_gr != 0 && regid < sor)
+	    regid = (regid + rrb_gr) % sor;
+	bsp = uwx_add_to_bsp(bsp, regid);
+	*dispp = UWX_DISP_RSTK(bsp);
+    }
+    else if (regid >= UWX_REG_BR(1) && regid <= UWX_REG_GR(5))
+	*dispp = env->history.br[regid - UWX_REG_BR(1)];
+    else if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(5))
+	*dispp = env->history.fr[regid - UWX_REG_FR(2)];
+    else if (regid >= UWX_REG_FR(16) && regid <= UWX_REG_FR(31))
+	*dispp = env->history.fr[regid - UWX_REG_FR(16) + 4];
+    else if ( (regid >= UWX_REG_GR(1) && regid <= UWX_REG_GR(31)) ||
+		(regid >= UWX_REG_BR(0) && regid <= UWX_REG_BR(7)) ||
+		(regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(127)) )
+	*dispp = UWX_DISP_REG(regid);
+    else
+	status = UWX_ERR_BADREGID;
+    return status;
+}
+
+int uwx_set_reg(struct uwx_env *env, int regid, uint64_t val)
+{
+    int status;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    if (regid == UWX_REG_GR(12))
+	regid = UWX_REG_SP;
+    if (regid < NSPECIALREG) {
+	env->context.special[regid] = val;
+	env->context.valid_regs |= 1 << regid;
+	status = UWX_OK;
+    }
+    else if (regid >= UWX_REG_GR(4) && regid <= UWX_REG_GR(7)) {
+	env->context.gr[regid - UWX_REG_GR(4)] = val;
+	env->context.valid_regs |=
+			1 << (regid - UWX_REG_GR(4) + VALID_GR_SHIFT);
+	status = UWX_OK;
+    }
+    else if (regid >= UWX_REG_GR(32) && regid <= UWX_REG_GR(127)) {
+	status = UWX_ERR_BADREGID;
+    }
+    else if (regid >= UWX_REG_BR(1) && regid <= UWX_REG_BR(5)) {
+	env->context.br[regid - UWX_REG_BR(1)] = val;
+	env->context.valid_regs |=
+			1 << (regid - UWX_REG_BR(1) + VALID_BR_SHIFT);
+	status = UWX_OK;
+    }
+    else
+	status = UWX_ERR_BADREGID;
+    return status;
+}
+
+int uwx_set_fr(struct uwx_env *env, int regid, uint64_t *val)
+{
+
+    if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(5))
+	regid -= UWX_REG_FR(2);
+    else if (regid >= UWX_REG_FR(16) && regid <= UWX_REG_FR(31))
+	regid -= UWX_REG_FR(16) - 4;
+    else
+	return UWX_ERR_BADREGID;
+
+    env->context.fr[regid].part0 = val[0];
+    env->context.fr[regid].part1 = val[1];
+    env->context.valid_frs |= 1 << regid;
+    env->nsbreg = NSBREG;
+    return UWX_OK;
+}
+
+uint64_t uwx_add_to_bsp(uint64_t bsp, int nslots)
+{
+    int bias;
+
+    /*
+     *  Here's a picture of the backing store as modeled in
+     *  the computations below. "X" marks NaT collections at
+     *  every 0x1f8 mod 0x200 address.
+     *
+     *  To make the NaT adjustments easier, we bias the current bsp
+     *  by enough slots to place it at the previous NaT collection.
+     *  Then we need to add the bias to the number of slots,
+     *  then add 1 for every 63 slots to account for NaT collections.
+     *  Then we can remove the bias again and add the adjusted
+     *  number of slots to the bsp.
+     *
+     *   0                           1f8                             3f8
+     *  +---------------------------------------------------------------+
+     *  |                              X                               X|
+     *  +---------------------------------------------------------------+
+     *   <-------- bias -------->
+     *                           <--- nslots --->
+     *                           ^
+     *                           |
+     *                          bsp
+     *   <------------ nslots + bias ----------->
+
+     *  When subtracting from bsp, we avoid depending on the sign of
+     *  the quotient by adding 63*8 before division and subtracting 8
+     *  after division. (Assumes that we will never be called upon
+     *  to subtract more than 504 slots from bsp.)
+     *
+     *   0                           1f8                             3f8
+     *  +---------------------------------------------------------------+
+     *  |                              X                               X|
+     *  +---------------------------------------------------------------+
+     *                                  <-- bias -->
+     *                           <--- (-nslots) --->
+     *                                              ^
+     *                                              |
+     *                                             bsp
+     *                           <----------------->
+     *                             -(nslots + bias)
+     */
+
+    bias = ((unsigned int)bsp & 0x1f8) / DWORDSZ;
+    nslots += (nslots + bias + 63*8) / 63 - 8;
+    return bsp + nslots * DWORDSZ;
+}
+
+#if 0
+int uwx_selftest_bsp_arithmetic()
+{
+    int i;
+    int j;
+    int r;
+    uint64_t bstore[161];
+    uint64_t *bsp;
+    uint64_t *p;
+    int failed = 0;
+
+    printf("uwx_selftest_bsp_arithmetic: bsp at %08lx\n", (unsigned int)bstore);
+    r = 0;
+    bsp = bstore;
+    for (i = 0; i < 161; i++) {
+	if (((unsigned int)bsp & 0x1f8) == 0x1f8)
+	    *bsp++ = 1000 + r;
+	else
+	    *bsp++ = r++;
+    }
+
+    printf("uwx_selftest_bsp_arithmetic: plus tests...\n");
+    bsp = bstore;
+    for (i = 0; i < 64; i++) {
+	r = (int)*bsp;
+	if (r >= 1000)
+	    r -= 1000;
+	for (j = 0; j < 96; j++) {
+	    p = (uint64_t *)(intptr_t)uwx_add_to_bsp((uint64_t)bsp, j);
+	    if (*p != (r + j)) {
+		failed++;
+		printf("%d [%08lx] + %d -> %08lx ",
+				i, (unsigned int)bsp, j, (unsigned int)p);
+		printf("(read %d instead of %d)\n", (int)*p, r + j);
+	    }
+	}
+	bsp++;
+    }
+
+    printf("uwx_selftest_bsp_arithmetic: minus tests...\n");
+    bsp = &bstore[161];
+    for (i = 63; i >= 0; i--) {
+	bsp--;
+	r = (int)*bsp;
+	if (r >= 1000)
+	    r -= 1000;
+	for (j = 0; j < 96; j++) {
+	    p = (uint64_t *)(intptr_t)uwx_add_to_bsp((uint64_t)bsp, -j);
+	    if (*p != (r - j)) {
+		failed++;
+		printf("%d [%08lx] - %d -> %08lx ",
+				i, (unsigned int)bsp, j, (unsigned int)p);
+		printf("(read %d instead of %d)\n", (int)*p, r - j);
+	    }
+	}
+    }
+
+    return failed;
+}
+#endif


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_context.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_context.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_context.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_context.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,26 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+extern uint64_t uwx_add_to_bsp(uint64_t bsp, int nslots);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_context.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_env.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_env.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_env.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,222 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+#include "uwx_env.h"
+#include "uwx_scoreboard.h"
+#include "uwx_str.h"
+#include "uwx_trace.h"
+
+#ifdef _KERNEL
+static struct uwx_env uwx_env;
+#define	free(p)		/* nullified */
+#define	malloc(sz)	((sz == sizeof(uwx_env)) ? &uwx_env : NULL)
+#endif
+
+alloc_cb uwx_allocate_cb = 0;
+free_cb uwx_free_cb = 0;
+
+int uwx_register_alloc_cb(alloc_cb alloc, free_cb free)
+{
+    uwx_allocate_cb = alloc;
+    uwx_free_cb = free;
+    return UWX_OK;
+}
+
+int uwx_init_history(struct uwx_env *env)
+{
+    int i;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    for (i = 0; i < NSPECIALREG; i++)
+	env->history.special[i] = UWX_DISP_REG(i);;
+    for (i = 0; i < NPRESERVEDGR; i++)
+	env->history.gr[i] = UWX_DISP_REG(UWX_REG_GR(4+i));
+    for (i = 0; i < NPRESERVEDBR; i++)
+	env->history.br[i] = UWX_DISP_REG(UWX_REG_BR(1+i));
+    for (i = 0; i < 4; i++)
+	env->history.fr[i] = UWX_DISP_REG(UWX_REG_FR(2+i));
+    for ( ; i < NPRESERVEDFR; i++)
+	env->history.fr[i] = UWX_DISP_REG(UWX_REG_FR(12+i));
+
+    return UWX_OK;
+}
+
+int uwx_init_env(struct uwx_env *env, size_t total_size)
+{
+    int i;
+    struct uwx_str_pool *str_pool;
+    struct uwx_scoreboard *scoreboards;
+
+    str_pool = (struct uwx_str_pool *)(env + 1);
+    scoreboards = (struct uwx_scoreboard *)(str_pool + 1);
+
+    if (sizeof(struct uwx_env) + sizeof(struct uwx_str_pool) > total_size)
+	return UWX_ERR_NOMEM;
+    total_size -= sizeof(struct uwx_env) + sizeof(struct uwx_str_pool);
+
+    env->context.valid_regs = 0;
+    env->context.valid_frs = 0;
+    for (i = 0; i < NSPECIALREG; i++)
+	env->context.special[i] = 0;
+    for (i = 0; i < NPRESERVEDGR; i++)
+	env->context.gr[i] = 0;
+    for (i = 0; i < NPRESERVEDBR; i++)
+	env->context.br[i] = 0;
+    for (i = 0; i < NPRESERVEDFR; i++) {
+	env->context.fr[i].part0 = 0;
+	env->context.fr[i].part1 = 0;
+    }
+    env->rstate = 0;
+    env->remapped_ip = 0;
+    env->function_offset = 0;
+    env->ptr_size = DWORDSZ;
+    env->uinfo_hdr = 0;
+    env->uinfo_end = 0;
+    env->code_start = 0;
+    env->text_base = 0;
+    (void)uwx_init_history(env);
+    if (uwx_allocate_cb != NULL)
+	env->allocate_cb = uwx_allocate_cb;
+    else
+	env->allocate_cb = NULL;
+    if (uwx_free_cb != NULL)
+	env->free_cb = uwx_free_cb;
+    else
+	env->free_cb = NULL;
+    env->free_scoreboards = 0;
+    env->used_scoreboards = 0;
+    env->labeled_scoreboards = 0;
+    (void)uwx_init_str_pool(env, str_pool);
+    env->module_name = 0;
+    env->function_name = 0;
+    env->cb_token = 0;
+    env->copyin = 0;
+    env->lookupip = 0;
+    env->remote = 0;
+    env->byte_swap = 0;
+    env->abi_context = 0;
+    env->nsbreg = NSBREG;
+    env->nscoreboards = 0;
+    env->on_heap = 0;
+    env->trace = 0;
+    TRACE_INIT
+    for (i = 0; total_size >= sizeof(struct uwx_scoreboard); i++) {
+	(void) uwx_prealloc_scoreboard(env, &scoreboards[i]);
+	total_size -= sizeof(struct uwx_scoreboard);
+    }
+    return UWX_OK;
+}
+
+int uwx_set_nofr(struct uwx_env *env)
+{
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    env->nsbreg = NSBREG_NOFR;
+    return UWX_OK;
+}
+
+struct uwx_env *uwx_init()
+{
+    struct uwx_env *env;
+    size_t total_size;
+
+    total_size = sizeof(struct uwx_env) +
+		    sizeof(struct uwx_str_pool) +
+			NSCOREBOARDS * sizeof(struct uwx_scoreboard);
+
+    if (uwx_allocate_cb == 0)
+	env = (struct uwx_env *) malloc(total_size);
+    else
+	env = (struct uwx_env *) (*uwx_allocate_cb)(total_size);
+    if (env != 0) {
+	uwx_init_env(env, total_size);
+	env->on_heap = 1;
+    }
+    return env;
+}
+
+int uwx_set_remote(struct uwx_env *env, int is_big_endian_target)
+{
+    int is_big_endian_host;
+    char *p;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    env->remote = 1;
+
+    is_big_endian_host = 1;
+    p = (char *)&is_big_endian_host;
+    *p = 0;
+    if (is_big_endian_target == is_big_endian_host)
+	env->byte_swap = 0;
+    else
+	env->byte_swap = 1;
+
+    return UWX_OK;
+}
+
+int uwx_register_callbacks(
+    struct uwx_env *env,
+    intptr_t tok,
+    copyin_cb copyin,
+    lookupip_cb lookupip)
+{
+    if (env == 0)
+	return UWX_ERR_NOENV;
+    env->cb_token = tok;
+    env->copyin = copyin;
+    env->lookupip = lookupip;
+    return UWX_OK;
+}
+
+int uwx_get_abi_context_code(struct uwx_env *env)
+{
+    if (env == 0)
+	return UWX_ERR_NOENV;
+    return env->abi_context;
+}
+
+int uwx_free(struct uwx_env *env)
+{
+    if (env != 0) {
+	uwx_free_scoreboards(env);
+	uwx_free_str_pool(env);
+	if (env->on_heap) {
+	    if (env->free_cb == 0)
+		free((void *)env);
+	    else
+		(*env->free_cb)((void *)env);
+	}
+    }
+    return UWX_OK;
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_env.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_env.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_env.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_env.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,112 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx.h"
+
+#define WORDSZ			4
+#define DWORDSZ			8
+#define BUNDLESZ		16
+#define SLOTSPERBUNDLE		3
+
+#define UNWIND_TBL_32BIT	0x8000000000000000LL
+
+#define UNW_VER(x)		((x) >> 48)
+#define UNW_FLAG_MASK		0x0000ffff00000000LL
+#define UNW_FLAG_EHANDLER	0x0000000100000000LL
+#define UNW_FLAG_UHANDLER	0x0000000200000000LL
+#define UNW_LENGTH(x)		((x) & 0x00000000ffffffffLL)
+
+struct uwx_scoreboard;
+
+#define NSCOREBOARDS	8	/* Initial allocation of scoreboards */
+
+#define NSPECIALREG	16	/* Must be even, so FRs are aligned */
+#define NPRESERVEDGR	4
+#define NPRESERVEDBR	5
+#define NPRESERVEDFR	20
+
+struct uwx_fpreg {
+    uint64_t part0;
+    uint64_t part1;
+};
+
+struct uwx_context {
+    unsigned int valid_regs;
+    unsigned int valid_frs;
+    uint64_t special[NSPECIALREG];
+    uint64_t gr[NPRESERVEDGR];
+    uint64_t br[NPRESERVEDBR];
+    struct uwx_fpreg fr[NPRESERVEDFR];
+};
+
+#define VALID_GR_SHIFT	NSPECIALREG
+#define VALID_BR_SHIFT	(NSPECIALREG + NPRESERVEDGR)
+
+#define VALID_BASIC4	0x0f	/* IP, SP, BSP, CFM */
+#define VALID_MARKERS	0x70	/* RP, PSP, PFS */
+
+struct uwx_history {
+    uint64_t special[NSPECIALREG];
+    uint64_t gr[NPRESERVEDGR];
+    uint64_t br[NPRESERVEDBR];
+    uint64_t fr[NPRESERVEDFR];
+};
+
+struct uwx_str_pool;
+
+struct uwx_env {
+    struct uwx_context context;
+    uint64_t *rstate;
+    uint64_t remapped_ip;
+    int64_t function_offset;
+    uint64_t ptr_size;
+    uint64_t uinfo_hdr;
+    uint64_t uinfo_end;
+    uint64_t code_start;
+    uint64_t text_base;
+    struct uwx_history history;
+    alloc_cb allocate_cb;
+    free_cb free_cb;
+    struct uwx_scoreboard *free_scoreboards;
+    struct uwx_scoreboard *used_scoreboards;
+    struct uwx_scoreboard *labeled_scoreboards;
+    struct uwx_str_pool *string_pool;
+    char *module_name;
+    char *function_name;
+    intptr_t cb_token;
+    copyin_cb copyin;
+    lookupip_cb lookupip;
+    int remote;
+    int byte_swap;
+    int abi_context;
+    int nsbreg;
+    int nscoreboards;
+    int on_heap;
+    int trace;
+};
+
+extern alloc_cb uwx_allocate_cb;
+extern free_cb uwx_free_cb;
+extern int uwx_init_env(struct uwx_env *env, size_t total_size);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_env.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,316 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef _KERNEL
+#include <stdlib.h>
+#endif
+
+#include "uwx_env.h"
+#include "uwx_scoreboard.h"
+#include "uwx_trace.h"
+
+#ifdef _KERNEL
+static unsigned short uwx_allocated;
+static struct uwx_scoreboard uwx_scoreboard[sizeof(uwx_allocated) << 3];
+
+static void
+free(struct uwx_scoreboard *p)
+{
+	int idx = p - uwx_scoreboard;
+	uwx_allocated &= ~(1 << idx);
+}
+
+static struct uwx_scoreboard *
+malloc(size_t sz)
+{
+	int idx;
+	if (sz != sizeof(struct uwx_scoreboard))
+		return (NULL);
+	for (idx = 0; idx < (sizeof(uwx_allocated) << 3); idx++) {
+		if ((uwx_allocated & (1 << idx)) == 0) {
+			uwx_allocated |= 1 << idx;
+			return (uwx_scoreboard + idx);
+		}
+	}
+	return (NULL);
+}
+#endif
+
+
+void uwx_prealloc_scoreboard(struct uwx_env *env, struct uwx_scoreboard *sb)
+{
+    sb->id = env->nscoreboards++;
+    sb->nextused = env->used_scoreboards;
+    sb->prealloc = 1;
+    env->used_scoreboards = sb;
+    TRACE_B_PREALLOC(sb->id)
+}
+
+struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env)
+{
+    struct uwx_scoreboard *sb;
+    int i;
+
+    if (env->free_scoreboards != 0) {
+	sb = env->free_scoreboards;
+	env->free_scoreboards = sb->nextfree;
+	TRACE_B_REUSE(sb->id)
+    }
+    else {
+	if (env->allocate_cb == 0)
+	    sb = (struct uwx_scoreboard *)
+			malloc(sizeof(struct uwx_scoreboard));
+	else
+	    sb = (struct uwx_scoreboard *)
+			(*env->allocate_cb)(sizeof(struct uwx_scoreboard));
+	if (sb == 0)
+	    return 0;
+	sb->id = env->nscoreboards++;
+	sb->nextused = env->used_scoreboards;
+	sb->prealloc = 0;
+	env->used_scoreboards = sb;
+	TRACE_B_ALLOC(sb->id)
+    }
+
+    sb->nextstack = 0;
+    sb->nextlabel = 0;
+    for (i = 0; i < env->nsbreg; i++)
+	sb->rstate[i] = UWX_DISP_NONE;
+    sb->rstate[SBREG_RP] = UWX_DISP_REG(UWX_REG_BR(0));
+    sb->rstate[SBREG_PSP] = UWX_DISP_SPPLUS(0);
+    sb->rstate[SBREG_PFS] = UWX_DISP_REG(UWX_REG_AR_PFS);
+    sb->rstate[SBREG_PRIUNAT] = UWX_DISP_REG(UWX_REG_AR_UNAT);
+    sb->label = 0;
+    return sb;
+}
+
+static
+void uwx_reclaim_scoreboards(struct uwx_env *env)
+{
+    struct uwx_scoreboard *sb;
+
+    env->free_scoreboards = 0;
+    for (sb = env->used_scoreboards; sb != 0; sb = sb->nextused) {
+	sb->nextfree = env->free_scoreboards;
+	env->free_scoreboards = sb;
+    }
+    env->labeled_scoreboards = 0;
+}
+
+struct uwx_scoreboard *uwx_init_scoreboards(struct uwx_env *env)
+{
+    struct uwx_scoreboard *sb;
+
+    uwx_reclaim_scoreboards(env);
+    sb = uwx_alloc_scoreboard(env);
+    return sb;
+}
+
+struct uwx_scoreboard *uwx_new_scoreboard(
+    struct uwx_env *env,
+    struct uwx_scoreboard *prevsb)
+{
+    int i;
+    struct uwx_scoreboard *sb;
+
+    sb = uwx_alloc_scoreboard(env);
+    if (sb == 0)
+	return 0;
+    sb->nextstack = prevsb;
+    for (i = 0; i < env->nsbreg; i++)
+	sb->rstate[i] = prevsb->rstate[i];
+    return sb;
+}
+
+struct uwx_scoreboard *uwx_pop_scoreboards(
+    struct uwx_env *env,
+    struct uwx_scoreboard *sb,
+    int ecount)
+{
+    struct uwx_scoreboard *next;
+
+    while (ecount > 0) {
+	next = sb->nextstack;
+	TRACE_B_POP(sb->id)
+	sb->nextstack = 0;
+	sb->nextfree = env->free_scoreboards;
+	env->free_scoreboards = sb;
+	sb = next;
+	if (sb == 0)
+	    return 0;
+	ecount--;
+    }
+    return sb;
+}
+
+int uwx_label_scoreboard(
+    struct uwx_env *env,
+    struct uwx_scoreboard *sb,
+    int label)
+{
+    struct uwx_scoreboard *new;
+    struct uwx_scoreboard *back;
+    struct uwx_scoreboard *next;
+    int i;
+
+    TRACE_B_LABEL(label)
+
+    /* Copy the current stack, storing reverse links */
+    /* in the "nextstack" field. */
+
+    back = 0;
+    new = 0;
+    while (sb != 0) {
+	TRACE_B_LABEL_COPY(sb->id)
+	new = uwx_alloc_scoreboard(env);
+	if (new == 0)
+	    return UWX_ERR_NOMEM;
+	new->nextstack = back;
+	for (i = 0; i < env->nsbreg; i++)
+	    new->rstate[i] = sb->rstate[i];
+	sb = sb->nextstack;
+	back = new;
+    }
+
+    /* The "new" pointer now points to the bottom of the new stack, */
+    /* and the "nextstack" links lead towards the top. */
+    /* Now go back down the stack, reversing the stack links to their */
+    /* proper direction. */
+
+    back = 0;
+    while (new != 0) {
+	next = new->nextstack;
+	new->nextstack = back;
+	TRACE_B_LABEL_REVERSE(back, new)
+	back = new;
+	new = next;
+    }
+
+    /* The "back" pointer now points to the top of the stack. */
+
+    back->label = label;
+    back->nextlabel = env->labeled_scoreboards;
+    env->labeled_scoreboards = back;
+    return UWX_OK;
+}
+
+int uwx_copy_scoreboard(
+    struct uwx_env *env,
+    struct uwx_scoreboard *sb,
+    int label)
+{
+    struct uwx_scoreboard *next;
+    struct uwx_scoreboard *next2;
+    struct uwx_scoreboard *lsb;
+    struct uwx_scoreboard *new;
+    struct uwx_scoreboard *back;
+    int i;
+
+    TRACE_B_COPY(label, sb->id)
+
+    /* Free the existing stack. */
+
+    next = sb->nextstack;
+    while (next != 0) {
+	TRACE_B_COPY_FREE(next->id)
+	next2 = next->nextstack;
+	next->nextstack = 0;
+	next->nextfree = env->free_scoreboards;
+	env->free_scoreboards = next;
+	next = next2;
+    }
+
+    /* Find the scoreboard with the requested label. */
+
+    for (lsb = env->labeled_scoreboards; lsb != 0; lsb = lsb->nextlabel) {
+	if (lsb->label == label)
+	    break;
+    }
+
+    if (lsb == 0)
+	return UWX_ERR_UNDEFLABEL;
+
+    TRACE_B_COPY_FOUND(lsb->id)
+
+    /* Copy the labeled scoreboard. */
+
+    sb->nextstack = 0;
+    sb->nextlabel = 0;
+    for (i = 0; i < env->nsbreg; i++)
+	sb->rstate[i] = lsb->rstate[i];
+    sb->label = 0;
+
+    /* Now copy its stack, storing reverse links in the nextstack field. */
+
+    back = sb;
+    new = 0;
+    for (next = lsb->nextstack; next != 0; next = next->nextstack) {
+	TRACE_B_COPY_COPY(next->id)
+	new = uwx_alloc_scoreboard(env);
+	if (new == 0)
+	    return UWX_ERR_NOMEM;
+	new->nextstack = back;
+	for (i = 0; i < env->nsbreg; i++)
+	    new->rstate[i] = next->rstate[i];
+	back = new;
+    }
+
+    /* The "new" pointer now points to the bottom of the new stack, */
+    /* and the "nextstack" links lead towards the top. */
+    /* Now go back down the stack, reversing the nextstack links to their */
+    /* proper direction. */
+
+    back = 0;
+    while (new != 0) {
+	next = new->nextstack;
+	new->nextstack = back;
+	TRACE_B_COPY_REVERSE(back, new)
+	back = new;
+	new = next;
+    }
+
+    return UWX_OK;
+}
+
+void uwx_free_scoreboards(struct uwx_env *env)
+{
+    struct uwx_scoreboard *sb;
+    struct uwx_scoreboard *next;
+
+    for (sb = env->used_scoreboards; sb != 0; sb = next) {
+	TRACE_B_FREE(sb->id)
+	next = sb->nextused;
+	if (!sb->prealloc) {
+	    if (env->free_cb == 0)
+		free((void *)sb);
+	    else
+		(*env->free_cb)((void *)sb);
+	}
+    }
+    env->free_scoreboards = 0;
+    env->used_scoreboards = 0;
+    env->labeled_scoreboards = 0;
+}
+


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,85 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define NSB_SPECIAL	9
+#define NSB_GR		4
+#define NSB_BR		5
+#define NSB_FR		20
+
+#define SBREG_RP	0
+#define SBREG_PSP	1
+#define SBREG_PFS	2
+#define SBREG_PREDS	3
+#define SBREG_UNAT	4
+#define SBREG_PRIUNAT	5
+#define SBREG_RNAT	6
+#define SBREG_LC	7
+#define SBREG_FPSR	8
+#define SBREG_GR	(0 + NSB_SPECIAL)
+#define SBREG_BR	(SBREG_GR + NSB_GR)
+#define SBREG_FR	(SBREG_BR + NSB_BR)
+
+#define NSBREG_NOFR	(NSB_SPECIAL + NSB_GR + NSB_BR)
+#define NSBREG		(NSB_SPECIAL + NSB_GR + NSB_BR + NSB_FR)
+
+struct uwx_scoreboard {
+    struct uwx_scoreboard *nextused;
+    struct uwx_scoreboard *nextfree;
+    struct uwx_scoreboard *nextstack;
+    struct uwx_scoreboard *nextlabel;
+    uint64_t rstate[NSBREG];
+    int label;
+    int id;
+    int prealloc;
+};
+
+extern void uwx_prealloc_scoreboard(
+    struct uwx_env *env,
+    struct uwx_scoreboard *sb);
+
+extern struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env);
+
+extern struct uwx_scoreboard *uwx_init_scoreboards(struct uwx_env *env);
+
+extern struct uwx_scoreboard *uwx_new_scoreboard(
+    struct uwx_env *env,
+    struct uwx_scoreboard *prevsb);
+
+extern struct uwx_scoreboard *uwx_pop_scoreboards(
+    struct uwx_env *env,
+    struct uwx_scoreboard *sb,
+    int ecount);
+
+extern int uwx_label_scoreboard(
+    struct uwx_env *env,
+    struct uwx_scoreboard *sb,
+    int label);
+
+extern int uwx_copy_scoreboard(
+    struct uwx_env *env,
+    struct uwx_scoreboard *sb,
+    int label);
+
+extern void uwx_free_scoreboards(struct uwx_env *env);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_self.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_self.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_self.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,443 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <crt0.h>
+#include <dlfcn.h>
+#include <sys/uc_access.h>
+
+#include "uwx_env.h"
+#include "uwx_context.h"
+#include "uwx_trace.h"
+#include "uwx_self.h"
+#include "uwx_self_info.h"
+
+#define UWX_ABI_HPUX_SIGCONTEXT 0x0101	/* abi = HP-UX, context = 1 */
+
+void uwx_free_load_module_cache(struct uwx_self_info *info);
+
+int uwx_self_init_info_block(struct uwx_env *env, struct uwx_self_info *info)
+{
+    info->env = env;
+    info->ucontext = 0;
+    info->bspstore = 0;
+    info->sendsig_start = __load_info->li_sendsig_txt;
+    info->sendsig_end = __load_info->li_sendsig_txt +
+				__load_info->li_sendsig_tsz;
+    info->on_heap = 0;
+    info->trace = env->trace;
+    info->load_module_cache = NULL;
+
+    return UWX_OK;
+}
+
+struct uwx_self_info *uwx_self_init_info(struct uwx_env *env)
+{
+    struct uwx_self_info *info;
+
+    info = (struct uwx_self_info *)
+			(*env->allocate_cb)(sizeof(struct uwx_self_info));
+    if (info == 0)
+	return 0;
+
+    uwx_self_init_info_block(env, info);
+    info->on_heap = 1;
+    return info;
+}
+
+int uwx_self_free_info(struct uwx_self_info *info)
+{
+    int i;
+
+    if (info->load_module_cache != NULL)
+	uwx_free_load_module_cache(info);
+    if (info->on_heap)
+	(*info->env->free_cb)((void *)info);
+    return UWX_OK;
+}
+
+int uwx_self_init_from_sigcontext(
+    struct uwx_env *env,
+    struct uwx_self_info *info,
+    ucontext_t *ucontext)
+{
+    int status;
+    uint16_t reason;
+    uint64_t ip;
+    uint64_t sp;
+    uint64_t bsp;
+    uint64_t cfm;
+    unsigned int nat;
+    uint64_t ec;
+    int adj;
+
+    info->ucontext = ucontext;
+    status = __uc_get_reason(ucontext, &reason);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+    status = __uc_get_ip(ucontext, &ip);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+    status = __uc_get_grs(ucontext, 12, 1, &sp, &nat);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+    status = __uc_get_cfm(ucontext, &cfm);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+#ifdef NEW_UC_GET_AR
+    status = __uc_get_ar_bsp(ucontext, &bsp);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+    status = __uc_get_ar_bspstore(ucontext, &info->bspstore);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+    status = __uc_get_ar_ec(ucontext, &ec);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+#else
+    status = __uc_get_ar(ucontext, 17, &bsp);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+    status = __uc_get_ar(ucontext, 18, &info->bspstore);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+    status = __uc_get_ar(ucontext, 66, &ec);
+    if (status != 0)
+	return UWX_ERR_UCACCESS;
+#endif
+    /* The returned bsp needs to be adjusted. */
+    /* For interrupt frames, where bsp was advanced by a cover */
+    /* instruction, subtract sof (size of frame). For non-interrupt */
+    /* frames, where bsp was advanced by br.call, subtract sol */
+    /* (size of locals). */
+    if (reason != 0)
+	adj = (unsigned int)cfm & 0x7f;		/* interrupt frame */
+    else
+	adj = ((unsigned int)cfm >> 7) & 0x7f;	/* non-interrupt frame */
+    bsp = uwx_add_to_bsp(bsp, -adj);
+    cfm |= ec << 52;
+    uwx_init_context(env, ip, sp, bsp, cfm);
+    return UWX_OK;
+}
+
+int uwx_self_do_context_frame(
+    struct uwx_env *env,
+    struct uwx_self_info *info)
+{
+    int abi_context;
+    int status;
+    uint64_t ucontext;
+
+    abi_context = uwx_get_abi_context_code(env);
+    if (abi_context != UWX_ABI_HPUX_SIGCONTEXT)
+	return UWX_SELF_ERR_BADABICONTEXT;
+    status = uwx_get_reg(env, UWX_REG_GR(32), (uint64_t *)&ucontext);
+    if (status != UWX_OK)
+	return status;
+    return uwx_self_init_from_sigcontext(env, info,
+					(ucontext_t *)(intptr_t)ucontext);
+}
+
+int uwx_self_copyin(
+    int request,
+    char *loc,
+    uint64_t rem,
+    int len,
+    intptr_t tok)
+{
+    int status;
+    int regid;
+    unsigned int nat;
+    struct uwx_self_info *info = (struct uwx_self_info *) tok;
+    unsigned long *wp;
+    uint64_t *dp;
+
+    status = -1;
+
+    dp = (uint64_t *) loc;
+
+    switch (request) {
+	case UWX_COPYIN_UINFO:
+	case UWX_COPYIN_MSTACK:
+	    if (len == 4) {
+		wp = (unsigned long *) loc;
+		*wp = *(unsigned long *)(intptr_t)rem;
+		TRACE_SELF_COPYIN4(rem, len, wp)
+		status = 0;
+	    }
+	    else if (len == 8) {
+		*dp = *(uint64_t *)(intptr_t)rem;
+		TRACE_SELF_COPYIN8(rem, len, dp)
+		status = 0;
+	    }
+	    break;
+	case UWX_COPYIN_RSTACK:
+	    if (len == 8) {
+		if (info->ucontext == 0 && rem == (info->bspstore | 0x1f8)) {
+		    *dp = info->env->context.special[UWX_REG_AR_RNAT];
+		    status = 0;
+		}
+		else if (info->ucontext == 0 || rem < info->bspstore) {
+		    *dp = *(uint64_t *)(intptr_t)rem;
+		    TRACE_SELF_COPYIN8(rem, len, dp)
+		    status = 0;
+		}
+		else {
+		    status = __uc_get_rsebs(info->ucontext,
+					    (uint64_t *)(intptr_t)rem, 1, dp);
+		}
+	    }
+	    break;
+	case UWX_COPYIN_REG:
+	    regid = (int)rem;
+	    if (info->ucontext != 0) {
+		if (len == 8) {
+		    if (rem == UWX_REG_PREDS)
+			status = __uc_get_prs(info->ucontext, dp);
+		    else if (rem == UWX_REG_AR_PFS)
+			status = __uc_get_ar(info->ucontext, 64, dp);
+		    else if (rem == UWX_REG_AR_RNAT)
+			status = __uc_get_ar(info->ucontext, 19, dp);
+		    else if (rem == UWX_REG_AR_UNAT)
+			status = __uc_get_ar(info->ucontext, 36, dp);
+		    else if (rem == UWX_REG_AR_FPSR)
+			status = __uc_get_ar(info->ucontext, 40, dp);
+		    else if (rem == UWX_REG_AR_LC)
+			status = __uc_get_ar(info->ucontext, 65, dp);
+		    else if (regid >= UWX_REG_GR(1) &&
+						regid <= UWX_REG_GR(31))
+			status = __uc_get_grs(info->ucontext,
+					    regid - UWX_REG_GR(0), 1, dp, &nat);
+		    else if (regid >= UWX_REG_BR(0) &&
+						regid <= UWX_REG_BR(7))
+			status = __uc_get_brs(info->ucontext,
+					    regid - UWX_REG_BR(0), 1, dp);
+		}
+		else if (len == 16) {
+		    if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(127)) {
+			status = __uc_get_frs(info->ucontext,
+				regid - UWX_REG_FR(0), 1, (fp_regval_t *)dp);
+		    }
+		}
+	    }
+	    break;
+    }
+    if (status != 0)
+	return 0;
+    return len;
+}
+
+#define MODULE_CACHE_SIZE 4
+
+struct load_module_cache {
+    int clock;
+    char *names[MODULE_CACHE_SIZE];
+    struct load_module_desc descs[MODULE_CACHE_SIZE];
+    struct uwx_symbol_cache *symbol_cache;
+};
+
+void uwx_free_load_module_cache(struct uwx_self_info *info)
+{
+    int i;
+
+    for (i = 0; i < MODULE_CACHE_SIZE; i++) {
+	if (info->load_module_cache->names[i] != NULL)
+	    (*info->env->free_cb)((void *)info->load_module_cache->names[i]);
+    }
+
+    if (info->load_module_cache->symbol_cache != NULL)
+	uwx_release_symbol_cache(info->env,
+				    info->load_module_cache->symbol_cache);
+
+    (*info->env->free_cb)((void *)info->load_module_cache);
+}
+
+struct load_module_desc *uwx_get_modinfo(
+    struct uwx_self_info *info,
+    uint64_t ip,
+    char **module_name_p)
+{
+    int i;
+    UINT64 handle;
+    struct load_module_cache *cache;
+    struct load_module_desc *desc;
+    char *module_name;
+
+    cache = info->load_module_cache;
+    if (cache == NULL) {
+	cache = (struct load_module_cache *)
+		(*info->env->allocate_cb)(sizeof(struct load_module_cache));
+	if (cache == NULL)
+	    return NULL;
+	for (i = 0; i < MODULE_CACHE_SIZE; i++) {
+	    desc = &cache->descs[i];
+	    desc->text_base = 0;
+	    desc->text_size = 0;
+	    cache->names[i] = NULL;
+	}
+	cache->clock = 0;
+	cache->symbol_cache = NULL;
+	info->load_module_cache = cache;
+    }
+    for (i = 0; i < MODULE_CACHE_SIZE; i++) {
+	desc = &cache->descs[i];
+	if (ip >= desc->text_base && ip < desc->text_base + desc->text_size)
+	    break;
+    }
+    if (i >= MODULE_CACHE_SIZE) {
+	i = cache->clock;
+	cache->clock = (cache->clock + 1) % MODULE_CACHE_SIZE;
+	desc = &cache->descs[i];
+	handle = dlmodinfo(ip, desc, sizeof(*desc), 0, 0, 0);
+	if (handle == 0)
+	    return NULL;
+	if (cache->names[i] != NULL)
+	    (*info->env->free_cb)(cache->names[i]);
+	cache->names[i] = NULL;
+    }
+    if (module_name_p != NULL) {
+	if (cache->names[i] == NULL) {
+	    module_name = dlgetname(desc, sizeof(*desc), 0, 0, 0);
+	    if (module_name != NULL) {
+		cache->names[i] = (char *)
+			    (*info->env->allocate_cb)(strlen(module_name)+1);
+		if (cache->names[i] != NULL)
+		    strcpy(cache->names[i], module_name);
+	    }
+	}
+	*module_name_p = cache->names[i];
+    }
+    return desc;
+}
+
+int uwx_self_lookupip(
+    int request,
+    uint64_t ip,
+    intptr_t tok,
+    uint64_t **resultp)
+{
+    struct uwx_self_info *info = (struct uwx_self_info *) tok;
+    UINT64 handle;
+    struct load_module_desc *desc;
+    uint64_t *unwind_base;
+    uint64_t *rvec;
+    char *module_name;
+    char *func_name;
+    uint64_t offset;
+    int i;
+    int status;
+
+    if (request == UWX_LKUP_LOOKUP) {
+	TRACE_SELF_LOOKUP(ip)
+	if (ip >= info->sendsig_start && ip < info->sendsig_end) {
+	    i = 0;
+	    rvec = info->rvec;
+	    rvec[i++] = UWX_KEY_CONTEXT;
+	    rvec[i++] = UWX_ABI_HPUX_SIGCONTEXT;
+	    rvec[i++] = UWX_KEY_END;
+	    rvec[i++] = 0;
+	    *resultp = rvec;
+	    return UWX_LKUP_FDESC;
+	}
+	else {
+	    desc = uwx_get_modinfo(info, ip, NULL);
+	    if (desc == NULL)
+		return UWX_LKUP_ERR;
+	    unwind_base = (uint64_t *) (intptr_t) desc->unwind_base;
+	    TRACE_SELF_LOOKUP_DESC(desc->text_base,
+					desc->linkage_ptr, unwind_base)
+	    i = 0;
+	    rvec = info->rvec;
+	    rvec[i++] = UWX_KEY_TBASE;
+	    rvec[i++] = desc->text_base;
+	    rvec[i++] = UWX_KEY_UFLAGS;
+	    rvec[i++] = unwind_base[0];
+	    rvec[i++] = UWX_KEY_USTART;
+	    rvec[i++] = desc->text_base + unwind_base[1];
+	    rvec[i++] = UWX_KEY_UEND;
+	    rvec[i++] = desc->text_base + unwind_base[2];
+	    rvec[i++] = UWX_KEY_GP;
+	    rvec[i++] = desc->linkage_ptr;
+	    rvec[i++] = UWX_KEY_END;
+	    rvec[i++] = 0;
+	    *resultp = rvec;
+	    return UWX_LKUP_UTABLE;
+	}
+    }
+    else if (request == UWX_LKUP_FREE) {
+	return 0;
+    }
+    else if (request == UWX_LKUP_MODULE) {
+	desc = uwx_get_modinfo(info, ip, &module_name);
+	if (desc == NULL)
+	    return UWX_LKUP_ERR;
+	if (module_name == NULL)
+	    return UWX_LKUP_ERR;
+	i = 0;
+	rvec = info->rvec;
+	rvec[i++] = UWX_KEY_MODULE;
+	rvec[i++] = (uint64_t)(intptr_t)module_name;
+	rvec[i++] = UWX_KEY_TBASE;
+	rvec[i++] = desc->text_base;
+	rvec[i++] = UWX_KEY_END;
+	rvec[i++] = 0;
+	*resultp = rvec;
+	return UWX_LKUP_SYMINFO;
+    }
+    else if (request == UWX_LKUP_SYMBOLS) {
+	rvec = *resultp;
+	for (i = 0; rvec[i] != UWX_KEY_END; i += 2) {
+	    if (rvec[i] == UWX_KEY_FUNCSTART)
+		ip = rvec[i+1];
+	}
+	desc = uwx_get_modinfo(info, ip, &module_name);
+	if (desc == NULL)
+	    return UWX_LKUP_ERR;
+	if (module_name == NULL)
+	    return UWX_LKUP_ERR;
+	status = uwx_find_symbol(info->env,
+			&info->load_module_cache->symbol_cache,
+			module_name, ip - desc->text_base,
+			&func_name, &offset);
+	i = 0;
+	rvec = info->rvec;
+	rvec[i++] = UWX_KEY_MODULE;
+	rvec[i++] = (uint64_t)(intptr_t)module_name;
+	rvec[i++] = UWX_KEY_TBASE;
+	rvec[i++] = desc->text_base;
+	if (status == UWX_OK) {
+	    rvec[i++] = UWX_KEY_FUNC;
+	    rvec[i++] = (uint64_t)(intptr_t)func_name;
+	    rvec[i++] = UWX_KEY_FUNCSTART;
+	    rvec[i++] = ip - offset;
+	}
+	rvec[i++] = UWX_KEY_END;
+	rvec[i++] = 0;
+	*resultp = rvec;
+	return UWX_LKUP_SYMINFO;
+    }
+    return UWX_LKUP_ERR;
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_self.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_self.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_self.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_self.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,113 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef __UWX_SELF_INCLUDED
+#define __UWX_SELF_INCLUDED 1
+
+#include <signal.h>
+
+#ifndef __UWX_INCLUDED
+#include "uwx.h"
+#endif /* __UWX_INCLUDED */
+
+#if defined(__cplusplus)
+#define __EXTERN_C extern "C"
+#else
+#define __EXTERN_C extern
+#endif
+
+struct uwx_self_info;
+
+__EXTERN_C struct uwx_self_info *uwx_self_init_info(struct uwx_env *env);
+
+__EXTERN_C int uwx_self_free_info(struct uwx_self_info *info);
+
+__EXTERN_C int uwx_self_init_context(struct uwx_env *env);
+
+__EXTERN_C int uwx_self_init_from_sigcontext(
+    struct uwx_env *env,
+    struct uwx_self_info *info,
+    ucontext_t *ucontext);
+
+__EXTERN_C int uwx_self_do_context_frame(
+    struct uwx_env *env,
+    struct uwx_self_info *info);
+
+__EXTERN_C int uwx_self_copyin(
+    int request,
+    char *loc,
+    uint64_t rem,
+    int len,
+    intptr_t tok);
+
+__EXTERN_C int uwx_self_lookupip(
+    int request,
+    uint64_t ip,
+    intptr_t tok,
+    uint64_t **resultp);
+
+#define UWX_SELF_ERR_BADABICONTEXT  (-101)
+
+#undef __EXTERN_C
+
+#if defined(__cplusplus)
+
+class UnwindExpressSelf : public UnwindExpress {
+
+public:
+
+    UnwindExpressSelf() {
+	info = uwx_self_init_info(env);
+	(void)uwx_register_callbacks(env, (intptr_t)info,
+				uwx_self_copyin, uwx_self_lookupip);
+    }
+
+    ~UnwindExpressSelf() {
+	if (info != 0)
+	    uwx_self_free_info(info);
+	info = 0;
+    }
+
+    int init_context() {
+	return uwx_self_init_context(env);
+    }
+
+    int init_context(ucontext_t *ucontext) {
+	return uwx_self_init_from_sigcontext(env, info, ucontext);
+    }
+
+    int do_context_frame() {
+	return uwx_self_do_context_frame(env, info);
+    }
+
+protected:
+
+    struct uwx_self_info *info;
+
+};
+
+#endif /* __cplusplus */
+
+#endif /* __UWX_SELF_INCLUDED */


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_self.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_self_context.s
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_self_context.s	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_self_context.s	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,384 @@
+/* $MidnightBSD$ */
+// Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+
+#ifdef _LP64
+#define SWIZZLE add
+#define STPTR st8
+#else
+#define SWIZZLE addp4
+#define STPTR st4
+#endif
+
+rRP	= r14
+rPFS	= r15
+rUNAT	= r16
+rRNAT	= r17
+rENV0	= r18
+rENV1	= r19
+rENV2	= r20
+rNSLOT	= r21
+rBSP	= r22
+rPBSP	= r23
+rRSC	= r24
+rNATP	= r25
+rBIAS	= r26
+rRSC0	= r27
+rTMP1	= r28
+rTMP2	= r29
+rTMP3	= r30
+rTMP4	= r31
+rTMP5	= r8
+rMYPFS	= r9
+rPSP	= r10
+
+VALID_IP      = 1
+VALID_SP      = 1 << 1
+VALID_BSP     = 1 << 2
+VALID_CFM     = 1 << 3
+VALID_PREDS   = 1 << 7
+VALID_PRIUNAT = 1 << 8
+VALID_RNAT    = 1 << 10
+VALID_UNAT    = 1 << 11
+VALID_FPSR    = 1 << 12
+VALID_LC      = 1 << 13
+VALID_GRS     = 0xf << 16
+VALID_BRS     = 0x1f << 20
+VALID_BASIC4  = VALID_IP | VALID_SP | VALID_BSP | VALID_CFM
+VALID_SPEC    = VALID_PREDS | VALID_PRIUNAT | VALID_RNAT | VALID_UNAT | VALID_FPSR | VALID_LC
+VALID_REGS    = VALID_BASIC4 | VALID_SPEC | VALID_GRS | VALID_BRS
+VALID_FRS     = 0xfffff
+// valid_regs and valid_frs are separate unsigned int fields.
+// In order to store them with a single st8, we need to know
+// the endianness.
+#ifdef __LITTLE_ENDIAN__
+VALID_BITS   = (VALID_FRS << 32) | VALID_REGS
+#else
+VALID_BITS   = (VALID_REGS << 32) | VALID_FRS
+#endif
+
+	.text
+
+// int uwx_self_init_context(struct uwx_env *env);
+//
+// Stores a snapshot of the caller's context in the uwx_env structure.
+
+	.proc	uwx_self_init_context
+	.global uwx_self_init_context
+uwx_self_init_context:
+	.prologue
+	alloc	rPFS = ar.pfs, 1, 0, 0, 0
+	mov	rUNAT = ar.unat
+	.body
+	SWIZZLE	rENV0 = r0, r32		// rENV0 = &env
+	;;
+	flushrs
+	extr.u	rNSLOT = rPFS, 7, 7 	// nslots = pfs.sol
+	mov	rRP = b0
+	;;
+	mov	rRSC = ar.rsc
+	add	rENV1 = 136, rENV0	// rENV1 = &env->context.gr[0]
+	add	rENV2 = 144, rENV0	// rENV2 = &env->context.gr[1]
+	;;
+	and	rRSC0 = -4, rRSC	// clear ar.rsc.mode
+	adds	rNATP = 0x1f8, r0
+	mov	rTMP1 = b1
+	;;
+	st8.spill [rENV1] = r4, 16	// env+136: r4
+	st8.spill [rENV2] = r5, 16	// env+144: r5
+	mov	rTMP2 = b2
+	;;
+	st8.spill [rENV1] = r6, 16	// env+152: r6
+	st8.spill [rENV2] = r7, 16	// env+160: r7
+	mov	rTMP3 = b3
+	;;
+	st8	[rENV1] = rTMP1, 16	// env+168: b1
+	st8	[rENV2] = rTMP2, 16	// env+176: b2
+	mov	rTMP1 = b4
+	;;
+	st8	[rENV1] = rTMP3, 16	// env+184: b3
+	st8	[rENV2] = rTMP1, 16	// env+192: b4
+	mov	rTMP2 = b5
+	;;
+	st8	[rENV1] = rTMP2		// env+200: b5
+	mov	ar.rsc = rRSC0		// enforced lazy mode
+	add	rENV1 = 8, rENV0
+	;;
+	mov	rRNAT = ar.rnat		// get copy of ar.rnat
+	movl	rTMP1 = VALID_BITS	// valid_regs: ip, sp, bsp, cfm,
+					// preds, priunat, rnat, unat, fpsr,
+					// lc, grs, brs
+					// = 0x1ff3d8f00000000 
+	;;
+	mov	ar.rsc = rRSC		// restore ar.rsc
+	mov	rBSP = ar.bsp
+	add	rTMP3 = 136, rENV0	// spill_loc = &env->context.gr[0]
+	;;
+	mov	rTMP2 = ar.unat
+	nop
+	extr.u	rTMP3 = rTMP3, 3, 6	// bitpos = spill_loc{8:3}
+	;;
+	and	rBIAS = rBSP, rNATP	// bias = (bsp & 0x1f8) ...
+	sub	rTMP4 = 64, rTMP3	// (64 - bitpos)
+	shr	rTMP5 = rTMP2, rTMP3	// (unat >> bitpos)
+	;;
+	nop
+	extr.u	rBIAS = rBIAS, 3, 6	//   ... div 8
+	shl	rTMP2 = rTMP2, rTMP4	// (unat << (64 - bitpos))
+	;;
+	or	rTMP2 = rTMP2, rTMP5	// rotate_right(unat, bitpos)
+	nop
+	mov	rTMP4 = pr
+	;;
+	st8	[rENV0] = rTMP1, 16	// env+0: valid_regs mask
+	st8	[rENV1] = rRP, 24	// env+8: ip (my rp)
+	sub	rBIAS = rNSLOT, rBIAS	// bias = nslots - bias
+	;;
+	cmp.lt	p6, p0 = 0, rBIAS	// if (0 < bias) ...
+	cmp.lt	p7, p0 = 63, rBIAS	// if (63 < bias) ...
+	;;
+	st8	[rENV0] = r12, 48	// env+16: sp
+	st8	[rENV1] = rPFS, 40	// env+32: cfm (my pfs)
+(p6)	add	rNSLOT = 1, rNSLOT	//   ... nslots++
+	;;
+	st8	[rENV0] = rTMP4, 24	// env+64: preds
+	st8	[rENV1] = rTMP2, 24	// env+72: priunat
+(p7)	add	rNSLOT = 1, rNSLOT	//   ... nslots++
+	;;
+	st8	[rENV0] = rRNAT, -64	// env+88: ar.rnat
+	st8	[rENV1] = rUNAT, 8	// env+96: ar.unat
+	dep.z	rTMP3 = rNSLOT, 3, 7 	// (nslots << 3)
+	;;
+	sub	rPBSP = rBSP, rTMP3	// prev_bsp = bsp - (nslots << 3)
+	mov	rTMP3 = ar.fpsr
+	mov	rTMP1 = ar.lc
+	;;
+	st8	[rENV0] = rPBSP, 184	// env+24: bsp (my prev bsp)
+	st8	[rENV1] = rTMP3, 8	// env+104: ar.fpsr
+	add	rENV2 = 320, rENV2	// rENV2 = &env->context.rstate
+	;;
+	st8	[rENV1] = rTMP1, 112	// env+112: ar.lc
+	STPTR	[rENV2] = r0		// env+528: env->rstate = 0
+	nop
+	;;
+	// THIS CODE NEEDS TO BE SCHEDULED!!!
+	stf.spill [rENV0] = f2, 32	// env+208: f2
+	stf.spill [rENV1] = f3, 32	// env+224: f3
+	;;
+	stf.spill [rENV0] = f4, 32	// env+240: f4
+	stf.spill [rENV1] = f5, 32	// env+256: f5
+	;;
+	stf.spill [rENV0] = f16, 32	// env+272: f16
+	stf.spill [rENV1] = f17, 32	// env+288: f17
+	;;
+	stf.spill [rENV0] = f18, 32	// env+304: f16
+	stf.spill [rENV1] = f19, 32	// env+320: f17
+	;;
+	stf.spill [rENV0] = f20, 32	// env+336: f16
+	stf.spill [rENV1] = f21, 32	// env+352: f17
+	;;
+	stf.spill [rENV0] = f22, 32	// env+368: f16
+	stf.spill [rENV1] = f23, 32	// env+384: f17
+	;;
+	stf.spill [rENV0] = f24, 32	// env+400: f16
+	stf.spill [rENV1] = f25, 32	// env+416: f17
+	;;
+	stf.spill [rENV0] = f26, 32	// env+432: f16
+	stf.spill [rENV1] = f27, 32	// env+448: f17
+	;;
+	stf.spill [rENV0] = f28, 32	// env+464: f16
+	stf.spill [rENV1] = f29, 32	// env+480: f17
+	;;
+	stf.spill [rENV0] = f30, 32	// env+496: f16
+	stf.spill [rENV1] = f31, 32	// env+512: f17
+	;;
+	mov	ar.unat = rUNAT
+	mov	ret0 = r0		// return UWX_OK
+	br.ret.sptk b0
+	.endp
+
+// uwx_self_install_context(
+//		struct uwx_env *env,
+//		uint64_t r15,
+//		uint64_t r16,
+//		uint64_t r17,
+//		uint64_t r18,
+//		uint64_t ret
+//		);
+//
+// Installs the given context, and sets the landing pad binding
+// registers r15-r18 to the values given.
+// Returns the value "ret" to the new context (for testing --
+// when transferring to a landing pad, the new context won't
+// care about the return value).
+
+	.proc	uwx_self_install_context
+	.global uwx_self_install_context
+uwx_self_install_context:
+	.prologue
+	alloc	rMYPFS = ar.pfs, 6, 0, 0, 0
+	.body
+	SWIZZLE	rENV0 = r0, r32		// rENV0 = &env
+	;;
+
+	// THIS CODE NEEDS TO BE SCHEDULED!!!
+
+	// Restore GR 4-7 and ar.unat
+	add	rENV1 = 136, rENV0	// &env->context.gr[0]
+	add	rENV2 = 72, rENV0	// &env->context.priunat
+	;;
+	ld8	rTMP2 = [rENV2], 24	// env+72: priunat
+	extr.u	rTMP3 = rENV1, 3, 6	// bitpos = spill_loc{8:3}
+	;;
+	ld8	rUNAT = [rENV2], 48	// env+96: ar.unat
+	sub	rTMP4 = 64, rTMP3	// (64 - bitpos)
+	shl	rTMP5 = rTMP2, rTMP3	// (unat << bitpos)
+	;;
+	shr	rTMP2 = rTMP2, rTMP4	// (unat >> (64 - bitpos))
+	;;
+	or	rTMP2 = rTMP2, rTMP5	// rotate_left(unat, bitpos)
+	;;
+	mov	ar.unat = rTMP2		// put priunat in place
+	;;
+	ld8.fill r4 = [rENV1], 16	// env+136: r4
+	ld8.fill r5 = [rENV2], 16	// env+144: r5
+	;;
+	ld8.fill r6 = [rENV1], 16	// env+152: r6
+	ld8.fill r7 = [rENV2], 16	// env+160: r7
+	;;
+	mov	ar.unat = rUNAT		// restore real ar.unat
+
+	// Restore BR 1-5
+	ld8	rTMP1 = [rENV1], 16	// env+168: b1
+	ld8	rTMP2 = [rENV2], 16	// env+176: b2
+	;;
+	ld8	rTMP3 = [rENV1], 16	// env+184: b3
+	ld8	rTMP4 = [rENV2], -168	// env+192: b4
+	mov	b1 = rTMP1
+	;;
+	ld8	rTMP1 = [rENV1], -168	// env+200: b5
+	mov	b2 = rTMP2
+	mov	b3 = rTMP3
+	mov	b4 = rTMP4
+	;;
+	mov	b5 = rTMP1
+
+	// Restore ar.bsp, ar.pfs, and ar.rnat
+	ld8	rPFS = [rENV1], 56	// env+32: cfm (+saved ar.ec)
+	mov	rRSC = ar.rsc
+	adds	rBIAS = 0x1f8, r0
+	;;
+	flushrs
+	ld8	rRNAT = [rENV1], -24	// env+88: ar.rnat
+	ld8	rPBSP = [rENV2], 88	// env+24: prev_bsp
+	and	rRSC0 = -4, rRSC	// clear ar.rsc.mode
+	;;
+	mov	ar.rsc = rRSC0		// enforced lazy mode
+	extr.u	rNSLOT = rPFS, 7, 7 	// nslots = pfs.sol
+	;;
+	invala
+	and	rBIAS = rPBSP, rBIAS	// bias = prev_bsp & 0x1f8 ...
+	;;
+	extr.u	rBIAS = rBIAS, 3, 6	// ... div 8
+	;;
+	add	rBIAS = rNSLOT, rBIAS	// bias += nslots
+	;;
+	cmp.lt	p6, p0 = 63, rBIAS	// if (63 < bias) ...
+	cmp.lt	p7, p0 = 126, rBIAS	// if (126 < bias) ...
+	;;
+(p6)	add	rNSLOT = 1, rNSLOT	//   ... nslots++
+	;;
+(p7)	add	rNSLOT = 1, rNSLOT	//   ... nslots++
+	;;
+	dep.z	rTMP3 = rNSLOT, 3, 7 	// (nslots << 3)
+	;;
+	add	rBSP = rPBSP, rTMP3	// bsp = prev_bsp + (nslots << 3)
+	;;
+	mov	ar.bspstore = rBSP	// restore ar.bsp
+	;;
+	mov	ar.rnat = rRNAT		// restore ar.rnat
+	mov	ar.pfs = rPFS		// restore ar.pfs
+	;;
+	mov	ar.rsc = rRSC		// restore ar.rsc
+
+	// Restore preds and ar.lc
+	ld8	rTMP1 = [rENV1], -56	// env+64: preds
+	ld8	rTMP2 = [rENV2], -96	// env+112: ar.lc
+	;;
+	mov	pr = rTMP1
+	mov	ar.lc = rTMP2
+
+	// Get previous sp and ip
+	ld8	rRP = [rENV1], 96	// env+8: ip (my rp)
+	ld8	rPSP = [rENV2], 112	// env+16: sp
+	;;
+
+	// Restore ar.fpsr and gp
+	ld8	rTMP1 = [rENV1], 104	// env+104: ar.fpsr
+	ld8	r1 = [rENV2], 96	// env+128: gp
+	;;
+	mov	ar.fpsr = rTMP1		// restore ar.fpsr
+
+	// Restore FR 2-5 and 16-31
+	ldf.fill f2 = [rENV1], 32	// env+208: f2
+	ldf.fill f3 = [rENV2], 32	// env+224: f3
+	;;
+	ldf.fill f4 = [rENV1], 32	// env+240: f4
+	ldf.fill f5 = [rENV2], 32	// env+256: f5
+	;;
+	ldf.fill f16 = [rENV1], 32	// env+272: f16
+	ldf.fill f17 = [rENV2], 32	// env+288: f17
+	;;
+	ldf.fill f18 = [rENV1], 32	// env+304: f16
+	ldf.fill f19 = [rENV2], 32	// env+320: f17
+	;;
+	ldf.fill f20 = [rENV1], 32	// env+336: f16
+	ldf.fill f21 = [rENV2], 32	// env+352: f17
+	;;
+	ldf.fill f22 = [rENV1], 32	// env+368: f16
+	ldf.fill f23 = [rENV2], 32	// env+384: f17
+	;;
+	ldf.fill f24 = [rENV1], 32	// env+400: f16
+	ldf.fill f25 = [rENV2], 32	// env+416: f17
+	;;
+	ldf.fill f26 = [rENV1], 32	// env+432: f16
+	ldf.fill f27 = [rENV2], 32	// env+448: f17
+	;;
+	ldf.fill f28 = [rENV1], 32	// env+464: f16
+	ldf.fill f29 = [rENV2], 32	// env+480: f17
+	;;
+	ldf.fill f30 = [rENV1], 32	// env+496: f16
+	ldf.fill f31 = [rENV2], 32	// env+512: f17
+
+	// Set landing pad parameter registers
+	mov	r15 = r33
+	mov	r16 = r34
+	mov	r17 = r35
+	mov	r18 = r36
+
+	// Restore previous sp and Return
+	mov	ret0 = r37
+	mov	sp = rPSP
+	mov	b0 = rRP
+	br.ret.sptk b0
+
+	.endp


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_self_context.s
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_self_info.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_self_info.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_self_info.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,45 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define MAX_RVEC_SIZE 12
+
+struct load_module_cache;
+
+struct uwx_self_info {
+    struct uwx_env *env;
+    ucontext_t *ucontext;
+    uint64_t bspstore;
+    uint64_t rvec[MAX_RVEC_SIZE];
+    uint64_t sendsig_start;
+    uint64_t sendsig_end;
+    int on_heap;
+    int trace;
+    struct load_module_cache *load_module_cache;
+};
+
+extern int uwx_self_init_info_block(
+    struct uwx_env *env,
+    struct uwx_self_info *info
+    );


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_self_info.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_step.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_step.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_step.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,828 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx_env.h"
+#include "uwx_utable.h"
+#include "uwx_uinfo.h"
+#include "uwx_scoreboard.h"
+#include "uwx_str.h"
+#include "uwx_step.h"
+#include "uwx_trace.h"
+
+/*
+ *  uwx_step.c
+ *
+ *  This file contains the routines for stepping from one frame
+ *  into its callers frame. The context for the current frame
+ *  is maintained inside the current unwind environment
+ *  (struct uwx_env), and is updated with each call to
+ *  uwx_step() to refer to the previous frame.
+ */
+
+
+/* Forward Declarations */
+
+int uwx_decode_uvec(struct uwx_env *env, uint64_t *uvec, uint64_t **rstate);
+int uwx_restore_reg(struct uwx_env *env, uint64_t rstate,
+					uint64_t *valp, uint64_t *histp);
+int uwx_restore_freg(struct uwx_env *env, uint64_t rstate,
+					uint64_t *valp, uint64_t *histp);
+int uwx_restore_nat(struct uwx_env *env, uint64_t rstate, int unat);
+
+
+/* uwx_lookupip_hook: Hook routine so dynamic instrumentation */
+/*      tools can intercept Lookup IP events. When not */
+/*      intercepted, it just returns "Not found", so that */
+/*      the callback routine is invoked. */
+
+/*ARGSUSED*/
+int uwx_lookupip_hook(int request, uint64_t ip, intptr_t tok, uint64_t **vecp,
+			size_t uvecsize)
+{
+    return UWX_LKUP_NOTFOUND;
+}
+
+
+/* uwx_get_frame_info: Gets unwind info for current frame */
+static
+int uwx_get_frame_info(struct uwx_env *env)
+{
+    int i;
+    int status;
+    int cbstatus;
+    int cbcalled = 0;
+    uint64_t ip;
+    uint64_t *uvec;
+    uint64_t *rstate;
+    struct uwx_utable_entry uentry;
+    uint64_t uvecout[UVECSIZE];
+
+    if (env->copyin == 0 || env->lookupip == 0)
+	return UWX_ERR_NOCALLBACKS;
+
+    env->ptr_size = DWORDSZ;
+    env->code_start = 0;
+    env->function_offset = -1LL;
+    env->function_name = 0;
+    env->module_name = 0;
+    env->abi_context = 0;
+    uwx_reset_str_pool(env);
+
+    /* Use the lookup IP callback routine to find out about the */
+    /* current IP. If the predicate registers are valid, pass them */
+    /* in the uvec. */
+
+    /* When self-unwinding, we call a hook routine before the */
+    /* callback. If the application is running under control of */
+    /* a dynamic instrumentation tool, that tool will have an */
+    /* opportunity to intercept lookup IP requests. */
+
+    i = 0;
+    uvecout[i++] = UWX_KEY_VERSION;
+    uvecout[i++] = UWX_VERSION;
+    if (env->context.valid_regs & (1 << UWX_REG_PREDS)) {
+	uvecout[i++] = UWX_KEY_PREDS;
+	uvecout[i++] = env->context.special[UWX_REG_PREDS];
+    }
+    uvecout[i++] = UWX_KEY_END;
+    uvecout[i++] = 0;
+    uvec = uvecout;
+    cbstatus = UWX_LKUP_NOTFOUND;
+    ip = env->context.special[UWX_REG_IP];
+    env->remapped_ip = ip;
+
+    /* Call the hook routine. */
+
+    if (env->remote == 0)
+	cbstatus = uwx_lookupip_hook(UWX_LKUP_LOOKUP, ip, env->cb_token, &uvec,
+		sizeof(uvecout));
+
+    /* If the hook routine remapped the IP, use the new IP for */
+    /* the callback instead of the original IP. */
+
+    if (cbstatus == UWX_LKUP_REMAP) {
+	for (i = 0; uvec[i] != UWX_KEY_END; i += 2) {
+	    switch ((int)uvec[i]) {
+		case UWX_KEY_NEWIP:
+		    ip = uvec[i+1];
+		    break;
+	    }
+	}
+	env->remapped_ip = ip;
+    }
+
+    /* Now call the callback routine unless the hook routine gave */
+    /* us all the info. */
+
+    if (cbstatus == UWX_LKUP_NOTFOUND || cbstatus == UWX_LKUP_REMAP) {
+	cbcalled = 1;
+	cbstatus = (*env->lookupip)(UWX_LKUP_LOOKUP, ip, env->cb_token, &uvec);
+    }
+
+    /* If the callback routine remapped the IP, call it one more time */
+    /* with the new IP. */
+
+    if (cbstatus == UWX_LKUP_REMAP) {
+	for (i = 0; uvec[i] != UWX_KEY_END; i += 2) {
+	    switch ((int)uvec[i]) {
+		case UWX_KEY_NEWIP:
+		    ip = uvec[i+1];
+		    break;
+	    }
+	}
+	env->remapped_ip = ip;
+	cbstatus = (*env->lookupip)(UWX_LKUP_LOOKUP, ip, env->cb_token, &uvec);
+    }
+
+    /* If NOTFOUND, there's nothing we can do but return an error. */
+
+    if (cbstatus == UWX_LKUP_NOTFOUND) {
+	status = UWX_ERR_IPNOTFOUND;
+    }
+
+    /* If the callback returns an unwind table, we need to */
+    /* search the table for an unwind entry that describes the */
+    /* code region of interest, then decode the unwind information */
+    /* associated with that unwind table entry, and store the */
+    /* resulting register state array in the unwind environment */
+    /* block. */
+
+    else if (cbstatus == UWX_LKUP_UTABLE) {
+	status = uwx_search_utable(env, ip, uvec, &uentry);
+	if (cbcalled)
+	    (void) (*env->lookupip)(UWX_LKUP_FREE, 0, env->cb_token, &uvec);
+	if (status == UWX_OK) {
+	    env->ptr_size = uentry.ptr_size;
+	    env->code_start = uentry.code_start;
+	    status = uwx_decode_uinfo(env, &uentry, &rstate);
+	}
+	if (status == UWX_ERR_NOUENTRY || status == UWX_ERR_NOUDESC)
+	    status = uwx_default_rstate(env, &rstate);
+	if (status == UWX_OK)
+	    env->rstate = rstate;
+    }
+
+    /* If the callback returns an unwind info block, we can */
+    /* proceed directly to decoding the unwind information. */
+
+    else if (cbstatus == UWX_LKUP_UINFO) {
+	uentry.ptr_size = DWORDSZ;
+	uentry.code_start = 0;
+	uentry.code_end = 0;
+	uentry.unwind_info = 0;
+	uentry.unwind_flags = 0;
+	for (i = 0; uvec[i] != UWX_KEY_END; i += 2) {
+	    switch ((int)uvec[i]) {
+		case UWX_KEY_UFLAGS:
+		    uentry.unwind_flags = uvec[i+1];
+		    if (uentry.unwind_flags & UNWIND_TBL_32BIT)
+			uentry.ptr_size = WORDSZ;
+		    break;
+		case UWX_KEY_UINFO:
+		    uentry.unwind_info = uvec[i+1];
+		    break;
+		case UWX_KEY_GP:
+		    uwx_set_reg(env, UWX_REG_GP, uvec[i+1]);
+		    break;
+		case UWX_KEY_MODULE:
+		    env->module_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+		    break;
+		case UWX_KEY_FUNC:
+		    env->function_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+		    break;
+		case UWX_KEY_FUNCSTART:
+		    uentry.code_start = uvec[i+1];
+		    env->code_start = uentry.code_start;
+		    break;
+	    }
+	}
+	env->ptr_size = uentry.ptr_size;
+	if (cbcalled)
+	    (void) (*env->lookupip)(UWX_LKUP_FREE, 0, env->cb_token, &uvec);
+	status = uwx_decode_uinfo(env, &uentry, &rstate);
+	if (status == UWX_ERR_NOUDESC)
+	    status = uwx_default_rstate(env, &rstate);
+	if (status == UWX_OK)
+	    env->rstate = rstate;
+    }
+
+    /* If the callback returns a frame description (in the form */
+    /* of an update vector), convert the update vector into a */
+    /* register state array, then invoke the callback again to */
+    /* let it free any memory it allocated. */
+
+    else if (cbstatus == UWX_LKUP_FDESC) {
+	status = uwx_decode_uvec(env, uvec, &rstate);
+	if (cbcalled)
+	    (void) (*env->lookupip)(UWX_LKUP_FREE, 0, env->cb_token, &uvec);
+	if (status == UWX_OK)
+	    env->rstate = rstate;
+    }
+
+    /* Any other return from the callback is an error. */
+
+    else {
+	status = UWX_ERR_LOOKUPERR;
+    }
+    return status;
+}
+
+
+/* uwx_restore_markers: Restores the stack markers -- PSP, RP, PFS */
+
+int uwx_restore_markers(struct uwx_env *env)
+{
+    int status;
+    uint64_t val;
+    uint64_t hist;
+
+    if ((env->context.valid_regs & VALID_BASIC4) != VALID_BASIC4)
+	return UWX_ERR_NOCONTEXT;
+
+    /* If we haven't already obtained the frame info for the */
+    /* current frame, get it now. */
+
+    if (env->rstate == 0) {
+	status = uwx_get_frame_info(env);
+	if (status != UWX_OK)
+	    return status;
+    }
+
+    TRACE_S_STEP(env->rstate)
+
+    if (env->rstate[SBREG_PSP] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_PSP], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_PSP] = val;
+	env->history.special[UWX_REG_PSP] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_PSP;
+	TRACE_S_RESTORE_REG("PSP", env->rstate[SBREG_PSP], val)
+    }
+
+    if (env->rstate[SBREG_RP] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_RP], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_RP] = val;
+	env->history.special[UWX_REG_RP] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_RP;
+	TRACE_S_RESTORE_REG("RP", env->rstate[SBREG_RP], val)
+    }
+
+    if (env->rstate[SBREG_PFS] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_PFS], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_PFS] = val;
+	env->history.special[UWX_REG_PFS] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_PFS;
+	TRACE_S_RESTORE_REG("PFS", env->rstate[SBREG_PFS], val)
+    }
+
+    return UWX_OK;
+}
+
+/* uwx_get_module_info: Gets module name and text base for current frame */
+
+int uwx_get_module_info(
+    struct uwx_env *env,
+    char **modp,
+    uint64_t *text_base)
+{
+    int i;
+    int status;
+    int cbstatus;
+    uint64_t ip;
+    uint64_t *uvec;
+    uint64_t uvecout[UVECSIZE];
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    /* If we haven't already obtained the frame info for the */
+    /* current frame, get it now. */
+
+    if (env->rstate == 0) {
+	status = uwx_get_frame_info(env);
+	if (status != UWX_OK)
+	    return status;
+    }
+
+    /* Get the module name from the lookup IP callback. */
+    if (env->module_name == 0) {
+	ip = env->remapped_ip;
+	i = 0;
+	if (env->function_offset >= 0) {
+	    uvecout[i++] = UWX_KEY_FUNCSTART;
+	    uvecout[i++] = ip - env->function_offset;
+	}
+	uvecout[i++] = UWX_KEY_END;
+	uvecout[i++] = 0;
+	uvec = uvecout;
+	cbstatus = (*env->lookupip)(UWX_LKUP_MODULE, ip, env->cb_token, &uvec);
+
+	if (cbstatus == UWX_LKUP_SYMINFO) {
+	    for (i = 0; uvec[i] != UWX_KEY_END; i += 2) {
+		switch ((int)uvec[i]) {
+		    case UWX_KEY_TBASE:
+			env->text_base = uvec[i+1];
+			break;
+		    case UWX_KEY_MODULE:
+			env->module_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+			break;
+		    case UWX_KEY_FUNC:
+			env->function_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+			break;
+		    case UWX_KEY_FUNCSTART:
+			env->function_offset = ip - uvec[i+1];
+			break;
+		}
+	    }
+	    (void) (*env->lookupip)(UWX_LKUP_FREE, 0, env->cb_token, &uvec);
+	}
+    }
+
+    *modp = env->module_name;
+    *text_base = env->text_base;
+
+    return UWX_OK;
+}
+
+/* uwx_get_funcstart: Gets start address of function from current frame */
+
+int uwx_get_funcstart(
+    struct uwx_env *env,
+    uint64_t *funcstart)
+{
+    int status;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    /* If we haven't already obtained the frame info for the */
+    /* current frame, get it now. */
+
+    if (env->rstate == 0) {
+	status = uwx_get_frame_info(env);
+	if (status != UWX_OK)
+	    return status;
+    }
+
+    *funcstart = env->remapped_ip - env->function_offset;
+
+    return UWX_OK;
+}
+
+/* uwx_get_sym_info: Gets symbolic info from current frame */
+/* (Will make a UWX_LKUP_SYMBOLS callback if info */
+/* was not provided by UWX_LKUP_LOOKUP callback) */
+
+int uwx_get_sym_info(
+    struct uwx_env *env,
+    char **modp,
+    char **symp,
+    uint64_t *offsetp)
+{
+    int status;
+    int cbstatus;
+    uint64_t ip;
+    uint64_t *uvec;
+    uint64_t uvecout[UVECSIZE];
+    int i;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    /* If we haven't already obtained the frame info for the */
+    /* current frame, get it now. */
+
+    if (env->rstate == 0) {
+	status = uwx_get_frame_info(env);
+	if (status != UWX_OK)
+	    return status;
+    }
+
+    /* Get the symbolic information from the lookup IP callback. */
+    if (env->function_name == 0) {
+	ip = env->remapped_ip;
+	i = 0;
+	if (env->function_offset >= 0) {
+	    uvecout[i++] = UWX_KEY_FUNCSTART;
+	    uvecout[i++] = ip - env->function_offset;
+	}
+	uvecout[i++] = UWX_KEY_END;
+	uvecout[i++] = 0;
+	uvec = uvecout;
+	cbstatus = (*env->lookupip)(UWX_LKUP_SYMBOLS, ip, env->cb_token, &uvec);
+
+	if (cbstatus == UWX_LKUP_SYMINFO) {
+	    for (i = 0; uvec[i] != UWX_KEY_END; i += 2) {
+		switch ((int)uvec[i]) {
+		    case UWX_KEY_MODULE:
+			env->module_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+			break;
+		    case UWX_KEY_FUNC:
+			env->function_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+			break;
+		    case UWX_KEY_FUNCSTART:
+			env->function_offset = ip - uvec[i+1];
+			break;
+		}
+	    }
+	    (void) (*env->lookupip)(UWX_LKUP_FREE, 0, env->cb_token, &uvec);
+	}
+    }
+
+    *modp = env->module_name;
+    *symp = env->function_name;
+    *offsetp = env->function_offset;
+
+    return UWX_OK;
+}
+
+
+/* uwx_step: Steps from the current frame to the previous frame */
+
+int uwx_step(struct uwx_env *env)
+{
+    int i;
+    int status;
+    int pfs_sol;
+    int dispcode;
+    uint64_t val;
+    uint64_t fval[2];
+    uint64_t hist;
+    uint64_t tempgr[NPRESERVEDGR];
+    int needpriunat;
+    int unat;
+    int tempnat;
+
+    if (env == 0)
+	return UWX_ERR_NOENV;
+
+    /* Complete the current context by restoring the current values */
+    /* of psp, rp, and pfs. */
+
+    if (env->rstate == 0 ||
+	    (env->context.valid_regs & VALID_MARKERS) != VALID_MARKERS) {
+	status = uwx_restore_markers(env);
+	if (status != UWX_OK)
+	    return status;
+    }
+
+    /* Check for bottom of stack (rp == 0). */
+
+    if (env->context.special[UWX_REG_RP] == 0)
+	return UWX_BOTTOM;
+
+    /* Find where the primary unat is saved, get a copy. */
+    /* Then, as we restore the GRs, we'll merge the NaT bits into the */
+    /* priunat register in the context. */
+    /* (Make sure we need it, though, before we try to get it, */
+    /* because the attempt to get it might invoke the copy-in callback. */
+    /* We don't need the priunat unless one of GR 4-7 was */
+    /* saved to the memory stack.) */
+
+    needpriunat = 0;
+    for (i = 0; i < NSB_GR; i++) {
+	dispcode = UWX_GET_DISP_CODE(env->rstate[SBREG_GR + i]);
+	if (dispcode == UWX_DISP_SPREL(0) || dispcode == UWX_DISP_PSPREL(0))
+	    needpriunat = 1;
+    }
+    unat = 0;
+    if (needpriunat && env->rstate[SBREG_PRIUNAT] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_PRIUNAT], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	unat = (int) val;
+	env->history.special[UWX_REG_PRIUNAT] = hist;
+	TRACE_S_RESTORE_REG("PRIUNAT", env->rstate[SBREG_PRIUNAT], val)
+    }
+
+    /* Retrieve saved values of the preserved GRs into temporaries. */
+
+    tempnat = (int) env->context.special[UWX_REG_PRIUNAT];
+    for (i = 0; i < NSB_GR; i++) {
+	if (env->rstate[SBREG_GR + i] != UWX_DISP_NONE) {
+	    status = uwx_restore_reg(env,
+			env->rstate[SBREG_GR + i], &val, &hist);
+	    if (status != UWX_OK)
+		return status;
+	    tempgr[i] = val;
+	    if (uwx_restore_nat(env, env->rstate[SBREG_GR + i], unat))
+		tempnat |= 1 << i;
+	    else
+		tempnat &= ~(1 << i);
+	    env->history.gr[i] = hist;
+	    env->context.valid_regs |= 1 << (i + VALID_GR_SHIFT);
+	    TRACE_S_RESTORE_GR(i, env->rstate[SBREG_GR + i], val)
+	}
+    }
+
+    /* Now we have everything we need to step back to the previous frame. */
+
+    /* Restore preserved BRs. */
+
+    for (i = 0; i < NSB_BR; i++) {
+	if (env->rstate[SBREG_BR + i] != UWX_DISP_NONE) {
+	    status = uwx_restore_reg(env,
+			env->rstate[SBREG_BR + i], &val, &hist);
+	    if (status != UWX_OK)
+		return status;
+	    env->context.br[i] = val;
+	    env->history.br[i] = hist;
+	    env->context.valid_regs |= 1 << (i + VALID_BR_SHIFT);
+	    TRACE_S_RESTORE_BR(i, env->rstate[SBREG_BR + i], val)
+	}
+    }
+
+    /* Restore preserved FRs. */
+
+    if (env->nsbreg == NSBREG) {
+	for (i = 0; i < NSB_FR; i++) {
+	    if (env->rstate[SBREG_FR + i] != UWX_DISP_NONE) {
+		status = uwx_restore_freg(env,
+			    env->rstate[SBREG_FR + i], fval, &hist);
+		if (status != UWX_OK)
+		    return status;
+		env->context.fr[i].part0 = fval[0];
+		env->context.fr[i].part1 = fval[1];
+		env->history.fr[i] = hist;
+		env->context.valid_frs |= 1 << i;
+		TRACE_S_RESTORE_FR(i, env->rstate[SBREG_FR + i], fval)
+	    }
+	}
+    }
+
+    /* Restore other preserved regs. */
+
+    if (env->rstate[SBREG_PREDS] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_PREDS], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_PREDS] = val;
+	env->history.special[UWX_REG_PREDS] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_PREDS;
+	TRACE_S_RESTORE_REG("PREDS", env->rstate[SBREG_PREDS], val)
+    }
+    if (env->rstate[SBREG_RNAT] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_RNAT], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_AR_RNAT] = val;
+	env->history.special[UWX_REG_AR_RNAT] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_AR_RNAT;
+	TRACE_S_RESTORE_REG("RNAT", env->rstate[SBREG_RNAT], val)
+    }
+    if (env->rstate[SBREG_UNAT] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_UNAT], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_AR_UNAT] = val;
+	env->history.special[UWX_REG_AR_UNAT] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_AR_UNAT;
+	TRACE_S_RESTORE_REG("UNAT", env->rstate[SBREG_UNAT], val)
+    }
+    if (env->rstate[SBREG_FPSR] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_FPSR], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_AR_FPSR] = val;
+	env->history.special[UWX_REG_AR_FPSR] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_AR_FPSR;
+	TRACE_S_RESTORE_REG("FPSR", env->rstate[SBREG_FPSR], val)
+    }
+    if (env->rstate[SBREG_LC] != UWX_DISP_NONE) {
+	status = uwx_restore_reg(env, env->rstate[SBREG_LC], &val, &hist);
+	if (status != UWX_OK)
+	    return status;
+	env->context.special[UWX_REG_AR_LC] = val;
+	env->history.special[UWX_REG_AR_LC] = hist;
+	env->context.valid_regs |= 1 << UWX_REG_AR_LC;
+	TRACE_S_RESTORE_REG("LC", env->rstate[SBREG_LC], val)
+    }
+
+    /* Restore preserved GRs from temporaries. */
+
+    for (i = 0; i < NSB_GR; i++) {
+	if (env->rstate[SBREG_GR + i] != UWX_DISP_NONE)
+	    env->context.gr[i] = tempgr[i];
+    }
+    env->context.special[UWX_REG_PRIUNAT] = tempnat;
+
+    /* Restore the frame markers. */
+
+    env->context.special[UWX_REG_IP] = env->context.special[UWX_REG_RP];
+    env->history.special[UWX_REG_IP] = env->history.special[UWX_REG_RP];
+
+    env->context.special[UWX_REG_SP] = env->context.special[UWX_REG_PSP];
+    env->history.special[UWX_REG_SP] = env->history.special[UWX_REG_PSP];
+
+    pfs_sol = ((unsigned int)env->context.special[UWX_REG_PFS] >> 7) & 0x7f;
+    env->context.special[UWX_REG_BSP] = uwx_add_to_bsp(
+				env->context.special[UWX_REG_BSP],
+				-pfs_sol);
+
+    env->context.special[UWX_REG_CFM] = env->context.special[UWX_REG_PFS];
+    env->history.special[UWX_REG_CFM] = env->history.special[UWX_REG_PFS];
+
+    env->context.special[UWX_REG_RP] = 0;
+
+    /* The frame info for the new frame isn't yet available. */
+
+    env->rstate = 0;
+    env->context.valid_regs &= ~VALID_MARKERS;
+
+    return UWX_OK;
+}
+
+
+/* uwx_decode_uvec: Converts the update vector into a register state array */
+
+int uwx_decode_uvec(struct uwx_env *env, uint64_t *uvec, uint64_t **rstate)
+{
+    int i;
+    int status;
+
+    status = uwx_default_rstate(env, rstate);
+    if (status != UWX_OK)
+	return status;
+
+    for (i = 0; uvec[i] != UWX_KEY_END; i += 2) {
+	switch ((int)uvec[i]) {
+	    case UWX_KEY_CONTEXT:
+		env->abi_context = (int)(uvec[i+1]);
+		status = UWX_ABI_FRAME;
+		break;
+	    case UWX_KEY_GP:
+		uwx_set_reg(env, UWX_REG_GP, uvec[i+1]);
+		break;
+	    case UWX_KEY_MODULE:
+		env->module_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+		break;
+	    case UWX_KEY_FUNC:
+		env->function_name =
+			    uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
+		break;
+	    case UWX_KEY_FUNCSTART:
+		env->function_offset = env->remapped_ip - uvec[i+1];
+		break;
+	    default:
+		return UWX_ERR_CANTUNWIND;
+	}
+    }
+    return status;
+}
+
+
+/* uwx_restore_reg: Restores a register according to the scoreboard */
+
+#define COPYIN_MSTACK_8(dest, src) \
+    (env->remote? \
+	(*env->copyin)(UWX_COPYIN_MSTACK, (dest), (src), \
+						DWORDSZ, env->cb_token) : \
+	(*(uint64_t *)(intptr_t)(dest) = \
+				*(uint64_t *)(intptr_t)(src), DWORDSZ) )
+
+int uwx_restore_reg(struct uwx_env *env, uint64_t rstate,
+				uint64_t *valp, uint64_t *histp)
+{
+    int status;
+    uint64_t p;
+    int n;
+    int regid;
+
+    status = UWX_OK;
+
+    switch (UWX_GET_DISP_CODE(rstate)) {
+	case UWX_DISP_SPPLUS(0):
+	    *valp = env->context.special[UWX_REG_SP] +
+				UWX_GET_DISP_OFFSET(rstate);
+	    *histp = UWX_DISP_NONE;
+	    break;
+	case UWX_DISP_SPREL(0):
+	    p = env->context.special[UWX_REG_SP] +
+				UWX_GET_DISP_OFFSET(rstate);
+	    n = COPYIN_MSTACK_8((char *)valp, p);
+	    if (n != DWORDSZ)
+		status = UWX_ERR_COPYIN_MSTK;
+	    *histp = UWX_DISP_MSTK(p);
+	    break;
+	case UWX_DISP_PSPREL(0):
+	    p = env->context.special[UWX_REG_PSP] + 16 -
+				UWX_GET_DISP_OFFSET(rstate);
+	    n = COPYIN_MSTACK_8((char *)valp, p);
+	    if (n != DWORDSZ)
+		status = UWX_ERR_COPYIN_MSTK;
+	    *histp = UWX_DISP_MSTK(p);
+	    break;
+	case UWX_DISP_REG(0):
+	    regid = UWX_GET_DISP_REGID(rstate);
+	    status = uwx_get_reg(env, regid, valp);
+	    (void) uwx_get_spill_loc(env, regid, histp);
+	    break;
+    }
+    return status;
+}
+
+#define COPYIN_MSTACK_16(dest, src) \
+    (env->remote? \
+	(*env->copyin)(UWX_COPYIN_MSTACK, (dest), (src), \
+						2*DWORDSZ, env->cb_token) : \
+	(*(uint64_t *)(intptr_t)(dest) = *(uint64_t *)(intptr_t)(src), \
+	    *(uint64_t *)(intptr_t)((dest)+8) = \
+					*(uint64_t *)(intptr_t)((src)+8), \
+	    2*DWORDSZ) )
+
+int uwx_restore_freg(struct uwx_env *env, uint64_t rstate,
+				uint64_t *valp, uint64_t *histp)
+{
+    int status;
+    uint64_t p;
+    int n;
+    int regid;
+
+    status = UWX_OK;
+
+    switch (UWX_GET_DISP_CODE(rstate)) {
+	case UWX_DISP_SPREL(0):
+	    p = env->context.special[UWX_REG_SP] +
+				UWX_GET_DISP_OFFSET(rstate);
+	    n = COPYIN_MSTACK_16((char *)valp, p);
+	    if (n != 2*DWORDSZ)
+		status = UWX_ERR_COPYIN_MSTK;
+	    *histp = UWX_DISP_MSTK(p);
+	    break;
+	case UWX_DISP_PSPREL(0):
+	    p = env->context.special[UWX_REG_PSP] + 16 -
+				UWX_GET_DISP_OFFSET(rstate);
+	    n = COPYIN_MSTACK_16((char *)valp, p);
+	    if (n != 2*DWORDSZ)
+		status = UWX_ERR_COPYIN_MSTK;
+	    *histp = UWX_DISP_MSTK(p);
+	    break;
+	case UWX_DISP_REG(0):
+	    regid = UWX_GET_DISP_REGID(rstate);
+	    status = uwx_get_reg(env, regid, valp);
+	    (void) uwx_get_spill_loc(env, regid, histp);
+	    break;
+    }
+    return status;
+}
+
+/* uwx_restore_nat: Returns the saved NaT bit for a preserved GR */
+
+int uwx_restore_nat(struct uwx_env *env, uint64_t rstate, int unat)
+{
+    int nat;
+    uint64_t p;
+
+    nat = 0;
+    switch (UWX_GET_DISP_CODE(rstate)) {
+	case UWX_DISP_SPREL(0):
+	    p = env->context.special[UWX_REG_SP] +
+				UWX_GET_DISP_OFFSET(rstate);
+	    nat = (unat >> (((int)p >> 3) & 0x3f)) & 0x01;
+	    break;
+	case UWX_DISP_PSPREL(0):
+	    p = env->context.special[UWX_REG_PSP] + 16 -
+				UWX_GET_DISP_OFFSET(rstate);
+	    nat = (unat >> (((int)p >> 3) & 0x3f)) & 0x01;
+	    break;
+	case UWX_DISP_REG(0):
+	    (void) uwx_get_nat(env, UWX_GET_DISP_REGID(rstate), &nat);
+	    break;
+    }
+    return nat;
+}
+


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_step.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_step.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_step.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_step.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,31 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define UVECSIZE 20	/* Size of uvec supplied by unwind engine */
+			/* for callback's use. */
+
+extern int uwx_lookupip_hook(int request, uint64_t ip, intptr_t tok,
+    uint64_t **vecp, size_t uvecsize);
+extern int uwx_restore_markers(struct uwx_env *env);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_step.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_str.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_str.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_str.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,129 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef _KERNEL
+#include <string.h>
+#endif
+
+#include "uwx_env.h"
+#include "uwx_str.h"
+
+#ifdef _KERNEL
+static struct uwx_str_pool	uwx_str_pool;
+#define	free(p)		/* nullified */
+#define	malloc(sz)	((sz == sizeof(uwx_str_pool)) ? &uwx_str_pool : NULL)
+#endif
+
+/*
+ *  uwx_str.c
+ *
+ *  This file contains the routines for maintaining a string
+ *  pool for the unwind environment. We preallocate enough
+ *  space for most purposes so that no memory allocation is
+ *  necessary during a normal unwind. If we do need more,
+ *  we use the allocate callback, if one is provided.
+ *
+ *  The string pool is reused with each call to step(),
+ *  and is completely freed when the unwind environment is
+ *  freed.
+ */
+
+
+int uwx_init_str_pool(struct uwx_env *env, struct uwx_str_pool *pool)
+{
+    if (pool == 0)
+	return UWX_ERR_NOMEM;
+
+    pool->next = 0;
+    pool->size = STRPOOLSIZE;
+    pool->used = 0;
+
+    env->string_pool = pool;
+
+    return UWX_OK;
+}
+
+void uwx_free_str_pool(struct uwx_env *env)
+{
+    struct uwx_str_pool *pool;
+    struct uwx_str_pool *next;
+
+    /* The first pool is preallocated as part of the uwx_env. Don't free it! */
+    pool = env->string_pool;
+    if (pool != 0)
+	pool = pool->next;
+    for (; pool != 0; pool = next) {
+	next = pool->next;
+	if (env->free_cb == 0)
+	    free(pool);
+	else
+	    (*env->free_cb)(pool);
+    }
+}
+
+char *uwx_alloc_str(struct uwx_env *env, char *str)
+{
+    int len;
+    int size;
+    struct uwx_str_pool *pool;
+    struct uwx_str_pool *prev;
+    char *p;
+
+    len = strlen(str) + 1;
+    prev = 0;
+    for (pool = env->string_pool; pool != 0; pool = pool->next) {
+	prev = pool;
+	if (pool->size - pool->used >= len)
+	    break;
+    }
+    if (pool == 0) {
+	size = STRPOOLSIZE;
+	if (len > size)
+	    size = len;
+	size += sizeof(struct uwx_str_pool) - STRPOOLSIZE;
+	if (env->allocate_cb == 0)
+	    pool = (struct uwx_str_pool *) malloc(size);
+	else
+	    pool = (struct uwx_str_pool *) (*env->allocate_cb)(size);
+	if (env->string_pool == 0)
+	    return 0;
+	pool->next = 0;
+	pool->size = size;
+	pool->used = 0;
+	prev->next = pool;
+    }
+    p = pool->pool + pool->used;
+    strcpy(p, str);
+    pool->used += len;
+    return p;
+}
+
+void uwx_reset_str_pool(struct uwx_env *env)
+{
+    struct uwx_str_pool *pool;
+
+    for (pool = env->string_pool; pool != 0; pool = pool->next)
+	pool->used = 0;
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_str.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_str.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_str.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_str.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,38 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define STRPOOLSIZE (400-sizeof(void *)-2*sizeof(int))
+
+struct uwx_str_pool {
+    struct uwx_str_pool *next;
+    int size;
+    int used;
+    char pool[STRPOOLSIZE];
+};
+
+extern int uwx_init_str_pool(struct uwx_env *env, struct uwx_str_pool *pool);
+extern void uwx_free_str_pool(struct uwx_env *env);
+extern char *uwx_alloc_str(struct uwx_env *env, char *str);
+extern void uwx_reset_str_pool(struct uwx_env *env);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_str.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_swap.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_swap.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_swap.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,71 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx_env.h"
+#include "uwx_swap.h"
+
+void uwx_swap4(uint32_t *w)
+{
+    unsigned char *p;
+    unsigned char t[4];
+
+    p = (unsigned char *) w;
+
+    t[0] = p[0];
+    t[1] = p[1];
+    t[2] = p[2];
+    t[3] = p[3];
+
+    p[0] = t[3];
+    p[1] = t[2];
+    p[2] = t[1];
+    p[3] = t[0];
+}
+
+void uwx_swap8(uint64_t *dw)
+{
+    unsigned char *p;
+    unsigned char t[8];
+
+    p = (unsigned char *) dw;
+
+    t[0] = p[0];
+    t[1] = p[1];
+    t[2] = p[2];
+    t[3] = p[3];
+    t[4] = p[4];
+    t[5] = p[5];
+    t[6] = p[6];
+    t[7] = p[7];
+
+    p[0] = t[7];
+    p[1] = t[6];
+    p[2] = t[5];
+    p[3] = t[4];
+    p[4] = t[3];
+    p[5] = t[2];
+    p[6] = t[1];
+    p[7] = t[0];
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_swap.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_swap.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_swap.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_swap.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,27 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+extern void uwx_swap4(uint32_t *w);
+extern void uwx_swap8(uint64_t *dw);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_swap.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,851 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef USE_CLEAN_NAMESPACE
+#define fopen _fopen
+#define fseek _fseek
+#define fread _fread
+#define fclose _fclose
+#endif /* USE_CLEAN_NAMESPACE */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <elf.h>
+
+#include "uwx.h"
+#include "uwx_env.h"
+
+#ifdef USE_CLEAN_NAMESPACE
+/*
+ * Moved the defines above the include of stdio.h,
+ * so we don't need these unless that causes problems
+ * and we have to move them back down here.
+ * #define fopen _fopen
+ * #define fseek _fseek
+ * #define fread _fread
+ * #define fclose _fclose
+ * extern FILE *_fopen(const char *, const char *);
+ * extern int _fseek(FILE *, long int, int);
+ * extern size_t _fread(void *, size_t, size_t, FILE *);
+ * extern int _fclose(FILE *);
+ */
+#endif /* USE_CLEAN_NAMESPACE */
+
+struct uwx_symbol_cache {
+    char *module_name;
+    int nsyms;
+    uint64_t *sym_values;
+    char **sym_names;
+    char *strings;
+};
+
+
+int uwx_read_func_symbols(
+    struct uwx_env *env,
+    struct uwx_symbol_cache *cache,
+    char *module_name);
+
+
+int uwx_find_symbol(
+    struct uwx_env *env,
+    struct uwx_symbol_cache **symbol_cache_p,
+    char *module_name,
+    uint64_t relip,
+    char **func_name_p,
+    uint64_t *offset_p)
+{
+    int status;
+    int i;
+    uint64_t offset;
+    uint64_t best_offset;
+    char *best_name;
+    struct symbol *sym;
+    struct uwx_symbol_cache *cache = NULL;
+
+    /* Allocate a symbol cache on first call */
+    if (symbol_cache_p != NULL)
+	cache = *symbol_cache_p;
+    if (cache == NULL) {
+	cache = (struct uwx_symbol_cache *)
+			(*env->allocate_cb)(sizeof(struct uwx_symbol_cache));
+	if (cache == NULL)
+	    return UWX_ERR_NOMEM;
+	cache->module_name = NULL;
+	cache->nsyms = 0;
+	cache->sym_values = NULL;
+	cache->sym_names = NULL;
+	cache->strings = NULL;
+	if (symbol_cache_p != NULL)
+	    *symbol_cache_p = cache;
+    }
+
+    /* Read function symbols from the object file */
+    status = uwx_read_func_symbols(env, cache, module_name);
+    if (status != UWX_OK)
+	return status;
+
+    /* Search for best match */
+    best_offset = ~(uint64_t)0;
+    best_name = NULL;
+    for (i = 0; i < cache->nsyms; i++) {
+	if (cache->sym_values[i] == relip) {
+	    *func_name_p = cache->sym_names[i];
+	    *offset_p = 0;
+	    if (symbol_cache_p == NULL)
+		uwx_release_symbol_cache(env, cache);
+	    return UWX_OK;
+	}
+	if (relip > cache->sym_values[i]) {
+	    offset = relip - cache->sym_values[i];
+	    if (offset < best_offset) {
+		best_offset = offset;
+		best_name = cache->sym_names[i];
+	    }
+	}
+    }
+    if (best_name == NULL)
+	return UWX_ERR_NOSYM;
+
+    if (symbol_cache_p == NULL)
+	uwx_release_symbol_cache(env, cache);
+
+    *func_name_p = best_name;
+    *offset_p = best_offset;
+    return UWX_OK;
+}
+
+
+void uwx_release_symbol_cache(
+    struct uwx_env *env,
+    struct uwx_symbol_cache *symbol_cache)
+{
+    if (symbol_cache->module_name != NULL)
+	(*env->free_cb)(symbol_cache->module_name);
+    if (symbol_cache->sym_values != NULL)
+	(*env->free_cb)(symbol_cache->sym_values);
+    if (symbol_cache->sym_names != NULL)
+	(*env->free_cb)(symbol_cache->sym_names);
+    if (symbol_cache->strings != NULL)
+	(*env->free_cb)(symbol_cache->strings);
+    (*env->free_cb)(symbol_cache);
+}
+
+
+#define ELF_ERR_NOMEM		UWX_ERR_NOMEM  /* Out of memory */
+#define ELF_ERR_OPEN		UWX_ERR_NOSYM  /* Can't open file */
+
+#define ELF_ERR_NOHEADER	UWX_ERR_NOSYM  /* Can't read ELF header */
+#define ELF_ERR_NOTELF		UWX_ERR_NOSYM  /* Not an ELF file */
+#define ELF_ERR_HEADER_SIZE	UWX_ERR_NOSYM  /* Invalid e_ehsize */
+#define ELF_ERR_INVALID_CLASS	UWX_ERR_NOSYM  /* Invalid EI_CLASS */
+#define ELF_ERR_INVALID_DATA	UWX_ERR_NOSYM  /* Invalid EI_DATA */
+
+#define ELF_ERR_READ_SECTHDR	UWX_ERR_NOSYM  /* Can't read section headers */
+#define ELF_ERR_SECTHDR_SIZE	UWX_ERR_NOSYM  /* Invalid e_shentsize */
+
+#define ELF_ERR_READ_PROGHDR	UWX_ERR_NOSYM  /* Can't read program headers */
+#define ELF_ERR_PROGHDR_SIZE	UWX_ERR_NOSYM  /* Invalid e_phentsize */
+
+#define ELF_ERR_READ_SECTION	UWX_ERR_NOSYM  /* Can't read section contents */
+
+#define ELF_ERR_READ_SYMTAB	UWX_ERR_NOSYM  /* Can't read symbol table */
+#define ELF_ERR_SYMTAB_SIZE	UWX_ERR_NOSYM  /* Invalid sh_entsize for symtab */
+
+
+struct elf_file {
+    uint64_t phoff;
+    uint64_t shoff;
+    uint64_t text_base;
+    uint64_t text_end;
+    alloc_cb allocate_cb;
+    free_cb free_cb;
+    const char *filename;
+    FILE *fd;
+    struct elf_section *sections;
+    struct elf_symbol *symbols;
+    char *symbol_strings;
+    int native_data;
+    int source_class;
+    int source_data;
+    int ehsize;
+    int phentsize;
+    int phnum;
+    int shentsize;
+    int shnum;
+    int nsyms;
+};
+
+struct elf_section {
+    uint64_t flags;
+    uint64_t addr;
+    uint64_t offset;
+    uint64_t size;
+    uint64_t entsize;
+    char *contents;
+    struct elf_symbol *symbols;
+    int type;
+    int link;
+    int info;
+    int nelems;
+};
+
+struct elf_symbol {
+    uint64_t value;
+    char *namep;
+    int name;
+    int type;
+    int shndx;
+};
+
+
+static void elf_swap_bytes(char *buf, char *template)
+{
+    int i;
+    int sz;
+    char temp[16];
+
+    while (sz = *template++) {
+	if (sz > 16)
+	    exit(1);
+	for (i = 0; i < sz; i++)
+	    temp[i] = buf[i];
+	for (i = 0; i < sz; i++)
+	    buf[i] = temp[sz-i-1];
+	buf += sz;
+    }
+}
+
+
+static int elf_read_section(struct elf_file *ef, int shndx)
+{
+    struct elf_section *sect;
+
+    if (shndx < 0 || shndx > ef->shnum)
+	return 0;
+
+    sect = &ef->sections[shndx];
+
+    /* Return if section has already been read */
+    if (sect->contents != NULL)
+	return 0;
+
+    sect->contents = (*ef->allocate_cb)(sect->size);
+    if (sect->contents == NULL)
+	return ELF_ERR_NOMEM;
+
+    fseek(ef->fd, (long)sect->offset, SEEK_SET);
+    if (fread(sect->contents, 1, sect->size, ef->fd) != sect->size)
+	return ELF_ERR_READ_SECTION;
+
+    return 0;
+}
+
+
+static char template_elf32_sym[] = {4, 4, 4, 1, 1, 2, 0};
+static char template_elf64_sym[] = {4, 1, 1, 2, 8, 8, 0};
+
+static int elf_read_symtab_section(struct elf_file *ef, int shndx)
+{
+    int i;
+    int nsyms;
+    long size;
+    union {
+	Elf32_Sym sym32;
+	Elf64_Sym sym64;
+    } sym;
+    struct elf_section *sect;
+    struct elf_symbol *syms;
+    struct elf_symbol *symp;
+    char *strtab;
+
+    sect = &ef->sections[shndx];
+
+    /* Return if section has already been read */
+    if (sect->symbols != NULL)
+	return 0;
+
+    if (ef->source_class == ELFCLASS32) {
+	if (sect->entsize != sizeof(sym.sym32))
+	    return ELF_ERR_SYMTAB_SIZE;
+    }
+    else {
+	if (sect->entsize != sizeof(sym.sym64))
+	    return ELF_ERR_SYMTAB_SIZE;
+    }
+
+    nsyms = sect->nelems;
+    syms = (struct elf_symbol *)
+			(*ef->allocate_cb)(sizeof(struct elf_symbol) * nsyms);
+    if (syms == NULL)
+	return ELF_ERR_NOMEM;
+
+    /* Read the symbol table */
+    fseek(ef->fd, (long)sect->offset, SEEK_SET);
+    for (i = 0; i < nsyms; i++) {
+
+	symp = &syms[i];
+
+	/* Read the next symbol table entry */
+	if (fread((char *)&sym, sect->entsize, 1, ef->fd) != 1) {
+	    (*ef->free_cb)(syms);
+	    return ELF_ERR_READ_SYMTAB;
+	}
+
+	/* Get fields from appropriate structure */
+	if (ef->source_class == ELFCLASS32) {
+	    /* Swap bytes if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&sym, template_elf32_sym);
+	    symp->name = sym.sym32.st_name;
+	    symp->type = sym.sym32.st_info & 0x0f;
+	    symp->shndx = sym.sym32.st_shndx;
+	    symp->value = sym.sym32.st_value;
+	}
+	else {
+	    /* Swap bytes if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&sym, template_elf64_sym);
+	    symp->name = sym.sym64.st_name;
+	    symp->type = sym.sym64.st_info & 0x0f;
+	    symp->shndx = sym.sym64.st_shndx;
+	    symp->value = sym.sym64.st_value;
+	}
+	symp->namep = NULL;
+
+    }
+
+    /* Read the symbol string table and convert section names */
+    /* from string table offsets to pointers */
+    if (sect->link > 0 && sect->link < ef->shnum) {
+	if (elf_read_section(ef, sect->link) == 0) {
+	    strtab = ef->sections[sect->link].contents;
+	    for (i = 0; i < nsyms; i++) {
+		symp = &syms[i];
+		symp->namep = strtab + symp->name;
+	    }
+	    ef->symbol_strings = strtab;
+	    ef->sections[sect->link].contents = NULL;
+	}
+    }
+
+    sect->symbols = syms;
+    return 0;
+}
+
+
+static char template_elf32_phdr[] = {4, 4, 4, 4, 4, 4, 4, 4, 0};
+static char template_elf64_phdr[] = {4, 4, 8, 8, 8, 8, 8, 8, 0};
+
+static int elf_read_prog_hdrs(struct elf_file *ef)
+{
+    int i;
+    union {
+	Elf32_Phdr hdr32;
+	Elf64_Phdr hdr64;
+    } header;
+    uint64_t vaddr;
+    uint64_t memsz;
+    uint64_t unwind_base;
+    int type;
+
+    if (ef->phnum == 0)
+	return 0;
+
+    if (ef->source_class == ELFCLASS32) {
+	if (ef->phentsize != sizeof(header.hdr32))
+	    return ELF_ERR_PROGHDR_SIZE;
+    }
+    else {
+	if (ef->phentsize != sizeof(header.hdr64))
+	    return ELF_ERR_PROGHDR_SIZE;
+    }
+
+    /* Look for the PT_IA_64_UNWIND segment */
+    /* (That will help us identify the text segment) */
+
+    fseek(ef->fd, (long)ef->phoff, SEEK_SET);
+    for (i = 0; i < ef->phnum; i++) {
+
+	/* Read the next program header */
+	if (fread((char *)&header, ef->phentsize, 1, ef->fd) != 1)
+	    return ELF_ERR_READ_PROGHDR;
+
+	/* Get fields from appropriate structure */
+	if (ef->source_class == ELFCLASS32) {
+	    /* Swap bytes in header fields if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&header, template_elf32_phdr);
+	    type = header.hdr32.p_type;
+	    vaddr = header.hdr32.p_vaddr;
+	}
+	else {
+	    /* Swap bytes in header fields if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&header, template_elf64_phdr);
+	    type = header.hdr64.p_type;
+	    vaddr = header.hdr64.p_vaddr;
+	}
+
+	if (type == PT_IA_64_UNWIND) {
+	    unwind_base = vaddr;
+	    break;
+	}
+
+    }
+
+    /* Now look for the PT_LOAD segment that includes the unwind segment */
+
+    fseek(ef->fd, (long)ef->phoff, SEEK_SET);
+    for (i = 0; i < ef->phnum; i++) {
+
+	/* Read the next program header */
+	if (fread((char *)&header, ef->phentsize, 1, ef->fd) != 1)
+	    return ELF_ERR_READ_PROGHDR;
+
+	/* Get fields from appropriate structure */
+	if (ef->source_class == ELFCLASS32) {
+	    /* Swap bytes in header fields if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&header, template_elf32_phdr);
+	    type = header.hdr32.p_type;
+	    vaddr = header.hdr32.p_vaddr;
+	    memsz = header.hdr32.p_memsz;
+	}
+	else {
+	    /* Swap bytes in header fields if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&header, template_elf64_phdr);
+	    type = header.hdr64.p_type;
+	    vaddr = header.hdr64.p_vaddr;
+	    memsz = header.hdr64.p_memsz;
+	}
+
+	if (type == PT_LOAD &&
+		vaddr <= unwind_base && unwind_base < vaddr + memsz) {
+	    ef->text_base = vaddr;
+	    ef->text_end = vaddr + memsz;
+	    break;
+	}
+
+    }
+
+    return 0;
+}
+
+
+static char template_elf32_shdr[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0};
+static char template_elf64_shdr[] = {4, 4, 8, 8, 8, 8, 4, 4, 8, 8, 0};
+
+static int elf_read_sect_hdrs(struct elf_file *ef)
+{
+    int i;
+    long size;
+    int err;
+    union {
+	Elf32_Shdr hdr32;
+	Elf64_Shdr hdr64;
+    } header;
+    struct elf_section *sect;
+    char *shstrtab;
+
+    if (ef->source_class == ELFCLASS32) {
+	if (ef->shentsize != sizeof(header.hdr32))
+	    return ELF_ERR_SECTHDR_SIZE;
+    }
+    else {
+	if (ef->shentsize != sizeof(header.hdr64))
+	    return ELF_ERR_SECTHDR_SIZE;
+    }
+
+    fseek(ef->fd, (long)ef->shoff, SEEK_SET);
+    ef->sections = (struct elf_section *)
+		    (*ef->allocate_cb)(sizeof(struct elf_section) * ef->shnum);
+    if (ef->sections == NULL)
+	return ELF_ERR_NOMEM;
+
+    /* Read the section header table */
+    for (i = 0; i < ef->shnum; i++) {
+
+	sect = &ef->sections[i];
+
+	/* Read the next section header */
+	if (fread((char *)&header, ef->shentsize, 1, ef->fd) != 1) {
+	    (*ef->free_cb)(ef->sections);
+	    return ELF_ERR_READ_SECTHDR;
+	}
+
+	/* Get fields from appropriate structure */
+	if (ef->source_class == ELFCLASS32) {
+	    /* Swap bytes in header fields if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&header, template_elf32_shdr);
+	    sect->type = header.hdr32.sh_type;
+	    sect->flags = header.hdr32.sh_flags;
+	    sect->addr = header.hdr32.sh_addr;
+	    sect->offset = header.hdr32.sh_offset;
+	    sect->size = header.hdr32.sh_size;
+	    sect->link = header.hdr32.sh_link;
+	    sect->info = header.hdr32.sh_info;
+	    sect->entsize = header.hdr32.sh_entsize;
+	}
+	else {
+	    /* Swap bytes in header fields if necessary */
+	    if (ef->source_data != ef->native_data)
+		elf_swap_bytes((char *)&header, template_elf64_shdr);
+	    sect->type = header.hdr64.sh_type;
+	    sect->flags = header.hdr64.sh_flags;
+	    sect->addr = header.hdr64.sh_addr;
+	    sect->offset = header.hdr64.sh_offset;
+	    sect->size = header.hdr64.sh_size;
+	    sect->link = header.hdr64.sh_link;
+	    sect->info = header.hdr64.sh_info;
+	    sect->entsize = header.hdr64.sh_entsize;
+	}
+	sect->contents = NULL;
+	sect->symbols = NULL;
+	if (sect->entsize > 0)
+	    sect->nelems = sect->size / sect->entsize;
+
+    }
+
+    return 0;
+}
+
+
+static char template_elf32_ehdr[] = {2, 2, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 0};
+static char template_elf64_ehdr[] = {2, 2, 4, 8, 8, 8, 4, 2, 2, 2, 2, 2, 2, 0};
+
+static int elf_read_header(struct elf_file *ef)
+{
+    union {
+	char ident[EI_NIDENT];
+	Elf32_Ehdr hdr32;
+	Elf64_Ehdr hdr64;
+    } header;
+
+    /* Read the ELF header */
+    fseek(ef->fd, 0L, SEEK_SET);
+    if (fread((char *)header.ident, EI_NIDENT, 1, ef->fd) != 1) {
+	return ELF_ERR_NOHEADER;
+    }
+
+    /* Verify that this is an ELF file */
+    if (header.ident[EI_MAG0] != ELFMAG0 ||
+	header.ident[EI_MAG1] != ELFMAG1 ||
+	header.ident[EI_MAG2] != ELFMAG2 ||
+	header.ident[EI_MAG3] != ELFMAG3) {
+	return ELF_ERR_NOTELF;
+    }
+
+    /* Get header fields from the byte array e_ident */
+    /* (These are independent of EI_CLASS and EI_DATA) */
+    ef->source_class = header.ident[EI_CLASS];
+    ef->source_data = header.ident[EI_DATA];
+
+    /* Verify EI_CLASS and EI_DATA */
+    if (header.ident[EI_CLASS] != ELFCLASS32 &&
+	header.ident[EI_CLASS] != ELFCLASS64) {
+	return ELF_ERR_INVALID_CLASS;
+    }
+    if (header.ident[EI_DATA] != ELFDATA2LSB &&
+	header.ident[EI_DATA] != ELFDATA2MSB) {
+	return ELF_ERR_INVALID_DATA;
+    }
+
+    /* Get remaining header fields from appropriate structure */
+    if (ef->source_class == ELFCLASS32) {
+	if (fread((char *)&header.hdr32 + EI_NIDENT,
+			sizeof(header.hdr32) - EI_NIDENT, 1, ef->fd) != 1)
+	    return ELF_ERR_NOHEADER;
+	/* Swap bytes in header fields if necessary */
+	if (ef->source_data != ef->native_data)
+	    elf_swap_bytes((char *)&header + EI_NIDENT, template_elf32_ehdr);
+	ef->phoff = header.hdr32.e_phoff;
+	ef->shoff = header.hdr32.e_shoff;
+	ef->ehsize = header.hdr32.e_ehsize;
+	ef->phentsize = header.hdr32.e_phentsize;
+	ef->phnum = header.hdr32.e_phnum;
+	ef->shentsize = header.hdr32.e_shentsize;
+	ef->shnum = header.hdr32.e_shnum;
+	if (ef->ehsize != sizeof(header.hdr32)) {
+	    return ELF_ERR_HEADER_SIZE;
+	}
+    }
+    else {
+	if (fread((char *)&header.hdr64 + EI_NIDENT,
+			sizeof(header.hdr64) - EI_NIDENT, 1, ef->fd) != 1)
+	    return ELF_ERR_NOHEADER;
+	/* Swap bytes in header fields if necessary */
+	if (ef->source_data != ef->native_data)
+	    elf_swap_bytes((char *)&header + EI_NIDENT, template_elf64_ehdr);
+	ef->phoff = header.hdr64.e_phoff;
+	ef->shoff = header.hdr64.e_shoff;
+	ef->ehsize = header.hdr64.e_ehsize;
+	ef->phentsize = header.hdr64.e_phentsize;
+	ef->phnum = header.hdr64.e_phnum;
+	ef->shentsize = header.hdr64.e_shentsize;
+	ef->shnum = header.hdr64.e_shnum;
+	if (ef->ehsize != sizeof(header.hdr64)) {
+	    return ELF_ERR_HEADER_SIZE;
+	}
+    }
+
+    return 0;
+}
+
+
+static struct elf_file *elf_new(struct uwx_env *env)
+{
+    int native_be;
+    char *p;
+    struct elf_file *ef;
+
+    ef = (struct elf_file *)(*env->allocate_cb)(sizeof(struct elf_file));
+    if (ef == NULL)
+	return NULL;
+
+    /* Determine the native byte order */
+    p = (char *)&native_be;
+    native_be = 1;	/* Assume big-endian */
+    *p = 0;		/* Sets be == 0 only if little-endian */
+
+    ef->allocate_cb = env->allocate_cb;
+    ef->free_cb = env->free_cb;
+    ef->filename = NULL;
+    ef->native_data = (native_be ? ELFDATA2MSB : ELFDATA2LSB);
+    ef->fd = NULL;
+    ef->source_class = 0;
+    ef->source_data = 0;
+    ef->phoff = 0;
+    ef->shoff = 0;
+    ef->text_base = 0;
+    ef->text_end = 0;
+    ef->ehsize = 0;
+    ef->phentsize = 0;
+    ef->phnum = 0;
+    ef->shentsize = 0;
+    ef->shnum = 0;
+    ef->sections = NULL;
+    ef->symbols = NULL;
+    ef->symbol_strings = NULL;
+    ef->nsyms = 0;
+    return ef;
+}
+
+
+static int elf_open(struct elf_file *ef, const char *filename)
+{
+    int err;
+
+    ef->filename = filename;
+
+    ef->fd = fopen(filename, "r");
+    if (ef->fd == NULL)
+	return ELF_ERR_OPEN;
+
+    if ((err = elf_read_header(ef)) != 0)
+	return err;
+
+    if ((err = elf_read_sect_hdrs(ef)) != 0)
+	return err;
+
+    if ((err = elf_read_prog_hdrs(ef)) != 0)
+	return err;
+
+    return 0;
+}
+
+
+static void elf_free_sections(struct elf_file *ef)
+{
+    int i;
+    struct elf_section *sect;
+
+    for (i = 0; i < ef->shnum; i++) {
+	sect = &ef->sections[i];
+	if (sect->contents != NULL)
+	    (*ef->free_cb)(sect->contents);
+	if ((sect->type == SHT_SYMTAB || sect->type == SHT_DYNSYM)
+						&& sect->symbols != NULL)
+	    (*ef->free_cb)(sect->symbols);
+    }
+    (*ef->free_cb)(ef->sections);
+}
+
+
+static void elf_close(struct elf_file *ef)
+{
+    if (ef->fd != NULL) {
+	fclose(ef->fd);
+	ef->fd = NULL;
+    }
+}
+
+
+static void elf_free(struct elf_file *ef)
+{
+    elf_close(ef);
+    if (ef->sections != NULL)
+	elf_free_sections(ef);
+    (*ef->free_cb)(ef);
+}
+
+
+static int elf_read_symbols(struct elf_file *ef)
+{
+    int i;
+    int err;
+    struct elf_section *sect;
+
+    for (i = 1; i < ef->shnum; i++) {
+	sect = &ef->sections[i];
+	if (sect->type == SHT_SYMTAB) {
+	    if (elf_read_symtab_section(ef, i) == 0) {
+		ef->symbols = sect->symbols;
+		ef->nsyms = sect->nelems;
+#ifdef DEBUG_SYMBOLS
+		printf("Read %d symbols from SHT_SYMTAB section\n", ef->nsyms);
+#endif /* DEBUG_SYMBOLS */
+		return 0;
+	    }
+	}
+    }
+    for (i = 1; i < ef->shnum; i++) {
+	sect = &ef->sections[i];
+	if (sect->type == SHT_DYNSYM) {
+	    if (elf_read_symtab_section(ef, i) == 0) {
+		ef->symbols = sect->symbols;
+		ef->nsyms = sect->nelems;
+#ifdef DEBUG_SYMBOLS
+		printf("Read %d symbols from SHT_DYNSYM section\n", ef->nsyms);
+#endif /* DEBUG_SYMBOLS */
+		return 0;
+	    }
+	}
+    }
+    return UWX_ERR_NOSYM;
+}
+
+
+#define SYM_IS_DEFINED(sym) \
+		((sym)->shndx != SHN_UNDEF)
+
+#define SYM_IS_IN_TEXT_SEGMENT(value) \
+		((value) >= ef->text_base && (value) < ef->text_end)
+
+#define SYM_HAS_INTERESTING_TYPE(type) ( \
+		(type) == STT_FUNC || \
+		(type) == STT_OBJECT || \
+		(type) == STT_HP_STUB \
+		)
+
+#define SYM_IS_INTERESTING(sym) ( \
+		SYM_IS_DEFINED(sym) && \
+		SYM_IS_IN_TEXT_SEGMENT((sym)->value) && \
+		SYM_HAS_INTERESTING_TYPE((sym)->type) \
+		)
+
+int uwx_read_func_symbols(
+    struct uwx_env *env,
+    struct uwx_symbol_cache *cache,
+    char *module_name)
+{
+    int i, j;
+    int status;
+    struct elf_file *ef;
+    struct elf_symbol *sym;
+    int nfuncsyms;
+    char **names;
+    uint64_t *values;
+
+    if (module_name != NULL &&
+	    cache->module_name != NULL &&
+		strcmp(module_name, cache->module_name) == 0)
+	return UWX_OK;
+
+    if (cache->sym_names != NULL)
+	(*env->free_cb)(cache->sym_names);
+    if (cache->sym_values != NULL)
+	(*env->free_cb)(cache->sym_values);
+    if (cache->strings != NULL)
+	(*env->free_cb)(cache->strings);
+
+    ef = elf_new(env);
+    if (ef == NULL)
+	return UWX_ERR_NOMEM;
+    status = elf_open(ef, module_name);
+    if (status != 0)
+	return UWX_ERR_NOSYM;
+    status = elf_read_symbols(ef);
+    if (status != 0)
+	return UWX_ERR_NOSYM;
+
+    nfuncsyms = 0;
+    for (i = 0; i < ef->nsyms; i++) {
+	sym = &ef->symbols[i];
+	if (SYM_IS_INTERESTING(sym))
+	    nfuncsyms++;
+    }
+
+    names = (char **)(*env->allocate_cb)(nfuncsyms * sizeof(char *));
+    if (names == NULL)
+	return UWX_ERR_NOMEM;
+    values = (uint64_t *)(*env->allocate_cb)(nfuncsyms * sizeof(uint64_t));
+    if (values == NULL)
+	return UWX_ERR_NOMEM;
+
+    j = 0;
+    for (i = 0; i < ef->nsyms; i++) {
+	sym = &ef->symbols[i];
+	if (SYM_IS_INTERESTING(sym)) {
+	    if (j >= nfuncsyms) /* should not happen! */
+		break;
+	    names[j] = sym->namep;
+	    values[j] = sym->value - ef->text_base;
+	    j++;
+	}
+    }
+
+    cache->module_name = (char *)(*env->allocate_cb)(strlen(module_name)+1);
+    if (cache->module_name != NULL) {
+	strcpy(cache->module_name, module_name);
+	cache->nsyms = nfuncsyms;
+	cache->sym_names = names;
+	cache->sym_values = values;
+	cache->strings = ef->symbol_strings;
+	ef->symbol_strings = NULL;
+    }
+
+    elf_close(ef);
+    elf_free(ef);
+
+#ifdef DEBUG_SYMBOLS
+    printf("Cached %d interesting symbols\n", nfuncsyms);
+#endif /* DEBUG_SYMBOLS */
+
+    return UWX_OK;
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,39 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+struct uwx_env;
+struct uwx_symbol_cache;
+
+extern int uwx_find_symbol(
+    struct uwx_env *env,
+    struct uwx_symbol_cache **symbol_cache_p,
+    char *module_name,
+    uint64_t relip,
+    char **func_name_p,
+    uint64_t *offset_p);
+
+extern void uwx_release_symbol_cache(
+    struct uwx_env *env,
+    struct uwx_symbol_cache *symbol_cache);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_symbols.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_trace.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_trace.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_trace.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,167 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx_env.h"
+#include "uwx_utable.h"
+#include "uwx_uinfo.h"
+#include "uwx_scoreboard.h"
+#include "uwx_trace.h"
+
+#ifdef UWX_TRACE_ENABLE
+
+void uwx_trace_init(struct uwx_env *env)
+{
+    char *tstr;
+
+    tstr = getenv("UWX_TRACE");
+    if (tstr != NULL) {
+	while (*tstr != '\0') {
+	    switch (*tstr) {
+		case 'i': env->trace |= UWX_TRACE_UINFO; break;
+		case 't': env->trace |= UWX_TRACE_UTABLE; break;
+		case 'b': env->trace |= UWX_TRACE_SB; break;
+		case 'r': env->trace |= UWX_TRACE_RSTATE; break;
+		case 's': env->trace |= UWX_TRACE_STEP; break;
+		case 'c': env->trace |= UWX_TRACE_CONTEXT; break;
+		case 'C': env->trace |= UWX_TRACE_COPYIN; break;
+		case 'L': env->trace |= UWX_TRACE_LOOKUPIP; break;
+		case '?':
+#ifdef _KERNEL
+		    fprintf(stderr, "UWX_TRACE flag `%c' unknown.\n", *tstr);
+#else
+		    fprintf(stderr, "UWX_TRACE flags:\n");
+		    fprintf(stderr, "  i: unwind info\n");
+		    fprintf(stderr, "  t: unwind table searching\n");
+		    fprintf(stderr, "  b: scoreboard management\n");
+		    fprintf(stderr, "  r: register state vector\n");
+		    fprintf(stderr, "  s: step\n");
+		    fprintf(stderr, "  c: context\n");
+		    fprintf(stderr, "  C: copyin callback\n");
+		    fprintf(stderr, "  L: lookup ip callback\n");
+		    exit(1);
+#endif
+	    }
+	    tstr++;
+	}
+    }
+}
+
+char *uwx_sb_rnames[] = {
+    "RP", "PSP", "PFS",
+    "PREDS", "UNAT", "PRIUNAT", "RNAT", "LC", "FPSR",
+    "GR4", "GR5", "GR6", "GR7",
+    "BR1", "BR2", "BR3", "BR4", "BR5",
+    "FR2", "FR3", "FR4", "FR5",
+    "FR16", "FR17", "FR18", "FR19",
+    "FR20", "FR21", "FR22", "FR23",
+    "FR24", "FR25", "FR26", "FR27",
+    "FR28", "FR29", "FR30", "FR31",
+};
+
+void uwx_dump_rstate(int regid, uint64_t rstate)
+{
+    int reg;
+
+    if (rstate == UWX_DISP_NONE)
+	return;
+    fprintf(stderr, "    %-7s", uwx_sb_rnames[regid]);
+    switch (UWX_GET_DISP_CODE(rstate)) {
+	case UWX_DISP_NONE:
+	    fprintf(stderr, "    unchanged\n");
+	    break;
+	case UWX_DISP_SPPLUS(0):
+	    fprintf(stderr, "    SP + %d\n", (int)rstate & ~0x07);
+	    break;
+	case UWX_DISP_SPREL(0):
+	    fprintf(stderr, "    [SP + %d]\n", (int)rstate & ~0x07);
+	    break;
+	case UWX_DISP_PSPREL(0):
+	    fprintf(stderr, "    [PSP + 16 - %d]\n", (int)rstate & ~0x07);
+	    break;
+	case UWX_DISP_REG(0):
+	    reg = UWX_GET_DISP_REGID(rstate);
+	    if (reg == UWX_REG_AR_PFS)
+		fprintf(stderr, "    AR.PFS\n");
+	    else if (reg == UWX_REG_AR_UNAT)
+		fprintf(stderr, "    AR.UNAT\n");
+	    else if (reg >= UWX_REG_GR(0) && reg < UWX_REG_GR(128))
+		fprintf(stderr, "    GR%d\n", reg - UWX_REG_GR(0));
+	    else if (reg >= UWX_REG_FR(0) && reg < UWX_REG_FR(128))
+		fprintf(stderr, "    FR%d\n", reg - UWX_REG_FR(0));
+	    else if (reg >= UWX_REG_BR(0) && reg < UWX_REG_BR(8))
+		fprintf(stderr, "    BR%d\n", reg - UWX_REG_BR(0));
+	    else
+		fprintf(stderr, "    <reg %d>\n", reg);
+	    break;
+	default:
+	    fprintf(stderr, "    <%08lx>\n", (long)rstate);
+	    break;
+    }
+}
+
+void uwx_dump_scoreboard(
+    struct uwx_scoreboard *scoreboard,
+    int nsbreg,
+    struct uwx_rhdr *rhdr,
+    int cur_slot,
+    int ip_slot)
+{
+    int i;
+
+    if (rhdr->is_prologue)
+	fprintf(stderr, "  Prologue region (start = %d, length = %d)\n",
+		    (int)cur_slot, (int)rhdr->rlen);
+    else
+	fprintf(stderr, "  Body region (start = %d, length = %d, ecount = %d)\n",
+		    cur_slot, (int)rhdr->rlen, rhdr->ecount);
+    if (ip_slot < rhdr->rlen)
+	fprintf(stderr, "    IP is in this region (offset = %d)\n", ip_slot);
+    for (i = 0; i < nsbreg; i++)
+	uwx_dump_rstate(i, scoreboard->rstate[i]);
+}
+
+void uwx_dump_uinfo_block(
+	struct uwx_utable_entry *uentry,
+	unsigned int ulen)
+{
+    int i;
+    uint32_t *uinfo = (uint32_t *)(intptr_t)uentry->unwind_info;
+
+    ulen += DWORDSZ;		/* Include unwind info header */
+    if (uentry->unwind_flags & UNWIND_TBL_32BIT) /* and personality routine */
+	ulen += WORDSZ;
+    else
+	ulen += DWORDSZ;
+    while (ulen >= WORDSZ) {
+	fprintf(stderr, "  %08lx: ", (unsigned long)uinfo);
+	for (i = 0; i < 4 * WORDSZ && ulen >= WORDSZ; i += WORDSZ) {
+	    fprintf(stderr, " %04x", *uinfo++);
+	    ulen -= WORDSZ;
+	}
+	fprintf(stderr, "\n");
+    }
+}
+
+#endif /* UWX_TRACE_ENABLE */


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_trace.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_trace.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_trace.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_trace.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,371 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define UWX_TRACE_SB		1	/* UWX_TRACE=b: scoreboard mgmt */
+#define UWX_TRACE_UINFO		2	/* UWX_TRACE=i: unwind info */
+#define UWX_TRACE_RSTATE	4	/* UWX_TRACE=r: reg state vector */
+#define UWX_TRACE_STEP		8	/* UWX_TRACE=s: step */
+#define UWX_TRACE_UTABLE	16	/* UWX_TRACE=t: unwind tbl search */
+#define UWX_TRACE_CONTEXT	32	/* UWX_TRACE=c: context */
+#define UWX_TRACE_COPYIN	64	/* UWX_TRACE=C: copyin callback */
+#define UWX_TRACE_LOOKUPIP	128	/* UWX_TRACE=L: lookupip callback */
+
+#ifdef UWX_TRACE_ENABLE
+
+#ifdef _KERNEL
+#define	fprintf(f, ...)		printf(__VA_ARGS__)
+#endif
+
+extern void uwx_trace_init(struct uwx_env *env);
+
+struct uwx_utable_entry;
+
+extern void uwx_dump_uinfo_block(struct uwx_utable_entry *, unsigned int);
+
+extern void uwx_dump_rstate(int regid, uint64_t rstate);
+
+struct uwx_rhdr;
+
+extern void uwx_dump_scoreboard(
+    struct uwx_scoreboard *scoreboard,
+    int nsbreg,
+    struct uwx_rhdr *rhdr,
+    int cur_slot,
+    int ip_slot);
+
+#define TRACE_INIT uwx_trace_init(env);
+
+#define TRACE_B_REUSE(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_alloc_scoreboard: reuse id %d\n", (id));
+
+#define TRACE_B_PREALLOC(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_prealloc_scoreboard: prealloc id %d\n", (id));
+
+#define TRACE_B_ALLOC(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_alloc_scoreboard: alloc id %d\n", (id));
+
+#define TRACE_B_POP(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_pop_scoreboards: free id %d\n", (id));
+
+#define TRACE_B_LABEL(label) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_label_scoreboard: label %d\n", (label));
+
+#define TRACE_B_LABEL_COPY(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_label_scoreboard: copy id %d\n", (id));
+
+#define TRACE_B_LABEL_REVERSE(back, new) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_label_scoreboard: reverse link %d -> %d\n", \
+			    (new)->id, ((back) == 0) ? -1 : (back)->id);
+
+#define TRACE_B_COPY(label, id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_copy_scoreboard: label %d, cur sb id %d\n", (label), (id));
+
+#define TRACE_B_COPY_FREE(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_copy_scoreboard: free id %d\n", (id));
+
+#define TRACE_B_COPY_FOUND(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_copy_scoreboard: found id %d\n", (id));
+
+#define TRACE_B_COPY_COPY(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_copy_scoreboard: copy id %d\n", (id));
+
+#define TRACE_B_COPY_REVERSE(back, new) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_copy_scoreboard: reverse link %d -> %d\n", \
+			    (new)->id, ((back) == 0) ? -1 : (back)->id);
+
+#define TRACE_B_FREE(id) \
+    if (env->trace & UWX_TRACE_SB) \
+	fprintf(stderr, "uwx_free_scoreboards: free id %d\n", (id));
+
+#define TRACE_I_DECODE_RHDR_1(name, b0) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_rhdr:     %02x                   %s\n", \
+			(b0), (name));
+
+#define TRACE_I_DECODE_RHDR_1L(name, b0, val) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_rhdr:     %02x %08x          %s\n", \
+			(b0), (int)(val), (name));
+
+#define TRACE_I_DECODE_RHDR_2L(name, b0, b1, val) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_rhdr:     %02x %02x %08x       %s\n", \
+			(b0), (b1), (int)(val), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_1(name, b0) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: %02x                   %s\n", \
+			(b0), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_1L(name, b0, val) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: %02x %08x          %s\n", \
+			(b0), (int)(val), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_1LL(name, b0, val1, val2) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: %02x %08x %08x %s\n", \
+			(b0), (int)(val1), (int)(val2), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_2(name, b0, b1) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: %02x %02x                %s\n", \
+			(b0), (b1), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_2L(name, b0, b1, val) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: %02x %02x %08x       %s\n", \
+			(b0), (b1), (int)(val), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_3(name, b0, b1, b2) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: %02x %02x %02x             %s\n", \
+			(b0), (b1), (b2), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_4(name, b0, b1, b2, b3) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: %02x %02x %02x %02x          %s\n", \
+			(b0), (b1), (b2), (b3), (name));
+
+#define TRACE_I_DECODE_PROLOGUE_SPILL_BASE(spill_base) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: spill base = %08x\n", (int)(spill_base));
+
+#define TRACE_I_DECODE_PROLOGUE_MASKS(gr_mem_mask, gr_gr_mask) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: gr_mem_mask = %02x; gr_gr_mask = %02x\n", \
+			(gr_mem_mask), (gr_gr_mask));
+
+#define TRACE_I_DECODE_PROLOGUE_NSPILL(ngr) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_prologue: ngr = %d\n", (ngr));
+
+#define TRACE_I_DECODE_BODY_1(name, b0) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_body:     %02x                   %s\n", \
+			(b0), (name));
+
+#define TRACE_I_DECODE_BODY_1L(name, b0, val) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_body:     %02x %08x          %s\n", \
+			(b0), (int)(val), (name));
+
+#define TRACE_I_DECODE_BODY_1LL(name, b0, val1, val2) \
+    if (env->trace & UWX_TRACE_UINFO) \
+	fprintf(stderr, "uwx_decode_body:     %02x %08x %08x %s\n", \
+			(b0), (int)(val1), (int)(val2), (name));
+
+#define TRACE_R_UIB(uentry, ulen) \
+    if (env->trace & UWX_TRACE_RSTATE) { \
+	fprintf(stderr, "Unwind info block (info = %08x %08x, flags = %08x %08x, ulen = %d)\n", \
+		    (unsigned int)((uentry)->unwind_info >> 32), \
+		    (unsigned int)(uentry)->unwind_info, \
+		    (unsigned int)((uentry)->unwind_flags >> 32), \
+		    (unsigned int)(uentry)->unwind_flags, \
+		    (ulen)); \
+	if (!env->remote) uwx_dump_uinfo_block(uentry, ulen); \
+    }
+
+#define TRACE_R_DUMP_SB(scoreboard, rhdr, cur_slot, ip_slot) \
+    if (env->trace & UWX_TRACE_RSTATE) \
+	uwx_dump_scoreboard(scoreboard, env->nsbreg, \
+				&(rhdr), cur_slot, ip_slot);
+
+#define TRACE_S_STEP(rstate) \
+    if (env->trace & UWX_TRACE_STEP) { \
+	fprintf(stderr, "uwx_restore_markers:\n"); \
+	uwx_dump_rstate(SBREG_RP, (rstate)[SBREG_RP]); \
+	uwx_dump_rstate(SBREG_PSP, (rstate)[SBREG_PSP]); \
+	uwx_dump_rstate(SBREG_PFS, (rstate)[SBREG_PFS]); \
+    }
+
+#define TRACE_S_RESTORE_REG(regname, rstate, val) \
+    if (env->trace & UWX_TRACE_STEP) \
+	fprintf(stderr, "  restore %-7s (rstate = %08x %08x) = %08x %08x\n", \
+			regname, \
+			(unsigned int) ((rstate) >> 32), \
+			(unsigned int) (rstate), \
+			(unsigned int) ((val) >> 32), \
+			(unsigned int) (val));
+
+#define TRACE_S_RESTORE_GR(regid, rstate, val) \
+    if (env->trace & UWX_TRACE_STEP) \
+	fprintf(stderr, "  restore GR%d     (rstate = %08x %08x) = %08x %08x\n", \
+			(regid) + 4, \
+			(unsigned int) ((rstate) >> 32), \
+			(unsigned int) (rstate), \
+			(unsigned int) ((val) >> 32), \
+			(unsigned int) (val));
+
+#define TRACE_S_RESTORE_BR(regid, rstate, val) \
+    if (env->trace & UWX_TRACE_STEP) \
+	fprintf(stderr, "  restore BR%d     (rstate = %08x %08x) = %08x %08x\n", \
+			(regid) + 1, \
+			(unsigned int) ((rstate) >> 32), \
+			(unsigned int) (rstate), \
+			(unsigned int) ((val) >> 32), \
+			(unsigned int) (val));
+
+#define TRACE_S_RESTORE_FR(regid, rstate, fval) \
+    if (env->trace & UWX_TRACE_STEP) \
+	fprintf(stderr, "  restore FR%d     (rstate = %08x %08x) = %08x %08x %08x %08x\n", \
+			(regid) + 1, \
+			(unsigned int) ((rstate) >> 32), \
+			(unsigned int) (rstate), \
+			(unsigned int) ((fval[0]) >> 32), \
+			(unsigned int) (fval[0]), \
+			(unsigned int) ((fval[1]) >> 32), \
+			(unsigned int) (fval[1]));
+
+#define TRACE_T_SEARCH32(ip) \
+    if (env->trace & UWX_TRACE_UTABLE) \
+	fprintf(stderr, "uwx_search_utable32 (relative ip = %08x)\n", (ip));
+
+#define TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end) \
+    if (env->trace & UWX_TRACE_UTABLE) \
+	fprintf(stderr, "    lb/ub = %d/%d, mid = %d, start/end = %08x %08x\n", \
+			    lb, ub, mid, code_start, code_end);
+
+#define TRACE_C_GET_REG(regid, bsp) \
+	if (env->trace & UWX_TRACE_CONTEXT) \
+	    fprintf(stderr, "uwx_get_reg (gr%d, bsp = %08x %08x)\n", \
+			(regid) - UWX_REG_GR(0), \
+			(unsigned int) ((bsp) >> 32), \
+			(unsigned int) (bsp));
+
+#define TRACE_C_ROTATE_GR(regid, sor, rrb_gr, newregid) \
+	if (env->trace & UWX_TRACE_CONTEXT) \
+	    fprintf(stderr, "uwx_get_reg (gr%d, sor = %d, rrb = %d) --> gr%d\n", \
+			(regid) + 32, \
+			(sor), \
+			(rrb_gr), \
+			(newregid) + 32);
+
+#define TRACE_SELF_COPYIN4(rem, len, wp) \
+    if (info->trace & UWX_TRACE_COPYIN) \
+	fprintf(stderr, "copyin (rem = %08x %08x, len = %d, val = %08x)\n", \
+			(unsigned int) ((rem) >> 32), \
+			(unsigned int) (rem), \
+			(len), *(wp));
+
+#define TRACE_SELF_COPYIN8(rem, len, dp) \
+    if (info->trace & UWX_TRACE_COPYIN) \
+	fprintf(stderr, "copyin (rem = %08x %08x, len = %d, val = %08x %08x)\n", \
+			(unsigned int) ((rem) >> 32), \
+			(unsigned int) (rem), \
+			(len), \
+			((unsigned int *)(dp))[0], \
+			((unsigned int *)(dp))[1]);
+
+#define TRACE_SELF_LOOKUP(ip) \
+    if (info->trace & UWX_TRACE_LOOKUPIP) \
+	fprintf(stderr, "Lookup IP callback: ip = %08x %08x\n", \
+			(unsigned int) ((ip) >> 32), \
+			(unsigned int) (ip));
+
+#define TRACE_SELF_LOOKUP_DESC(text_base, linkage_ptr, unwind_base) \
+	if (info->trace & UWX_TRACE_LOOKUPIP) { \
+	    fprintf(stderr, "  text base:    %08x %08x\n", \
+			(unsigned int) ((text_base) >> 32), \
+			(unsigned int) (text_base)); \
+	    fprintf(stderr, "  linkage ptr:  %08x %08x\n", \
+			(unsigned int) ((linkage_ptr) >> 32), \
+			(unsigned int) (linkage_ptr)); \
+	    fprintf(stderr, "  unwind base:  %08x %08x\n", \
+			(unsigned int) ((uint64_t)(unwind_base) >> 32), \
+			(unsigned int) (unwind_base)); \
+	    fprintf(stderr, "  unwind flags: %08x %08x\n", \
+			(unsigned int) ((unwind_base)[0] >> 32), \
+			(unsigned int) (unwind_base)[0]); \
+	    fprintf(stderr, "  unwind start: %08x %08x\n", \
+			(unsigned int) (((text_base)+(unwind_base)[1]) >> 32), \
+			(unsigned int) ((text_base)+(unwind_base)[1])); \
+	    fprintf(stderr, "  unwind end:   %08x %08x\n", \
+			(unsigned int) (((text_base)+(unwind_base)[2]) >> 32), \
+			(unsigned int) ((text_base)+(unwind_base)[2])); \
+	}
+
+#else /* !UWX_TRACE_ENABLE */
+
+#define TRACE_INIT
+#define TRACE_B_REUSE(id)
+#define TRACE_B_PREALLOC(id)
+#define TRACE_B_ALLOC(id)
+#define TRACE_B_POP(id)
+#define TRACE_B_LABEL(label)
+#define TRACE_B_LABEL_COPY(id)
+#define TRACE_B_LABEL_REVERSE(back, new)
+#define TRACE_B_COPY(label, id)
+#define TRACE_B_COPY_FREE(id)
+#define TRACE_B_COPY_FOUND(id)
+#define TRACE_B_COPY_COPY(id)
+#define TRACE_B_COPY_REVERSE(back, new)
+#define TRACE_B_FREE(id)
+#define TRACE_I_DECODE_RHDR_1(name, b0)
+#define TRACE_I_DECODE_RHDR_1L(name, b0, val)
+#define TRACE_I_DECODE_RHDR_2L(name, b0, b1, val)
+#define TRACE_I_DECODE_PROLOGUE_1(name, b0)
+#define TRACE_I_DECODE_PROLOGUE_1L(name, b0, val)
+#define TRACE_I_DECODE_PROLOGUE_1LL(name, b0, val1, val2)
+#define TRACE_I_DECODE_PROLOGUE_2(name, b0, b1)
+#define TRACE_I_DECODE_PROLOGUE_2L(name, b0, b1, parm1)
+#define TRACE_I_DECODE_PROLOGUE_3(name, b0, b1, b2)
+#define TRACE_I_DECODE_PROLOGUE_4(name, b0, b1, b2, b3)
+#define TRACE_I_DECODE_PROLOGUE_SPILL_BASE(spill_base)
+#define TRACE_I_DECODE_PROLOGUE_MASKS(gr_mem_mask, gr_gr_mask)
+#define TRACE_I_DECODE_PROLOGUE_NSPILL(ngr)
+#define TRACE_I_DECODE_BODY_1(name, b0)
+#define TRACE_I_DECODE_BODY_1L(name, b0, parm1)
+#define TRACE_I_DECODE_BODY_1LL(name, b0, parm1, parm2)
+#define TRACE_R_UIB(uentry, ulen)
+#define TRACE_R_DUMP_SB(scoreboard, rhdr, cur_slot, ip_slot)
+#define TRACE_S_STEP(rstate)
+#define TRACE_S_RESTORE_REG(regname, rstate, val)
+#define TRACE_S_RESTORE_GR(regid, rstate, val)
+#define TRACE_S_RESTORE_BR(regid, rstate, val)
+#define TRACE_S_RESTORE_FR(regid, rstate, val)
+#define TRACE_T_SEARCH32(ip)
+#define TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end)
+#define TRACE_C_GET_REG(regid, bsp)
+#define TRACE_C_ROTATE_GR(regid, sor, rrb_gr, newregid)
+#define TRACE_SELF_COPYIN4(rem, len, wp)
+#define TRACE_SELF_COPYIN8(rem, len, dp)
+#define TRACE_SELF_LOOKUP(ip)
+#define TRACE_SELF_LOOKUP_DESC(text_base, linkage_ptr, unwind_base)
+
+#endif /* UWX_TRACE_ENABLE */
+


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_trace.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,1120 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx_env.h"
+#include "uwx_uinfo.h"
+#include "uwx_utable.h"
+#include "uwx_scoreboard.h"
+#include "uwx_bstream.h"
+#include "uwx_trace.h"
+#include "uwx_swap.h"
+
+int uwx_count_ones(unsigned int mask);
+
+/*
+ *  uwx_uinfo.c
+ *
+ *  This file contains the routines for reading and decoding
+ *  the unwind information block. 
+ *
+ *  The main entry point, uwx_decode_uinfo(), is given a pointer
+ *  to an unwind table entry and a pointer (passed by reference)
+ *  to be filled in with a pointer to an update vector. It will
+ *  read and decode the unwind descriptors contained in the
+ *  unwind information block, then build the register state array,
+ *  which describes the actions necessary to step from the current
+ *  frame to the previous one.
+ */
+
+#define COPYIN_UINFO_4(dest, src) \
+    (env->remote? \
+      (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
+						WORDSZ, env->cb_token) : \
+      (*(uint32_t *)(intptr_t)(dest) = *(uint32_t *)(intptr_t)(src), WORDSZ) )
+
+#define COPYIN_UINFO_8(dest, src) \
+    (env->remote? \
+      (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
+						DWORDSZ, env->cb_token) : \
+      (*(uint64_t *)(intptr_t)(dest) = *(uint64_t *)(intptr_t)(src), DWORDSZ) )
+
+
+/* uwx_default_rstate: Returns the default register state for a leaf routine */
+
+int uwx_default_rstate(struct uwx_env *env, uint64_t **rstatep)
+{
+    struct uwx_scoreboard *sb;
+
+    sb = uwx_init_scoreboards(env);
+    *rstatep = sb->rstate;
+    return UWX_OK;
+}
+
+
+/* uwx_decode_uinfo: Decodes unwind info region */
+
+int uwx_decode_uinfo(
+    struct uwx_env *env,
+    struct uwx_utable_entry *uentry,
+    uint64_t **rstatep)
+{
+    uint64_t uinfohdr;
+    unsigned int ulen;
+    int len;
+    struct uwx_bstream bstream;
+    struct uwx_scoreboard *scoreboard;
+    int ip_slot;
+    int cur_slot;
+    int status;
+    struct uwx_rhdr rhdr;
+
+    /* Remember the offset from the start of the function */
+    /* to the current IP. This helps the client find */
+    /* the symbolic information. */
+
+    env->function_offset = env->remapped_ip - uentry->code_start;
+
+    /* Read the unwind info header using the copyin callback. */
+    /* (If we're reading a 32-bit unwind table, we need to */
+    /* read the header as two 32-bit pieces to preserve the */
+    /* guarantee that we always call copyin for aligned */
+    /* 4-byte or 8-byte chunks.) */
+    /* Then compute the length of the unwind descriptor */
+    /* region and initialize a byte stream to read it. */
+
+    if (uentry->unwind_flags & UNWIND_TBL_32BIT) {
+	len = COPYIN_UINFO_4((char *)&uinfohdr, uentry->unwind_info);
+	len += COPYIN_UINFO_4((char *)&uinfohdr + WORDSZ,
+					uentry->unwind_info + WORDSZ);
+	}
+    else
+	len = COPYIN_UINFO_8((char *)&uinfohdr, uentry->unwind_info);
+    if (len != DWORDSZ)
+	return UWX_ERR_COPYIN_UINFO;
+    if (env->byte_swap)
+	uwx_swap8(&uinfohdr);
+    if (uentry->unwind_flags & UNWIND_TBL_32BIT)
+	ulen = UNW_LENGTH(uinfohdr) * WORDSZ;
+    else
+	ulen = UNW_LENGTH(uinfohdr) * DWORDSZ;
+    uwx_init_bstream(&bstream, env,
+		uentry->unwind_info + DWORDSZ, ulen, UWX_COPYIN_UINFO);
+
+    /* Save the header and a pointer to the personality routine ptr */
+    /* for later use in exception handling. */
+
+    env->uinfo_hdr = uinfohdr;
+    env->uinfo_end = uentry->unwind_info + DWORDSZ + ulen;
+
+    TRACE_R_UIB(uentry, ulen)
+
+    /* Create an initial scoreboard for tracking the unwind state. */
+
+    scoreboard = uwx_init_scoreboards(env);
+
+    /* Prepare to read and decode the unwind regions described */
+    /* by the unwind info block. Find the target "ip" slot */
+    /* relative to the beginning of the region. The lower 4 bits */
+    /* of the actual IP encode the slot number within a bundle. */
+
+    cur_slot = 0;
+    ip_slot = (int) ((env->context.special[UWX_REG_IP] & ~0x0fLL)
+							- uentry->code_start)
+		/ BUNDLESZ * SLOTSPERBUNDLE
+		+ (unsigned int) (env->context.special[UWX_REG_IP] & 0x0f);
+
+    /* Loop over the regions in the unwind info block. */
+
+    for (;;) {
+
+	/* Decode the next region header. */
+	/* We have an error if we reach the end of the info block, */
+	/* since we should have found our target ip slot by then. */
+	/* We also have an error if the next byte isn't a region */
+	/* header record. */
+
+	status = uwx_decode_rhdr(env, &bstream, &rhdr);
+	if (status != UWX_OK)
+	    return status;
+
+	/* If a prologue region, get a new scoreboard, pushing */
+	/* the previous one onto the prologue stack. Then read */
+	/* and decode the prologue region records. */
+
+	if (rhdr.is_prologue) {
+	    scoreboard = uwx_new_scoreboard(env, scoreboard);
+	    if (scoreboard == 0)
+		return UWX_ERR_NOMEM;
+	    status = uwx_decode_prologue(env, &bstream,
+					    scoreboard, &rhdr, ip_slot);
+	}
+
+	/* If a body region, read and decode the body region */
+	/* records. If the body has an epilogue count, */
+	/* uwx_decode_body will note that in the region header */
+	/* record for use at the bottom of the loop. */
+
+	else {
+	    status = uwx_decode_body(env, &bstream, scoreboard, &rhdr, ip_slot);
+	}
+
+	if (status != UWX_OK)
+	    return status;
+
+	TRACE_R_DUMP_SB(scoreboard, rhdr, cur_slot, ip_slot)
+
+	/* If the target ip slot is within this region, we're done. */
+	/* Return the scoreboard's register state array. */
+
+	if (ip_slot < rhdr.rlen) {
+	    *rstatep = scoreboard->rstate;
+	    return UWX_OK;
+	}
+
+	/* Otherwise, update the current ip slot, pop the */
+	/* scoreboard stack based on the epilogue count, */
+	/* and loop back around for the next region. */
+
+	cur_slot += rhdr.rlen;
+	ip_slot -= rhdr.rlen;
+	if (rhdr.ecount > 0) {
+	    scoreboard = uwx_pop_scoreboards(env, scoreboard, rhdr.ecount);
+	    if (scoreboard == 0)
+		return UWX_ERR_PROLOG_UF;
+	}
+    }
+    /*NOTREACHED*/
+}
+
+
+/* uwx_decode_rhdr: Decodes a region header record */
+
+int uwx_decode_rhdr(
+    struct uwx_env *env,
+    struct uwx_bstream *bstream,
+    struct uwx_rhdr *rhdr)
+{
+    int b0;
+    int b1;
+    uint64_t val;
+    int status;
+
+    /* Get the first byte of the next descriptor record. */
+    b0 = uwx_get_byte(bstream);
+    if (b0 < 0)
+	return UWX_ERR_NOUDESC;
+
+    /* Initialize region header record. */
+
+    rhdr->is_prologue = 0;
+    rhdr->rlen = 0;
+    rhdr->mask = 0;
+    rhdr->grsave = 0;
+    rhdr->ecount = 0;
+
+    /* Format R1 */
+
+    if (b0 < 0x40) {
+	if ((b0 & 0x20) == 0) {
+	    TRACE_I_DECODE_RHDR_1("(R1) prologue", b0)
+	    rhdr->is_prologue = 1;
+	}
+	else {
+	    TRACE_I_DECODE_RHDR_1("(R1) body", b0)
+	}
+	rhdr->rlen = b0 & 0x1f;
+    }
+
+    /* Format R2 */
+
+    else if (b0 < 0x60) {
+	b1 = uwx_get_byte(bstream);
+	if (b1 < 0)
+	    return UWX_ERR_BADUDESC;
+	status = uwx_get_uleb128(bstream, &val);
+	if (status != 0)
+	    return UWX_ERR_BADUDESC;
+	TRACE_I_DECODE_RHDR_2L("(R2) prologue_gr", b0, b1, val)
+	rhdr->is_prologue = 1;
+	rhdr->rlen = (unsigned int) val;
+	rhdr->mask = ((b0 & 0x07) << 1) | (b1 >> 7);
+	rhdr->grsave = b1 & 0x7f;
+    }
+
+    /* Format R3 */
+
+    else if (b0 < 0x80) {
+	status = uwx_get_uleb128(bstream, &val);
+	if (status != 0)
+	    return UWX_ERR_BADUDESC;
+	if ((b0 & 0x03) == 0) {
+	    TRACE_I_DECODE_RHDR_1L("(R3) prologue", b0, val)
+	    rhdr->is_prologue = 1;
+	}
+	else {
+	    TRACE_I_DECODE_RHDR_1L("(R3) body", b0, val)
+	}
+	rhdr->rlen = (unsigned int) val;
+    }
+
+    /* Otherwise, not a region header record. */
+
+    else {
+	TRACE_I_DECODE_RHDR_1("(?)", b0)
+	return UWX_ERR_BADUDESC;
+    }
+
+    return UWX_OK;
+}
+
+
+/* uwx_decode_prologue: Decodes a prologue region */
+
+int uwx_decode_prologue(
+    struct uwx_env *env,
+    struct uwx_bstream *bstream,
+    struct uwx_scoreboard *scoreboard,
+    struct uwx_rhdr *rhdr,
+    int ip_slot)
+{
+    int status;
+    int reg;
+    int mask;
+    int b0;
+    int b1;
+    int b2;
+    int b3;
+    int r;
+    int t;
+    int i;
+    uint64_t parm1;
+    uint64_t parm2;
+    uint64_t newrstate[NSBREG];
+    int tspill[NSBREG];
+    int priunat_mem_rstate;
+    int t_priunat_mem;
+    unsigned int gr_mem_mask;
+    unsigned int br_mem_mask;
+    unsigned int fr_mem_mask;
+    unsigned int gr_gr_mask;
+    unsigned int br_gr_mask;
+    int ngr;
+    int nbr;
+    int nfr;
+    unsigned int spill_base;
+    unsigned int gr_base;
+    unsigned int br_base;
+    unsigned int fr_base;
+
+    /* Initialize an array of register states from the current */
+    /* scoreboard, along with a parallel array of spill times. */
+    /* We use this as a temporary scoreboard, then update the */
+    /* real scoreboard at the end of the procedure. */
+    /* We initialize the spill time to (rhdr.rlen - 1) so that */
+    /* spills without a "when" descriptor will take effect */
+    /* at the end of the prologue region. */
+    /* (Boundary condition: all actions in a zero-length prologue */
+    /* will appear to have happened in the instruction slot */
+    /* immediately preceding the prologue.) */
+
+    for (i = 0; i < env->nsbreg; i++) {
+	newrstate[i] = scoreboard->rstate[i];
+	tspill[i] = rhdr->rlen - 1;
+    }
+    priunat_mem_rstate = UWX_DISP_NONE;
+    t_priunat_mem = rhdr->rlen - 1;
+
+    fr_mem_mask = 0;
+    gr_mem_mask = 0;
+    br_mem_mask = 0;
+    gr_gr_mask = 0;
+    br_gr_mask = 0;
+    nfr = 127;
+    ngr = 127;
+    nbr = 127;
+    spill_base = 0;
+
+    /* If prologue_gr header record supplied mask and grsave, */
+    /* record these in the scoreboard. */
+
+    reg = rhdr->grsave;
+    mask = rhdr->mask;
+    if (mask & 0x8) {
+	newrstate[SBREG_RP] = UWX_DISP_REG(UWX_REG_GR(reg));
+	reg++;
+    }
+    if (mask & 0x4) {
+	newrstate[SBREG_PFS] = UWX_DISP_REG(UWX_REG_GR(reg));
+	reg++;
+    }
+    if (mask & 0x2) {
+	newrstate[SBREG_PSP] = UWX_DISP_REG(UWX_REG_GR(reg));
+	reg++;
+    }
+    if (mask & 0x1) {
+	newrstate[SBREG_PREDS] = UWX_DISP_REG(UWX_REG_GR(reg));
+	reg++;
+    }
+
+    /* Read prologue descriptor records until */
+    /* we hit another region header. */
+
+    for (;;) {
+
+	b0 = uwx_get_byte(bstream);
+
+	if (b0 < 0x80) {
+	    /* Return the last byte read to the byte stream, since it's */
+	    /* really the first byte of the next region header record. */
+	    if (b0 >= 0)
+		(void) uwx_unget_byte(bstream, b0);
+	    break;
+	}
+
+	switch ((b0 & 0x70) >> 4) {
+
+	    case 0:			/* 1000 xxxx */
+	    case 1:			/* 1001 xxxx */
+		/* Format P1 (br_mem) */
+		TRACE_I_DECODE_PROLOGUE_1("(P1) br_mem", b0)
+		br_mem_mask = b0 & 0x1f;
+		break;
+
+	    case 2:			/* 1010 xxxx */
+		/* Format P2 (br_gr) */
+		b1 = uwx_get_byte(bstream);
+		if (b1 < 0)
+		    return UWX_ERR_BADUDESC;
+		TRACE_I_DECODE_PROLOGUE_2("(P2) br_gr", b0, b1)
+		mask = ((b0 & 0x0f) << 1) | (b1 >> 7);
+		reg = b1 & 0x7f;
+		br_gr_mask = mask;
+		for (i = 0; i < NSB_BR && mask != 0; i++) {
+		    if (mask & 0x01) {
+			newrstate[SBREG_BR + i] = UWX_DISP_REG(UWX_REG_GR(reg));
+			reg++;
+		    }
+		    mask = mask >> 1;
+		}
+		break;
+
+	    case 3:			/* 1011 xxxx */
+		/* Format P3 */
+		if (b0 < 0xb8) {
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    r = ((b0 & 0x7) << 1) | (b1 >> 7);
+		    reg = b1 & 0x7f;
+		    switch (r) {
+			case 0:		/* psp_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) psp_gr", b0, b1)
+			    newrstate[SBREG_PSP] = UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 1:		/* rp_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) rp_gr", b0, b1)
+			    newrstate[SBREG_RP] = UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 2:		/* pfs_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) pfs_gr", b0, b1)
+			    newrstate[SBREG_PFS] = UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 3:		/* preds_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) preds_gr", b0, b1)
+			    newrstate[SBREG_PREDS] =
+					UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 4:		/* unat_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) unat_gr", b0, b1)
+			    newrstate[SBREG_UNAT] =
+					UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 5:		/* lc_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) lc_gr", b0, b1)
+			    newrstate[SBREG_LC] =
+					UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 6:		/* rp_br */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) rp_br", b0, b1)
+			    scoreboard->rstate[SBREG_RP] =
+					UWX_DISP_REG(UWX_REG_BR(reg));
+			    if (newrstate[SBREG_RP] ==
+						UWX_DISP_REG(UWX_REG_BR(0)))
+				newrstate[SBREG_RP] =
+					UWX_DISP_REG(UWX_REG_BR(reg));
+			    break;
+			case 7:		/* rnat_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) rnat_gr", b0, b1)
+			    newrstate[SBREG_RNAT] =
+					UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 8:		/* bsp_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) bsp_gr", b0, b1)
+			    /* Don't track BSP yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 9:		/* bspstore_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) bspstore_gr", b0, b1)
+			    /* Don't track BSPSTORE yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 10:	/* fpsr_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) fpsr_gr", b0, b1)
+			    newrstate[SBREG_FPSR] =
+					UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			case 11:	/* priunat_gr */
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) priunat_gr", b0, b1)
+			    newrstate[SBREG_PRIUNAT] =
+					UWX_DISP_REG(UWX_REG_GR(reg));
+			    break;
+			default:
+			    TRACE_I_DECODE_PROLOGUE_2("(P3) ??", b0, b1)
+			    return UWX_ERR_BADUDESC;
+		    }
+		}
+
+		/* Format P4 (spill_mask) */
+		else if (b0 == 0xb8) {
+		    TRACE_I_DECODE_PROLOGUE_1("(P4) spill_mask", b0)
+		    /* The spill_mask descriptor is followed by */
+		    /* an imask field whose length is determined */
+		    /* by the region length: there are two mask */
+		    /* bits per instruction slot in the region. */
+		    /* We decode these bits two at a time, counting */
+		    /* the number of FRs, GRs, and BRs that are */
+		    /* saved up to the slot of interest. Other */
+		    /* descriptors describe which sets of these */
+		    /* registers are spilled, and we put those */
+		    /* two pieces of information together at the */
+		    /* end of the main loop. */
+		    t = 0;
+		    nfr = 0;
+		    ngr = 0;
+		    nbr = 0;
+		    while (t < rhdr->rlen) {
+			b1 = uwx_get_byte(bstream);
+			if (b1 < 0)
+			    return UWX_ERR_BADUDESC;
+			for (i = 0; i < 4 && (t + i) < ip_slot; i++) {
+			    switch (b1 & 0xc0) {
+				case 0x00: break;
+				case 0x40: nfr++; break;
+				case 0x80: ngr++; break;
+				case 0xc0: nbr++; break;
+			    }
+			    b1 = b1 << 2;
+			}
+			t += 4;
+		    }
+		}
+
+		/* Format P5 (frgr_mem) */
+		else if (b0 == 0xb9) {
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    b2 = uwx_get_byte(bstream);
+		    if (b2 < 0)
+			return UWX_ERR_BADUDESC;
+		    b3 = uwx_get_byte(bstream);
+		    if (b3 < 0)
+			return UWX_ERR_BADUDESC;
+		    TRACE_I_DECODE_PROLOGUE_4("(P5) frgr_mem", b0, b1, b2, b3)
+		    gr_mem_mask = b1 >> 4;
+		    fr_mem_mask = ((b1 & 0x0f) << 16) | (b2 << 8) | b3;
+		}
+
+		/* Invalid descriptor record */
+		else {
+		    TRACE_I_DECODE_PROLOGUE_1("(?)", b0)
+		    return UWX_ERR_BADUDESC;
+		}
+
+		break;
+
+	    case 4:			/* 1100 xxxx */
+		/* Format P6 (fr_mem) */
+		TRACE_I_DECODE_PROLOGUE_1("(P6) fr_mem", b0)
+		fr_mem_mask = b0 & 0x0f;
+		break;
+
+	    case 5:			/* 1101 xxxx */
+		/* Format P6 (gr_mem) */
+		TRACE_I_DECODE_PROLOGUE_1("(P6) gr_mem", b0)
+		gr_mem_mask = b0 & 0x0f;
+		break;
+
+	    case 6:			/* 1110 xxxx */
+		/* Format P7 */
+		r = b0 & 0xf;
+		status = uwx_get_uleb128(bstream, &parm1);
+		if (status != 0)
+		    return UWX_ERR_BADUDESC;
+		switch (r) {
+		    case 0:		/* mem_stack_f */
+			status = uwx_get_uleb128(bstream, &parm2);
+			if (status != 0)
+			    return UWX_ERR_BADUDESC;
+			TRACE_I_DECODE_PROLOGUE_1LL("(P7) mem_stack_f", b0, parm1, parm2)
+			newrstate[SBREG_PSP] = UWX_DISP_SPPLUS(parm2 * 16);
+			tspill[SBREG_PSP] = (int) parm1;
+			break;
+		    case 1:		/* mem_stack_v */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) mem_stack_v", b0, parm1)
+			tspill[SBREG_PSP] = (int) parm1;
+			break;
+		    case 2:		/* spill_base */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) spill_base", b0, parm1)
+			spill_base = 4 * (unsigned int) parm1;
+			break;
+		    case 3:		/* psp_sprel */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) psp_sprel", b0, parm1)
+			newrstate[SBREG_PSP] = UWX_DISP_SPREL(parm1 * 4);
+			break;
+		    case 4:		/* rp_when */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) rp_when", b0, parm1)
+			tspill[SBREG_RP] = (int) parm1;
+			break;
+		    case 5:		/* rp_psprel */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) rp_psprel", b0, parm1)
+			newrstate[SBREG_RP] = UWX_DISP_PSPREL(parm1 * 4);
+			break;
+		    case 6:		/* pfs_when */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) pfs_when", b0, parm1)
+			tspill[SBREG_PFS] = (int) parm1;
+			break;
+		    case 7:		/* pfs_psprel */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) pfs_psprel", b0, parm1)
+			newrstate[SBREG_PFS] = UWX_DISP_PSPREL(parm1 * 4);
+			break;
+		    case 8:		/* preds_when */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) preds_when", b0, parm1)
+			tspill[SBREG_PREDS] = (int) parm1;
+			break;
+		    case 9:		/* preds_psprel */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) preds_psprel", b0, parm1)
+			newrstate[SBREG_PREDS] = UWX_DISP_PSPREL(parm1 * 4);
+			break;
+		    case 10:	/* lc_when */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) lc_when", b0, parm1)
+			tspill[SBREG_LC] = (int) parm1;
+			break;
+		    case 11:	/* lc_psprel */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) lc_psprel", b0, parm1)
+			newrstate[SBREG_LC] = UWX_DISP_PSPREL(parm1 * 4);
+			break;
+		    case 12:	/* unat_when */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) unat_when", b0, parm1)
+			tspill[SBREG_UNAT] = (int) parm1;
+			break;
+		    case 13:	/* unat_psprel */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) unat_psprel", b0, parm1)
+			newrstate[SBREG_UNAT] = UWX_DISP_PSPREL(parm1 * 4);
+			break;
+		    case 14:	/* fpsr_when */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) fpsr_when", b0, parm1)
+			tspill[SBREG_FPSR] = (int) parm1;
+			break;
+		    case 15:	/* fpsr_psprel */
+			TRACE_I_DECODE_PROLOGUE_1L("(P7) fpsr_psprel", b0, parm1)
+			newrstate[SBREG_FPSR] = UWX_DISP_PSPREL(parm1 * 4);
+			break;
+		}
+		break;
+
+	    case 7:			/* 1111 xxxx */
+		/* Format P8 */
+		if (b0 == 0xf0) {
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    status = uwx_get_uleb128(bstream, &parm1);
+		    if (status != 0)
+			return UWX_ERR_BADUDESC;
+		    switch (b1) {
+			case 1:		/* rp_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) rp_sprel", b0, b1, parm1)
+			    newrstate[SBREG_RP] = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 2:		/* pfs_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) pfs_sprel", b0, b1, parm1)
+			    newrstate[SBREG_PFS] = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 3:		/* preds_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) preds_sprel", b0, b1, parm1)
+			    newrstate[SBREG_PREDS] = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 4:		/* lc_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) lc_sprel", b0, b1, parm1)
+			    newrstate[SBREG_LC] = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 5:		/* unat_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) unat_sprel", b0, b1, parm1)
+			    newrstate[SBREG_UNAT] = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 6:		/* fpsr_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) fpsr_sprel", b0, b1, parm1)
+			    newrstate[SBREG_FPSR] = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 7:		/* bsp_when */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) bsp_when", b0, b1, parm1)
+			    /* Don't track BSP yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 8:		/* bsp_psprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) bsp_psprel", b0, b1, parm1)
+			    /* Don't track BSP yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 9:		/* bsp_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) bsp_sprel", b0, b1, parm1)
+			    /* Don't track BSP yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 10:	/* bspstore_when */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) bspstore_when", b0, b1, parm1)
+			    /* Don't track BSP yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 11:	/* bspstore_psprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) bspstore_psprel", b0, b1, parm1)
+			    /* Don't track BSP yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 12:	/* bspstore_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) bspstore_sprel", b0, b1, parm1)
+			    /* Don't track BSP yet */
+			    return UWX_ERR_CANTUNWIND;
+			    /* break; */
+			case 13:	/* rnat_when */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) rnat_when", b0, b1, parm1)
+			    tspill[SBREG_RNAT] = (int) parm1;
+			    break;
+			case 14:	/* rnat_psprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) rnat_psprel", b0, b1, parm1)
+			    newrstate[SBREG_RNAT] = UWX_DISP_PSPREL(parm1 * 4);
+			    break;
+			case 15:	/* rnat_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) rnat_sprel", b0, b1, parm1)
+			    newrstate[SBREG_RNAT] = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 16:	/* priunat_when_gr */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) priunat_when_gr", b0, b1, parm1)
+			    tspill[SBREG_PRIUNAT] = (int) parm1;
+			    break;
+			case 17:	/* priunat_psprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) priunat_psprel", b0, b1, parm1)
+			    priunat_mem_rstate = UWX_DISP_PSPREL(parm1 * 4);
+			    break;
+			case 18:	/* priunat_sprel */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) priunat_sprel", b0, b1, parm1)
+			    priunat_mem_rstate = UWX_DISP_SPREL(parm1 * 4);
+			    break;
+			case 19:	/* priunat_when_mem */
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) priunat_when_mem", b0, b1, parm1)
+			    t_priunat_mem = (int) parm1;
+			    break;
+			default:
+			    TRACE_I_DECODE_PROLOGUE_2L("(P8) ??", b0, b1, parm1)
+			    return UWX_ERR_BADUDESC;
+		    }
+		}
+
+		/* Format P9 (gr_gr) */
+		else if (b0 == 0xf1) {
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    b2 = uwx_get_byte(bstream);
+		    if (b2 < 0)
+			return UWX_ERR_BADUDESC;
+		    TRACE_I_DECODE_PROLOGUE_3("(P9) gr_gr", b0, b1, b2)
+		    mask = b1 & 0x0f;
+		    reg = b2 & 0x7f;
+		    gr_gr_mask = mask;
+		    for (i = 0; i < NSB_GR && mask != 0; i++) {
+			if (mask & 0x01) {
+			    newrstate[SBREG_GR + i] =
+					UWX_DISP_REG(UWX_REG_GR(reg));
+			    reg++;
+			}
+			mask = mask >> 1;
+		    }
+		}
+
+		/* Format X1 */
+		else if (b0 == 0xf9) {
+		    TRACE_I_DECODE_PROLOGUE_1("(X1)", b0)
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    /* Don't support X-format descriptors yet */
+		    return UWX_ERR_CANTUNWIND;
+		}
+
+		/* Format X2 */
+		else if (b0 == 0xfa) {
+		    TRACE_I_DECODE_PROLOGUE_1("(X2)", b0)
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    b2 = uwx_get_byte(bstream);
+		    if (b2 < 0)
+			return UWX_ERR_BADUDESC;
+		    /* Don't support X-format descriptors yet */
+		    return UWX_ERR_CANTUNWIND;
+		}
+
+		/* Format X3 */
+		else if (b0 == 0xfb) {
+		    TRACE_I_DECODE_PROLOGUE_1("(X3)", b0)
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    b2 = uwx_get_byte(bstream);
+		    if (b2 < 0)
+			return UWX_ERR_BADUDESC;
+		    /* Don't support X-format descriptors yet */
+		    return UWX_ERR_CANTUNWIND;
+		}
+
+		/* Format X4 */
+		else if (b0 == 0xfc) {
+		    TRACE_I_DECODE_PROLOGUE_1("(X4)", b0)
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    b2 = uwx_get_byte(bstream);
+		    if (b2 < 0)
+			return UWX_ERR_BADUDESC;
+		    b3 = uwx_get_byte(bstream);
+		    if (b3 < 0)
+			return UWX_ERR_BADUDESC;
+		    /* Don't support X-format descriptors yet */
+		    return UWX_ERR_CANTUNWIND;
+		}
+
+		/* Format P10 */
+		else if (b0 == 0xff) {
+		    b1 = uwx_get_byte(bstream);
+		    if (b1 < 0)
+			return UWX_ERR_BADUDESC;
+		    b2 = uwx_get_byte(bstream);
+		    if (b2 < 0)
+			return UWX_ERR_BADUDESC;
+		    TRACE_I_DECODE_PROLOGUE_3("(P10) abi", b0, b1, b2)
+		    env->abi_context = (b1 << 8) | b2;
+		    return UWX_ABI_FRAME;
+		}
+
+		/* Invalid descriptor record */
+		else {
+		    TRACE_I_DECODE_PROLOGUE_1("(?)", b0)
+		    return UWX_ERR_BADUDESC;
+		}
+		break;
+	}
+    }
+
+    /* Process the masks of spilled GRs, FRs, and BRs to */
+    /* determine when and where each register was saved. */
+
+    fr_base = spill_base + 16 * uwx_count_ones(fr_mem_mask);
+    br_base = fr_base + 8 * uwx_count_ones(br_mem_mask);
+    gr_base = br_base + 8 * uwx_count_ones(gr_mem_mask);
+    TRACE_I_DECODE_PROLOGUE_SPILL_BASE(spill_base)
+    TRACE_I_DECODE_PROLOGUE_MASKS(gr_mem_mask, gr_gr_mask)
+    TRACE_I_DECODE_PROLOGUE_NSPILL(ngr)
+    for (i = 0; ngr > 0 && i <= NSB_GR; i++) {
+	if (gr_mem_mask & 1) {
+	    newrstate[SBREG_GR + i] = UWX_DISP_PSPREL(gr_base);
+	    tspill[SBREG_GR + i] = 0;
+	    gr_base -= 8;
+	    ngr--;
+	}
+	else if (gr_gr_mask & 1) {
+	    tspill[SBREG_GR + i] = 0;
+	    ngr--;
+	}
+	gr_gr_mask = gr_gr_mask >> 1;
+	gr_mem_mask = gr_mem_mask >> 1;
+    }
+    for (i = 0; nbr > 0 && i <= NSB_BR; i++) {
+	if (br_mem_mask & 1) {
+	    newrstate[SBREG_BR + i] = UWX_DISP_PSPREL(br_base);
+	    tspill[SBREG_BR + i] = 0;
+	    br_base -= 8;
+	    nbr--;
+	}
+	else if (br_gr_mask & 1) {
+	    tspill[SBREG_BR + i] = 0;
+	    nbr--;
+	}
+	br_gr_mask = br_gr_mask >> 1;
+	br_mem_mask = br_mem_mask >> 1;
+    }
+    for (i = 0; nfr > 0 && i <= NSB_FR; i++) {
+	if (fr_mem_mask & 1) {
+	    newrstate[SBREG_FR + i] = UWX_DISP_PSPREL(fr_base);
+	    tspill[SBREG_FR + i] = 0;
+	    fr_base -= 16;
+	    nfr--;
+	}
+	fr_mem_mask = fr_mem_mask >> 1;
+    }
+
+    /* Update the scoreboard. */
+
+    for (i = 0; i < env->nsbreg; i++) {
+	if (ip_slot >= rhdr->rlen || ip_slot > tspill[i])
+	    scoreboard->rstate[i] = newrstate[i];
+    }
+    if (priunat_mem_rstate != UWX_DISP_NONE && ip_slot > t_priunat_mem)
+	scoreboard->rstate[SBREG_PRIUNAT] = priunat_mem_rstate;
+
+    return UWX_OK;
+}
+
+int uwx_count_ones(unsigned int mask)
+{
+    mask = (mask & 0x55555555) + ((mask & 0xaaaaaaaa) >> 1);
+    mask = (mask & 0x33333333) + ((mask & 0xcccccccc) >> 2);
+    mask = (mask & 0x0f0f0f0f) + ((mask & 0xf0f0f0f0) >> 4);
+    mask = (mask & 0x00ff00ff) + ((mask & 0xff00ff00) >> 8);
+    return (mask & 0x0000ffff) + ((mask & 0xffff0000) >> 16);
+}
+
+/* uwx_decode_body: Decodes a body region */
+
+int uwx_decode_body(
+    struct uwx_env *env,
+    struct uwx_bstream *bstream,
+    struct uwx_scoreboard *scoreboard,
+    struct uwx_rhdr *rhdr,
+    int ip_slot)
+{
+    int status;
+    int b0;
+    int b1;
+    int b2;
+    int b3;
+    int label;
+    int ecount;
+    int i;
+    uint64_t parm1;
+    uint64_t parm2;
+    uint64_t newrstate[NSBREG];
+    int tspill[NSBREG];
+    int t_sp_restore;
+
+    /* Initialize an array of register states from the current */
+    /* scoreboard, along with a parallel array of spill times. */
+    /* We use this as a temporary scoreboard, then update the */
+    /* real scoreboard at the end of the procedure. */
+    /* We initialize the spill time to (rhdr.rlen - 1) so that */
+    /* spills without a "when" descriptor will take effect */
+    /* at the end of the prologue region. */
+    /* (Boundary condition: all actions in a zero-length prologue */
+    /* will appear to have happened in the instruction slot */
+    /* immediately preceding the prologue.) */
+
+    for (i = 0; i < env->nsbreg; i++) {
+	newrstate[i] = scoreboard->rstate[i];
+	tspill[i] = rhdr->rlen - 1;
+    }
+    t_sp_restore = rhdr->rlen - 1;
+
+    /* Read body descriptor records until */
+    /* we hit another region header. */
+
+    for (;;) {
+
+	b0 = uwx_get_byte(bstream);
+
+	if (b0 < 0x80) {
+	    /* Return the last byte read to the byte stream, since it's */
+	    /* really the first byte of the next region header record. */
+	    if (b0 >= 0)
+		(void) uwx_unget_byte(bstream, b0);
+	    break;
+	}
+
+	/* Format B1 (label_state) */
+	if (b0 < 0xa0) {
+	    TRACE_I_DECODE_BODY_1("(B1) label_state", b0)
+	    label = b0 & 0x1f;
+	    status = uwx_label_scoreboard(env, scoreboard, label);
+	    if (status != UWX_OK)
+		return (status);
+	}
+
+	/* Format B1 (copy_state)  */
+	else if (b0 < 0xc0) {
+	    TRACE_I_DECODE_BODY_1("(B1) copy_state", b0)
+	    label = b0 & 0x1f;
+	    status = uwx_copy_scoreboard(env, scoreboard, label);
+	    if (status != UWX_OK)
+		return (status);
+	    for (i = 0; i < env->nsbreg; i++) {
+		newrstate[i] = scoreboard->rstate[i];
+		tspill[i] = rhdr->rlen;
+	    }
+	}
+
+	/* Format B2 (epilogue) */
+	else if (b0 < 0xe0) {
+	    ecount = b0 & 0x1f;
+	    status = uwx_get_uleb128(bstream, &parm1);
+	    if (status != 0)
+		return UWX_ERR_BADUDESC;
+	    TRACE_I_DECODE_BODY_1L("(B2) epilogue", b0, parm1)
+	    rhdr->ecount = ecount + 1;
+	    t_sp_restore = rhdr->rlen - (unsigned int) parm1;
+	}
+
+	/* Format B3 (epilogue) */
+	else if (b0 == 0xe0) {
+	    status = uwx_get_uleb128(bstream, &parm1);
+	    if (status != 0)
+		return UWX_ERR_BADUDESC;
+	    status = uwx_get_uleb128(bstream, &parm2);
+	    if (status != 0)
+		return UWX_ERR_BADUDESC;
+	    TRACE_I_DECODE_BODY_1LL("(B3) epilogue", b0, parm1, parm2)
+	    t_sp_restore = rhdr->rlen - (unsigned int) parm1;
+	    rhdr->ecount = (unsigned int) parm2 + 1;
+	}
+
+	/* Format B4 (label_state) */
+	else if (b0 == 0xf0) {
+	    status = uwx_get_uleb128(bstream, &parm1);
+	    if (status != 0)
+		return UWX_ERR_BADUDESC;
+	    TRACE_I_DECODE_BODY_1L("(B4) label_state", b0, parm1)
+	    label = (int) parm1;
+	    status = uwx_label_scoreboard(env, scoreboard, label);
+	    if (status != UWX_OK)
+		return (status);
+	}
+
+	/* Format B4 (copy_state) */
+	else if (b0 == 0xf8) {
+	    status = uwx_get_uleb128(bstream, &parm1);
+	    if (status != 0)
+		return UWX_ERR_BADUDESC;
+	    TRACE_I_DECODE_BODY_1L("(B4) copy_state", b0, parm1)
+	    label = (int) parm1;
+	    status = uwx_copy_scoreboard(env, scoreboard, label);
+	    if (status != UWX_OK)
+		return (status);
+	    for (i = 0; i < env->nsbreg; i++) {
+		newrstate[i] = scoreboard->rstate[i];
+		tspill[i] = rhdr->rlen;
+	    }
+	}
+
+	/* Format X1 */
+	else if (b0 == 0xf9) {
+	    TRACE_I_DECODE_BODY_1("(X1)", b0)
+	    b1 = uwx_get_byte(bstream);
+	    if (b1 < 0)
+		return UWX_ERR_BADUDESC;
+	    /* Don't support X-format descriptors yet */
+	    return UWX_ERR_CANTUNWIND;
+	}
+
+	/* Format X2 */
+	else if (b0 == 0xfa) {
+	    TRACE_I_DECODE_BODY_1("(X2)", b0)
+	    b1 = uwx_get_byte(bstream);
+	    if (b1 < 0)
+		return UWX_ERR_BADUDESC;
+	    b2 = uwx_get_byte(bstream);
+	    if (b2 < 0)
+		return UWX_ERR_BADUDESC;
+	    /* Don't support X-format descriptors yet */
+	    return UWX_ERR_CANTUNWIND;
+	}
+
+	/* Format X3 */
+	else if (b0 == 0xfb) {
+	    TRACE_I_DECODE_BODY_1("(X3)", b0)
+	    b1 = uwx_get_byte(bstream);
+	    if (b1 < 0)
+		return UWX_ERR_BADUDESC;
+	    b2 = uwx_get_byte(bstream);
+	    if (b2 < 0)
+		return UWX_ERR_BADUDESC;
+	    /* Don't support X-format descriptors yet */
+	    return UWX_ERR_CANTUNWIND;
+	}
+
+	/* Format X4 */
+	else if (b0 == 0xfc) {
+	    TRACE_I_DECODE_BODY_1("(X4)", b0)
+	    b1 = uwx_get_byte(bstream);
+	    if (b1 < 0)
+		return UWX_ERR_BADUDESC;
+	    b2 = uwx_get_byte(bstream);
+	    if (b2 < 0)
+		return UWX_ERR_BADUDESC;
+	    b3 = uwx_get_byte(bstream);
+	    if (b3 < 0)
+		return UWX_ERR_BADUDESC;
+	    /* Don't support X-format descriptors yet */
+	    return UWX_ERR_CANTUNWIND;
+	}
+
+	/* Invalid descriptor record */
+	else {
+	    TRACE_I_DECODE_BODY_1("(?)", b0)
+	    return UWX_ERR_BADUDESC;
+	}
+    }
+
+    /* Update the scoreboard. */
+
+    for (i = 0; i < env->nsbreg; i++) {
+	if (ip_slot > tspill[i])
+	    scoreboard->rstate[i] = newrstate[i];
+    }
+
+    /* If we've passed the point in the epilogue where sp */
+    /* is restored, update the scoreboard entry for PSP */
+    /* and reset any entries for registers saved in memory. */
+
+    if (rhdr->ecount > 0 && ip_slot > t_sp_restore) {
+	scoreboard->rstate[SBREG_PSP] = UWX_DISP_SPPLUS(0);
+	for (i = 0; i < env->nsbreg; i++) {
+	    if (UWX_GET_DISP_CODE(scoreboard->rstate[i]) == UWX_DISP_SPREL(0) ||
+		UWX_GET_DISP_CODE(scoreboard->rstate[i]) == UWX_DISP_PSPREL(0))
+		scoreboard->rstate[i] = UWX_DISP_NONE;
+	}
+    }
+
+    return UWX_OK;
+}
+


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,67 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+struct uwx_utable_entry;
+
+extern int uwx_decode_uinfo(
+    struct uwx_env *env,
+    struct uwx_utable_entry *uentry,
+    uint64_t **rstatep);
+
+extern int uwx_default_rstate(
+    struct uwx_env *env,
+    uint64_t **rstatep);
+
+/* Region header record */
+
+struct uwx_rhdr {
+    int is_prologue;		/* true if prologue region */
+    unsigned int rlen;		/* length of region (# instruction slots) */
+    int mask;			/* register save mask */
+    int grsave;			/* first gr used for saving */
+    unsigned int ecount;	/* epilogue count (0 = no epilogue) */
+    unsigned int epilogue_t;	/* epilogue "t" value */
+};
+
+struct uwx_bstream;
+
+extern int uwx_decode_rhdr(
+    struct uwx_env *env,
+    struct uwx_bstream *bstream,
+    struct uwx_rhdr *rhdr);
+
+extern int uwx_decode_prologue(
+    struct uwx_env *env,
+    struct uwx_bstream *bstream,
+    struct uwx_scoreboard *scoreboard,
+    struct uwx_rhdr *rhdr,
+    int ip_slot);
+
+extern int uwx_decode_body(
+    struct uwx_env *env,
+    struct uwx_bstream *bstream,
+    struct uwx_scoreboard *scoreboard,
+    struct uwx_rhdr *rhdr,
+    int ip_slot);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_uinfo.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_utable.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_utable.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_utable.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,274 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "uwx_env.h"
+#include "uwx_utable.h"
+#include "uwx_swap.h"
+#include "uwx_trace.h"
+
+/*
+ *  uwx_utable.c
+ *
+ *  This file contains the routines for searching an unwind table.
+ *  The main entry point, uwx_search_utable(), gets the
+ *  necessary information from the lookup ip callback's result
+ *  vector, determines whether the table is 32-bit or 64-bit,
+ *  then invokes the binary search routine for that format.
+ */
+
+
+/* Forward declarations */
+
+int uwx_search_utable32(
+    struct uwx_env *env,
+    uint32_t ip,
+    uint32_t text_base,
+    uint32_t unwind_start,
+    uint32_t unwind_end,
+    struct uwx_utable_entry *uentry);
+
+int uwx_search_utable64(
+    struct uwx_env *env,
+    uint64_t ip,
+    uint64_t text_base,
+    uint64_t unwind_start,
+    uint64_t unwind_end,
+    struct uwx_utable_entry *uentry);
+
+
+/* uwx_search_utable: Searches an unwind table for IP in current context */
+
+int uwx_search_utable(
+    struct uwx_env *env,
+    uint64_t ip,
+    uint64_t *uvec,
+    struct uwx_utable_entry *uentry)
+{
+    uint64_t text_base;
+    uint64_t unwind_flags;
+    uint64_t unwind_start;
+    uint64_t unwind_end;
+    int keys;
+    int status;
+
+    /* Get unwind table information from the result vector. */
+    /* Make sure all three required values are given. */
+
+    keys = 0;
+    text_base = 0;
+    unwind_flags = 0;
+    unwind_start = 0;
+    unwind_end = 0;
+    while (*uvec != 0) {
+	switch ((int)*uvec++) {
+	    case UWX_KEY_TBASE:
+		keys |= 1;
+		env->text_base = text_base = *uvec++;
+		break;
+	    case UWX_KEY_UFLAGS:
+		unwind_flags = *uvec++;
+		break;
+	    case UWX_KEY_USTART:
+		keys |= 2;
+		unwind_start = *uvec++;
+		break;
+	    case UWX_KEY_UEND:
+		keys |= 4;
+		unwind_end = *uvec++;
+		break;
+	    case UWX_KEY_GP:
+		uwx_set_reg(env, UWX_REG_GP, *uvec++);
+		break;
+	    default:
+		return UWX_ERR_BADKEY;
+	}
+    }
+    if (keys != 7)
+	return UWX_ERR_BADKEY;
+
+    /* Copy the unwind flags into the unwind entry. */
+    /* (uwx_decode_uinfo needs to know whether it's 32-bit or 64-bit.) */
+
+    uentry->unwind_flags = unwind_flags;
+
+    /* Call the appropriate binary search routine. */
+
+    if (unwind_flags & UNWIND_TBL_32BIT)
+	status = uwx_search_utable32(env,
+			(uint32_t) ip,
+			(uint32_t) text_base,
+			(uint32_t) unwind_start,
+			(uint32_t) unwind_end,
+			uentry);
+    else
+	status = uwx_search_utable64(env,
+			ip, text_base, unwind_start, unwind_end, uentry);
+
+    return status;
+}
+
+
+/* uwx_search_utable32: Binary search of 32-bit unwind table */
+
+#define COPYIN_UINFO_4(dest, src) \
+    (env->remote? \
+	(*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
+						WORDSZ, env->cb_token) : \
+	(*(uint32_t *)(dest) = *(uint32_t *)(src), WORDSZ) )
+
+#define SWIZZLE(x) (((uint64_t)((x) & 0xc0000000) << 31) | (x))
+
+int uwx_search_utable32(
+    struct uwx_env *env,
+    uint32_t ip,
+    uint32_t text_base,
+    uint32_t unwind_start,
+    uint32_t unwind_end,
+    struct uwx_utable_entry *uentry)
+{
+    int lb;
+    int ub;
+    int mid;
+    int len;
+    uint32_t code_start;
+    uint32_t code_end;
+    uint32_t unwind_info;
+
+    /* Since the unwind table uses segment-relative offsets, convert */
+    /* the IP in the current context to a segment-relative offset. */
+
+    ip -= text_base;
+
+    TRACE_T_SEARCH32(ip)
+
+    /* Standard binary search. */
+    /* Might modify this to do interpolation in the future. */
+
+    lb = 0;
+    ub = (unwind_end - unwind_start) / (3 * WORDSZ);
+    mid = 0;
+    while (ub > lb) {
+	mid = (lb + ub) / 2;
+	len = COPYIN_UINFO_4((char *)&code_start,
+	    (uintptr_t)(unwind_start+mid*3*WORDSZ));
+	len += COPYIN_UINFO_4((char *)&code_end,
+	    (uintptr_t)(unwind_start+mid*3*WORDSZ+WORDSZ));
+	if (len != 2 * WORDSZ)
+	    return UWX_ERR_COPYIN_UTBL;
+	if (env->byte_swap) {
+	    uwx_swap4(&code_start);
+	    uwx_swap4(&code_end);
+	}
+	TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end)
+	if (ip >= code_end)
+	    lb = mid + 1;
+	else if (ip < code_start)
+	    ub = mid;
+	else
+	    break;
+    }
+    if (ub <= lb)
+	return UWX_ERR_NOUENTRY;
+    len = COPYIN_UINFO_4((char *)&unwind_info,
+	(uintptr_t)(unwind_start+mid*3*WORDSZ+2*WORDSZ));
+    if (len != WORDSZ)
+	return UWX_ERR_COPYIN_UTBL;
+    if (env->byte_swap)
+	uwx_swap4(&unwind_info);
+    uentry->ptr_size = WORDSZ;
+    uentry->code_start = SWIZZLE(text_base + code_start);
+    uentry->code_end = SWIZZLE(text_base + code_end);
+    uentry->unwind_info = SWIZZLE(text_base + unwind_info);
+    return UWX_OK;
+}
+
+
+/* uwx_search_utable64: Binary search of 64-bit unwind table */
+
+#define COPYIN_UINFO_8(dest, src) \
+    (env->remote? \
+      (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
+						DWORDSZ, env->cb_token) : \
+      (*(uint64_t *)(intptr_t)(dest) = *(uint64_t *)(intptr_t)(src), DWORDSZ) )
+
+int uwx_search_utable64(
+    struct uwx_env *env,
+    uint64_t ip,
+    uint64_t text_base,
+    uint64_t unwind_start,
+    uint64_t unwind_end,
+    struct uwx_utable_entry *uentry)
+{
+    int lb;
+    int ub;
+    int mid;
+    int len;
+    uint64_t code_start;
+    uint64_t code_end;
+    uint64_t unwind_info;
+
+    /* Since the unwind table uses segment-relative offsets, convert */
+    /* the IP in the current context to a segment-relative offset. */
+
+    ip -= text_base;
+
+    /* Standard binary search. */
+    /* Might modify this to do interpolation in the future. */
+
+    lb = 0;
+    ub = (unwind_end - unwind_start) / (3 * DWORDSZ);
+    mid = 0;
+    while (ub > lb) {
+	mid = (lb + ub) / 2;
+	len = COPYIN_UINFO_8((char *)&code_start, unwind_start+mid*3*DWORDSZ);
+	len += COPYIN_UINFO_8((char *)&code_end,
+				unwind_start+mid*3*DWORDSZ+DWORDSZ);
+	if (len != 2 * DWORDSZ)
+	    return UWX_ERR_COPYIN_UTBL;
+	if (env->byte_swap) {
+	    uwx_swap8(&code_start);
+	    uwx_swap8(&code_end);
+	}
+	if (ip >= code_end)
+	    lb = mid + 1;
+	else if (ip < code_start)
+	    ub = mid;
+	else
+	    break;
+    }
+    if (ub <= lb)
+	return UWX_ERR_NOUENTRY;
+    len = COPYIN_UINFO_8((char *)&unwind_info,
+			unwind_start+mid*3*DWORDSZ+2*DWORDSZ);
+    if (len != DWORDSZ)
+	return UWX_ERR_COPYIN_UTBL;
+    if (env->byte_swap)
+	uwx_swap8(&unwind_info);
+    uentry->ptr_size = DWORDSZ;
+    uentry->code_start = text_base + code_start;
+    uentry->code_end = text_base + code_end;
+    uentry->unwind_info = text_base + unwind_info;
+    return UWX_OK;
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_utable.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/src/uwx_utable.h
===================================================================
--- trunk/sys/contrib/ia64/libuwx/src/uwx_utable.h	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/src/uwx_utable.h	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,38 @@
+/* $MidnightBSD$ */
+/*
+Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+struct uwx_utable_entry {
+    uint64_t ptr_size;
+    uint64_t code_start;
+    uint64_t code_end;
+    uint64_t unwind_info;
+    uint64_t unwind_flags;
+};
+
+extern int uwx_search_utable(
+    struct uwx_env *env,
+    uint64_t ip,
+    uint64_t *uvec,
+    struct uwx_utable_entry *uentry);


Property changes on: trunk/sys/contrib/ia64/libuwx/src/uwx_utable.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/test/Makefile
===================================================================
--- trunk/sys/contrib/ia64/libuwx/test/Makefile	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/test/Makefile	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,15 @@
+# $MidnightBSD$
+UWXINCDIR = ../include
+UWXLIBDIR = ../lib/ipf32
+
+CFLAGS = -O -I $(UWXINCDIR)
+LDFLAGS = -L $(UWXLIBDIR)
+
+dumpmyself:	dumpmyself.o dump_context.o primeregs.o
+	$(CC) -o dumpmyself $(LDFLAGS) dumpmyself.o dump_context.o primeregs.o -luwx
+
+
+dumpmyself.o:	$(UWXINCDIR)/uwx.h $(UWXINCDIR)/uwx_self.h
+
+dump_context.o:	
+primeregs.o:


Property changes on: trunk/sys/contrib/ia64/libuwx/test/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/test/dump_context.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/test/dump_context.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/test/dump_context.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,101 @@
+/* $MidnightBSD$ */
+#include <stdio.h>
+#include <inttypes.h>
+
+#define IP 0
+#define SP 1
+#define BSP 2
+#define CFM 3
+#define RP 4
+#define PSP 5
+#define PFS 6
+#define PREDS 7
+#define PRIUNAT 8
+#define AR_BSPSTORE 9
+#define AR_RNAT 10
+#define AR_UNAT 11
+#define AR_FPSR 12
+#define AR_LC 13
+#define AR_PFS 14
+#define GR4 16
+#define GR5 17
+#define GR6 18
+#define GR7 19
+#define BR1 20
+#define BR2 21
+#define BR3 22
+#define BR4 23
+#define BR5 24
+
+void dump_context(uint64_t *context)
+{
+    int i, j;
+    unsigned int valid;
+    uint64_t val;
+    static char *names[] = {
+	/*  0 */ "ip", "sp", "bsp", "cfm",
+	/*  4 */ "rp", "psp", "pfs", "preds",
+	/*  8 */ "priunat", "ar.bspstore", "ar.rnat", "ar.unat",
+	/* 12 */ "ar.fpsr", "ar.lc", "ar.pfs", "(pad)",
+	/* 16 */ "gr4", "gr5", "gr6", "gr7",
+	/* 20 */ "br1", "br2", "br3", "br4", "br5"
+    };
+    static int col1[] = {
+	IP,
+	SP,
+	BSP,
+	CFM,
+	RP,
+	PSP,
+	PFS,
+	AR_RNAT,
+	AR_UNAT,
+	AR_FPSR,
+	AR_LC,
+	AR_PFS,
+    };
+    static int col2[] = {
+	PREDS,
+	PRIUNAT,
+	GR4,
+	GR5,
+	GR6,
+	GR7,
+	BR1,
+	BR2,
+	BR3,
+	BR4,
+	BR5,
+    };
+
+#define NCOL1 (sizeof(col1)/sizeof(int))
+#define NCOL2 (sizeof(col2)/sizeof(int))
+#define NPRINT (NCOL1 > NCOL2 ? NCOL1 : NCOL2)
+
+    valid = (unsigned int)(context[0] >> 32);
+    printf("  valid_regs (%08lx):", valid);
+    for (i = 0; i <= BR5; i++) {
+	if (valid & 1) printf(" %s", names[i]);
+	valid >>= 1;
+    }
+    printf("\n");
+    for (i = 0; i < NPRINT; i++) {
+	if (i < NCOL1) {
+	    j = col1[i];
+	    val = context[j+1];
+	    printf("  %-8s %08x %08x", names[j],
+			(unsigned int)(val >> 32),
+			(unsigned int)val);
+	}
+	else
+	    printf("                            ");
+	if (i < NCOL2) {
+	    j = col2[i];
+	    val = context[j+1];
+	    printf("      %-8s %08x %08x", names[j],
+			(unsigned int)(val >> 32),
+			(unsigned int)val);
+	}
+	putchar('\n');
+    }
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/test/dump_context.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/test/dumpmyself.c
===================================================================
--- trunk/sys/contrib/ia64/libuwx/test/dumpmyself.c	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/test/dumpmyself.c	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,107 @@
+/* $MidnightBSD$ */
+#include "uwx.h"
+#include "uwx_self.h"
+
+struct uwx_env *uenv;
+struct uwx_self_info *cbinfo;
+
+extern int uwx_get_frame_info(struct uwx_env *uenv);
+
+extern void dump_context(uint64_t *context);
+
+extern void prime_registers();
+
+int main(int argc, char **argv)
+{
+    int status;
+    unsigned int *wp;
+    uenv = uwx_init();
+    printf("uwx_init returned %08x\n", uenv);
+    cbinfo = uwx_self_init_info(uenv);
+    status = uwx_register_callbacks(
+		uenv,
+		(intptr_t)cbinfo,
+		uwx_self_copyin,
+		uwx_self_lookupip);
+    printf("uwx_register_callbacks returned %d\n", status);
+    uwx_self_init_context(uenv);
+    printf("In main():\n");
+    dump_context((uint64_t *)uenv);
+    prime_registers();
+    uwx_free(uenv);
+    return 0;
+}
+
+int func1(void)
+{
+    uwx_self_init_context(uenv);
+    printf("In func1():\n");
+    dump_context((uint64_t *)uenv);
+    return func2();
+}
+
+int func2(void)
+{
+    uwx_self_init_context(uenv);
+    printf("In func2():\n");
+    dump_context((uint64_t *)uenv);
+    return func3();
+}
+
+int func3(void)
+{
+    uwx_self_init_context(uenv);
+    printf("In func3():\n");
+    dump_context((uint64_t *)uenv);
+    return func4();
+}
+
+int func4(void)
+{
+    int status;
+    int foo[10];
+    uint64_t *p;
+    uint64_t disp;
+    uint64_t val;
+
+    func5(foo);
+    uwx_self_init_context(uenv);
+    uwx_init_history(uenv);
+    printf("In func4():\n");
+    dump_context((uint64_t *)uenv);
+    for (;;) {
+	status = uwx_step(uenv);
+	if (status != UWX_OK) {
+	    printf("uwx_step returned %d\n", status);
+	    break;
+	}
+	status = uwx_get_reg(uenv, UWX_REG_PFS, &val);
+	if (status != UWX_OK) {
+	    printf("uwx_get_reg returned %d\n", status);
+	    break;
+	}
+	printf("After step:\n");
+	dump_context((uint64_t *)uenv);
+	status = uwx_get_spill_loc(uenv, UWX_REG_IP, &disp);
+	if (status == UWX_OK) {
+	    p = (uint64_t *)(disp & ~0x7LL);
+	    if ((disp & 0x7) == UWX_DISP_RSTK(0))
+		printf("IP spilled to backing store %08x = %08x\n",
+						    (int)p, (int)(*p));
+	    else if ((disp & 0x7) == UWX_DISP_MSTK(0))
+		printf("IP spilled to mem stack %08x = %08x\n",
+						    (int)p, (int)(*p));
+	    else if ((disp & 0x7) == UWX_DISP_REG(0))
+		printf("IP found in register %08x\n", (int)disp >> 4);
+	    else
+		printf("IP history not available\n");
+	}
+    }
+    return 0;
+}
+
+int func5(int *foo)
+{
+    foo[0] = 0;
+    return 0;
+}


Property changes on: trunk/sys/contrib/ia64/libuwx/test/dumpmyself.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/contrib/ia64/libuwx/test/primeregs.s
===================================================================
--- trunk/sys/contrib/ia64/libuwx/test/primeregs.s	                        (rev 0)
+++ trunk/sys/contrib/ia64/libuwx/test/primeregs.s	2018-05-28 18:56:41 UTC (rev 10140)
@@ -0,0 +1,94 @@
+/* $MidnightBSD$ */
+	.text
+	.proc	prime_registers
+	.global prime_registers
+
+prime_registers:
+
+	.prologue
+
+	.save ar.pfs, r32
+	alloc	r32 = ar.pfs, 0, 3, 0, 0
+	.save rp, r33
+	mov	r33 = b0
+	.save ar.unat, r34
+	mov	r34 = ar.unat
+	add	r14 = -56, sp
+	add	r15 = -48, sp
+	.fframe 80
+	add	sp = -80, sp
+	mov	r16 = b1
+	;;
+
+	.save.g 0x1
+	st8.spill [r14] = r4, 16
+	.save.g 0x2
+	st8.spill [r15] = r5, 16
+	mov	r17 = b2
+	;;
+	.save.g 0x4
+	st8.spill [r14] = r6, 16
+	.save.g 0x8
+	st8.spill [r15] = r7, 16
+	mov	r18 = b3
+	;;
+	.save.b 0x1
+	st8	[r14] = r16, 16
+	.save.b 0x2
+	st8	[r15] = r17, 16
+	mov	r19 = b4
+	;;
+	.save.b 0x4
+	st8	[r14] = r18, 16
+	.save.b 0x8
+	st8	[r15] = r19
+	mov	r20 = b5
+	;;
+	.save.b 0x10
+	st8	[r14] = r20
+
+	.body
+
+	dep.z	r4 = -0x34, 16, 32
+	;;
+	add	r5 = 1, r4
+	add	r6 = 2, r4
+	;;
+	add	r7 = 3, r4
+	;;
+
+	.global func1
+	.type	func1, @function
+	br.call.sptk b0 = func1
+	;;
+
+	add	r14 = 80, sp
+	add	r15 = 88, sp
+	;;
+	ld8	r20 = [r15], -16
+	;;
+	ld8	r19 = [r14], -16
+	ld8	r18 = [r15], -16
+	mov	b5 = r20
+	;;
+	ld8	r17 = [r14], -16
+	ld8	r16 = [r15], -16
+	mov	b4 = r19
+	;;
+	ld8.fill r7 = [r14], -16
+	ld8.fill r6 = [r15], -16
+	mov	b3 = r18
+	;;
+	ld8.fill r5 = [r14]
+	ld8.fill r4 = [r15]
+	mov	b2 = r17
+	mov	b1 = r16
+
+	.restore sp
+	mov	ar.pfs = r32
+	;;
+	add	sp = 80, sp
+	mov	ar.unat = r34
+	mov	b0 = r33
+	br.ret.sptk	b0
+	.endp


Property changes on: trunk/sys/contrib/ia64/libuwx/test/primeregs.s
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list