aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/contrib/ia64/libuwx/src/Makefile15
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx.h71
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_bstream.c8
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_bstream.h2
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_context.c29
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_context.h2
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_env.c143
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_env.h9
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_scoreboard.c48
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_scoreboard.h7
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_self.c250
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_self.h2
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_self_context.s273
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_self_info.h44
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_step.c149
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_step.h4
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_str.c35
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_str.h6
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_swap.c2
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_swap.h2
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_symbols.c850
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_symbols.h38
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_trace.c64
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_trace.h114
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_uinfo.c48
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_uinfo.h2
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_utable.c35
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_utable.h3
28 files changed, 1908 insertions, 347 deletions
diff --git a/sys/contrib/ia64/libuwx/src/Makefile b/sys/contrib/ia64/libuwx/src/Makefile
index fa5b8f5c51ff..7cc0f2d5aed7 100644
--- a/sys/contrib/ia64/libuwx/src/Makefile
+++ b/sys/contrib/ia64/libuwx/src/Makefile
@@ -15,11 +15,12 @@ OTHERCFLAGS =
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_trace.o uwx_uinfo.o \
- uwx_utable.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 uwx_ttrace.o
+SELFOBJS = uwx_self.o uwx_self_context.o
# SELFLIBS = # For cross-unwind library
SELFLIBS = -luca
@@ -34,6 +35,9 @@ libuwx.so: $(OBJS) $(SELFOBJS)
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
@@ -49,6 +53,8 @@ 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 \
@@ -56,7 +62,8 @@ uwx_uinfo.o: uwx.h uwx_env.h uwx_uinfo.h uwx_utable.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_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
diff --git a/sys/contrib/ia64/libuwx/src/uwx.h b/sys/contrib/ia64/libuwx/src/uwx.h
index 9adcfb920800..41d4cca09dbf 100644
--- a/sys/contrib/ia64/libuwx/src/uwx.h
+++ b/sys/contrib/ia64/libuwx/src/uwx.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -25,13 +25,8 @@ 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"
@@ -39,11 +34,14 @@ OTHER DEALINGS IN THE SOFTWARE.
#define __EXTERN_C extern
#endif
-#define UWX_VERSION 1 /* Version id for callback interfaces */
+#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);
@@ -58,6 +56,9 @@ __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) */
@@ -107,6 +108,17 @@ __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 */
@@ -114,6 +126,22 @@ __EXTERN_C int uwx_get_sym_info(
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 */
@@ -135,6 +163,10 @@ __EXTERN_C int uwx_get_spill_loc(
/* 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 */
@@ -158,6 +190,8 @@ __EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
#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 */
@@ -169,6 +203,7 @@ __EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
#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 */
@@ -199,11 +234,13 @@ __EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
#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 */
@@ -212,6 +249,7 @@ __EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
#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 */
@@ -219,6 +257,7 @@ __EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
/* 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 */
@@ -246,6 +285,7 @@ __EXTERN_C int uwx_get_abi_context_code(struct uwx_env *env);
#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))
@@ -321,10 +361,27 @@ public:
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);
}
diff --git a/sys/contrib/ia64/libuwx/src/uwx_bstream.c b/sys/contrib/ia64/libuwx/src/uwx_bstream.c
index 4bc8e4259487..3a9e6d99886f 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_bstream.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_bstream.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -46,7 +46,7 @@ void uwx_init_bstream(
}
else {
bstream->source = 0;
- bstream->bufp = (unsigned char *) source;
+ bstream->bufp = (unsigned char *) (intptr_t) source;
bstream->nbuf = len;
bstream->copyin = 0;
bstream->cb_token = 0;
@@ -64,6 +64,8 @@ int uwx_get_byte(struct uwx_bstream *bstream)
int len;
int n;
int b;
+ uint32_t *wp;
+ uint64_t *dp;
if (bstream->peekc >= 0) {
b = bstream->peekc;
@@ -129,7 +131,6 @@ int uwx_get_uleb128(struct uwx_bstream *bstream, uint64_t *valp)
return 0;
}
-#if 0
int uwx_get_uleb128_alt(struct uwx_bstream *bstream, uint64_t *valp)
{
uint64_t val;
@@ -178,4 +179,3 @@ int uwx_get_uleb128_alt(struct uwx_bstream *bstream, uint64_t *valp)
*valp = val;
return 0;
}
-#endif
diff --git a/sys/contrib/ia64/libuwx/src/uwx_bstream.h b/sys/contrib/ia64/libuwx/src/uwx_bstream.h
index 066d94645dfb..c2fe5da0704d 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_bstream.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_bstream.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
diff --git a/sys/contrib/ia64/libuwx/src/uwx_context.c b/sys/contrib/ia64/libuwx/src/uwx_context.c
index 68e65e7c5547..a7acd72873dd 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_context.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_context.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -182,7 +182,7 @@ int uwx_get_nat(struct uwx_env *env, int regid, int *natp)
bsp = uwx_add_to_bsp(bsp, regid);
natcollp = bsp | 0x01f8;
n = (*env->copyin)(UWX_COPYIN_RSTACK, (char *)&natcoll,
- bsp, DWORDSZ, env->cb_token);
+ natcollp, DWORDSZ, env->cb_token);
if (n != DWORDSZ)
return UWX_ERR_COPYIN_RSTK;
*natp = (int)(natcoll >> (((int)bsp >> 3) & 0x3f)) & 0x01;
@@ -200,6 +200,7 @@ int uwx_get_spill_loc(struct uwx_env *env, int regid, uint64_t *dispp)
int sor;
int rrb_gr;
uint64_t bsp;
+ int n;
if (env == 0)
return UWX_ERR_NOENV;
@@ -208,8 +209,17 @@ int uwx_get_spill_loc(struct uwx_env *env, int regid, uint64_t *dispp)
if (regid == UWX_REG_GR(12))
regid = UWX_REG_SP;
- if (regid < NSPECIALREG)
+ 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)) {
@@ -273,6 +283,7 @@ int uwx_set_reg(struct uwx_env *env, int regid, uint64_t val)
int uwx_set_fr(struct uwx_env *env, int regid, uint64_t *val)
{
+ int status;
if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(5))
regid -= UWX_REG_FR(2);
@@ -313,7 +324,7 @@ uint64_t uwx_add_to_bsp(uint64_t bsp, int nslots)
* ^
* |
* bsp
- * <------- adjusted (nslots + bias) ------->
+ * <------------ nslots + bias ----------->
* When subtracting from bsp, we avoid depending on the sign of
* the quotient by adding 63*8 before division and subtracting 8
@@ -325,12 +336,12 @@ uint64_t uwx_add_to_bsp(uint64_t bsp, int nslots)
* | X X|
* +---------------------------------------------------------------+
* <-- bias -->
- * <--- |nslots| --->
+ * <--- (-nslots) --->
* ^
* |
* bsp
* <----------------->
- * adjusted |nslots + bias|
+ * -(nslots + bias)
*/
bias = ((unsigned int)bsp & 0x1f8) / DWORDSZ;
@@ -338,7 +349,6 @@ uint64_t uwx_add_to_bsp(uint64_t bsp, int nslots)
return bsp + nslots * DWORDSZ;
}
-#if 0
int uwx_selftest_bsp_arithmetic()
{
int i;
@@ -366,7 +376,7 @@ int uwx_selftest_bsp_arithmetic()
if (r >= 1000)
r -= 1000;
for (j = 0; j < 96; j++) {
- p = (uint64_t *)uwx_add_to_bsp((uint64_t)bsp, j);
+ p = (uint64_t *)(intptr_t)uwx_add_to_bsp((uint64_t)bsp, j);
if (*p != (r + j)) {
failed++;
printf("%d [%08lx] + %d -> %08lx ",
@@ -385,7 +395,7 @@ int uwx_selftest_bsp_arithmetic()
if (r >= 1000)
r -= 1000;
for (j = 0; j < 96; j++) {
- p = (uint64_t *)uwx_add_to_bsp((uint64_t)bsp, -j);
+ p = (uint64_t *)(intptr_t)uwx_add_to_bsp((uint64_t)bsp, -j);
if (*p != (r - j)) {
failed++;
printf("%d [%08lx] - %d -> %08lx ",
@@ -397,4 +407,3 @@ int uwx_selftest_bsp_arithmetic()
return failed;
}
-#endif
diff --git a/sys/contrib/ia64/libuwx/src/uwx_context.h b/sys/contrib/ia64/libuwx/src/uwx_context.h
index 2bdedc91cacb..1f172db5b539 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_context.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_context.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
diff --git a/sys/contrib/ia64/libuwx/src/uwx_env.c b/sys/contrib/ia64/libuwx/src/uwx_env.c
index 4149a276af0c..9e24d9b3e705 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_env.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_env.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -22,21 +22,13 @@ 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;
@@ -68,52 +60,97 @@ int uwx_init_history(struct uwx_env *env)
return UWX_OK;
}
-struct uwx_env *uwx_init()
+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 = malloc;
+ if (uwx_free_cb != NULL)
+ env->free_cb = uwx_free_cb;
+ else
+ env->free_cb = free;
+ 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(sizeof(struct uwx_env));
+ env = (struct uwx_env *) malloc(total_size);
else
- env = (struct uwx_env *) (*uwx_allocate_cb)(sizeof(struct uwx_env));
+ env = (struct uwx_env *) (*uwx_allocate_cb)(total_size);
if (env != 0) {
- 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;
- (void)uwx_init_history(env);
- env->allocate_cb = uwx_allocate_cb;
- env->free_cb = uwx_free_cb;
- env->free_scoreboards = 0;
- env->used_scoreboards = 0;
- env->labeled_scoreboards = 0;
- (void)uwx_init_str_pool(env);
- 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_NOFR;
- env->nscoreboards = 0;
- env->trace = 0;
- TRACE_INIT
- for (i = 0; i < NSCOREBOARDS; i++)
- (void) uwx_alloc_scoreboard(env);
+ uwx_init_env(env, total_size);
+ env->on_heap = 1;
}
return env;
}
@@ -165,10 +202,12 @@ int uwx_free(struct uwx_env *env)
if (env != 0) {
uwx_free_scoreboards(env);
uwx_free_str_pool(env);
- if (env->free_cb == 0)
- free((void *)env);
- else
- (*env->free_cb)((void *)env);
+ if (env->on_heap) {
+ if (env->free_cb == 0)
+ free((void *)env);
+ else
+ (*env->free_cb)((void *)env);
+ }
}
return UWX_OK;
}
diff --git a/sys/contrib/ia64/libuwx/src/uwx_env.h b/sys/contrib/ia64/libuwx/src/uwx_env.h
index 2451239549f8..71b9d663e07a 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_env.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_env.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -80,6 +80,11 @@ struct uwx_env {
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;
@@ -97,8 +102,10 @@ struct uwx_env {
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);
diff --git a/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c b/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
index ee58880e24ae..df8abadff1d4 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -22,42 +22,22 @@ 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)
+void uwx_prealloc_scoreboard(struct uwx_env *env, struct uwx_scoreboard *sb)
{
- int idx = p - uwx_scoreboard;
- uwx_allocated &= ~(1 << idx);
+ sb->id = env->nscoreboards++;
+ sb->nextused = env->used_scoreboards;
+ sb->prealloc = 1;
+ env->used_scoreboards = sb;
+ TRACE_B_PREALLOC(sb->id)
}
-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
-
-
struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env)
{
struct uwx_scoreboard *sb;
@@ -79,6 +59,7 @@ struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env)
return 0;
sb->id = env->nscoreboards++;
sb->nextused = env->used_scoreboards;
+ sb->prealloc = 0;
env->used_scoreboards = sb;
TRACE_B_ALLOC(sb->id)
}
@@ -95,7 +76,6 @@ struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env)
return sb;
}
-static
void uwx_reclaim_scoreboards(struct uwx_env *env)
{
struct uwx_scoreboard *sb;
@@ -170,7 +150,6 @@ int uwx_label_scoreboard(
/* in the "nextstack" field. */
back = 0;
- new = 0;
while (sb != 0) {
TRACE_B_LABEL_COPY(sb->id)
new = uwx_alloc_scoreboard(env);
@@ -254,7 +233,6 @@ int uwx_copy_scoreboard(
/* 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);
@@ -291,10 +269,12 @@ void uwx_free_scoreboards(struct uwx_env *env)
for (sb = env->used_scoreboards; sb != 0; sb = next) {
TRACE_B_FREE(sb->id)
next = sb->nextused;
- if (env->free_cb == 0)
- free((void *)sb);
- else
- (*env->free_cb)((void *)sb);
+ 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;
diff --git a/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h b/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h
index 0122d3801b57..752b8fb479bc 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_scoreboard.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -51,8 +51,13 @@ struct uwx_scoreboard {
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);
diff --git a/sys/contrib/ia64/libuwx/src/uwx_self.c b/sys/contrib/ia64/libuwx/src/uwx_self.c
index af2e36f740a8..5f47205f218c 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_self.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_self.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -23,6 +23,7 @@ OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
+#include <string.h>
#include <crt0.h>
#include <dlfcn.h>
#include <sys/uc_access.h>
@@ -31,52 +32,49 @@ OTHER DEALINGS IN THE SOFTWARE.
#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 */
-struct uwx_self_info {
- struct uwx_env *env;
- ucontext_t *ucontext;
- uint64_t bspstore;
- uint64_t rvec[10];
- uint64_t sendsig_start;
- uint64_t sendsig_end;
- alloc_cb allocate_cb;
- free_cb free_cb;
- int trace;
-};
+void uwx_free_load_module_cache(struct uwx_self_info *info);
-struct uwx_self_info *uwx_self_init_info(struct uwx_env *env)
+int uwx_self_init_info_block(struct uwx_env *env, struct uwx_self_info *info)
{
- struct uwx_self_info *info;
-
- if (env->allocate_cb == 0)
- info = (struct uwx_self_info *)
- malloc(sizeof(struct uwx_self_info));
- else
- info = (struct uwx_self_info *)
- (*env->allocate_cb)(sizeof(struct uwx_self_info));
- if (info == 0)
- return 0;
-
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->allocate_cb = env->allocate_cb;
- info->free_cb = env->free_cb;
+ 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)
{
- if (info->free_cb == 0)
- free((void *)info);
- else
- (*info->free_cb)((void *)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;
}
@@ -97,17 +95,37 @@ int uwx_self_init_from_sigcontext(
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 */
@@ -136,9 +154,10 @@ int uwx_self_do_context_frame(
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 != 0)
+ if (status != UWX_OK)
return status;
- return uwx_self_init_from_sigcontext(env, info, (ucontext_t *)ucontext);
+ return uwx_self_init_from_sigcontext(env, info,
+ (ucontext_t *)(intptr_t)ucontext);
}
int uwx_self_copyin(
@@ -164,12 +183,12 @@ int uwx_self_copyin(
case UWX_COPYIN_MSTACK:
if (len == 4) {
wp = (unsigned long *) loc;
- *wp = *(unsigned long *)rem;
+ *wp = *(unsigned long *)(intptr_t)rem;
TRACE_SELF_COPYIN4(rem, len, wp)
status = 0;
}
else if (len == 8) {
- *dp = *(uint64_t *)rem;
+ *dp = *(uint64_t *)(intptr_t)rem;
TRACE_SELF_COPYIN8(rem, len, dp)
status = 0;
}
@@ -181,13 +200,13 @@ int uwx_self_copyin(
status = 0;
}
else if (info->ucontext == 0 || rem < info->bspstore) {
- *dp = *(uint64_t *)rem;
+ *dp = *(uint64_t *)(intptr_t)rem;
TRACE_SELF_COPYIN8(rem, len, dp)
status = 0;
}
else {
status = __uc_get_rsebs(info->ucontext,
- (uint64_t *)rem, 1, dp);
+ (uint64_t *)(intptr_t)rem, 1, dp);
}
}
break;
@@ -230,6 +249,88 @@ int uwx_self_copyin(
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,
@@ -239,10 +340,14 @@ int uwx_self_lookupip(
{
struct uwx_self_info *info = (struct uwx_self_info *) tok;
UINT64 handle;
- struct load_module_desc desc;
+ 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)
@@ -251,28 +356,31 @@ int uwx_self_lookupip(
rvec = info->rvec;
rvec[i++] = UWX_KEY_CONTEXT;
rvec[i++] = UWX_ABI_HPUX_SIGCONTEXT;
- rvec[i++] = 0;
+ rvec[i++] = UWX_KEY_END;
rvec[i++] = 0;
*resultp = rvec;
return UWX_LKUP_FDESC;
}
else {
- handle = dlmodinfo(ip, &desc, sizeof(desc), 0, 0, 0);
- if (handle == 0)
+ desc = uwx_get_modinfo(info, ip, NULL);
+ if (desc == NULL)
return UWX_LKUP_ERR;
- unwind_base = (uint64_t *) desc.unwind_base;
- TRACE_SELF_LOOKUP_DESC(desc.text_base, unwind_base)
+ 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++] = 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++] = desc->text_base + unwind_base[1];
rvec[i++] = UWX_KEY_UEND;
- rvec[i++] = desc.text_base + unwind_base[2];
- rvec[i++] = 0;
+ 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;
@@ -281,4 +389,54 @@ int uwx_self_lookupip(
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;
}
diff --git a/sys/contrib/ia64/libuwx/src/uwx_self.h b/sys/contrib/ia64/libuwx/src/uwx_self.h
index 0590ade29556..ada318442ead 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_self.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_self.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
diff --git a/sys/contrib/ia64/libuwx/src/uwx_self_context.s b/sys/contrib/ia64/libuwx/src/uwx_self_context.s
index e373c4a893b3..e2986eb4139b 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_self_context.s
+++ b/sys/contrib/ia64/libuwx/src/uwx_self_context.s
@@ -1,4 +1,4 @@
-// Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+// 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
@@ -47,23 +47,40 @@ 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_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_RNAT | VALID_UNAT | VALID_FPSR | VALID_LC
-VALID_BITS = (VALID_BASIC4 | VALID_SPEC | VALID_GRS | VALID_BRS) << 32
+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:
@@ -107,9 +124,9 @@ uwx_self_init_context:
;;
mov rRNAT = ar.rnat // get copy of ar.rnat
movl rTMP1 = VALID_BITS // valid_regs: ip, sp, bsp, cfm,
- // preds, rnat, unat, fpsr,
+ // preds, priunat, rnat, unat, fpsr,
// lc, grs, brs
- // = 0x1ff3c8f00000000
+ // = 0x1ff3d8f00000000
;;
mov ar.rsc = rRSC // restore ar.rsc
mov rBSP = ar.bsp
@@ -119,25 +136,24 @@ uwx_self_init_context:
nop
extr.u rTMP3 = rTMP3, 3, 6 // bitpos = spill_loc{8:3}
;;
- or rNATP = rBSP, rNATP // natp = bsp | 0x1f8
+ and rBIAS = rBSP, rNATP // bias = (bsp & 0x1f8) ...
sub rTMP4 = 64, rTMP3 // (64 - bitpos)
shr rTMP5 = rTMP2, rTMP3 // (unat >> bitpos)
;;
- sub rBIAS = rNATP, rBSP // bias = (natp - bsp) ...
nop
+ extr.u rBIAS = rBIAS, 3, 6 // ... div 8
shl rTMP2 = rTMP2, rTMP4 // (unat << (64 - bitpos))
;;
or rTMP2 = rTMP2, rTMP5 // rotate_right(unat, bitpos)
- extr.u rBIAS = rBIAS, 3, 6 // ... div 8
+ nop
mov rTMP4 = pr
;;
st8 [rENV0] = rTMP1, 16 // env+0: valid_regs mask
st8 [rENV1] = rRP, 24 // env+8: ip (my rp)
- add rBIAS = rNSLOT, rBIAS // bias += nslots
+ sub rBIAS = rNSLOT, rBIAS // bias = nslots - bias
;;
- cmp.lt p6, p0 = 63, rBIAS // if (63 < bias) ...
- cmp.lt p7, p0 = 126, rBIAS // if (126 < bias) ...
- nop
+ 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)
@@ -147,24 +163,221 @@ uwx_self_init_context:
st8 [rENV1] = rTMP2, 24 // env+72: priunat
(p7) add rNSLOT = 1, rNSLOT // ... nslots++
;;
- st8 [rENV0] = rRNAT, -64 // env+88: rnat
- st8 [rENV1] = rUNAT, 8 // env+96: unat
+ 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 // env+24: bsp (my prev bsp)
- st8 [rENV1] = rTMP3, 8 // env+104: fpsr
+ 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 // env+112: lc
+ 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
+ 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
diff --git a/sys/contrib/ia64/libuwx/src/uwx_self_info.h b/sys/contrib/ia64/libuwx/src/uwx_self_info.h
new file mode 100644
index 000000000000..1d1cc57cca4b
--- /dev/null
+++ b/sys/contrib/ia64/libuwx/src/uwx_self_info.h
@@ -0,0 +1,44 @@
+/*
+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
+ );
diff --git a/sys/contrib/ia64/libuwx/src/uwx_step.c b/sys/contrib/ia64/libuwx/src/uwx_step.c
index 4e447399477f..e20c7c2a0fb6 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_step.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_step.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -66,7 +66,7 @@ int uwx_lookupip_hook(int request, uint64_t ip, intptr_t tok, uint64_t **vecp,
/* uwx_get_frame_info: Gets unwind info for current frame */
-static
+
int uwx_get_frame_info(struct uwx_env *env)
{
int i;
@@ -77,14 +77,18 @@ int uwx_get_frame_info(struct uwx_env *env)
uint64_t *uvec;
uint64_t *rstate;
struct uwx_utable_entry uentry;
+ uint64_t uinfop;
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 */
@@ -170,9 +174,12 @@ int uwx_get_frame_info(struct uwx_env *env)
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)
+ if (status == UWX_OK) {
+ env->ptr_size = uentry.ptr_size;
+ env->code_start = uentry.code_start;
status = uwx_decode_uinfo(env, &uentry, &rstate);
- else if (status == UWX_ERR_NOUENTRY)
+ }
+ if (status == UWX_ERR_NOUENTRY || status == UWX_ERR_NOUDESC)
status = uwx_default_rstate(env, &rstate);
if (status == UWX_OK)
env->rstate = rstate;
@@ -182,6 +189,7 @@ int uwx_get_frame_info(struct uwx_env *env)
/* 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;
@@ -190,26 +198,35 @@ int uwx_get_frame_info(struct uwx_env *env)
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 *)(uvec[i+1]));
+ uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
break;
case UWX_KEY_FUNC:
env->function_name =
- uwx_alloc_str(env, (char *)(uvec[i+1]));
+ 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;
}
@@ -291,7 +308,104 @@ int uwx_restore_markers(struct uwx_env *env)
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;
+ 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;
+ }
+
+ *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,
@@ -303,7 +417,7 @@ int uwx_get_sym_info(
int cbstatus;
uint64_t ip;
uint64_t *uvec;
- uint64_t uvecout[2];
+ uint64_t uvecout[UVECSIZE];
int i;
if (env == 0)
@@ -336,11 +450,11 @@ int uwx_get_sym_info(
switch ((int)uvec[i]) {
case UWX_KEY_MODULE:
env->module_name =
- uwx_alloc_str(env, (char *)(uvec[i+1]));
+ uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
break;
case UWX_KEY_FUNC:
env->function_name =
- uwx_alloc_str(env, (char *)(uvec[i+1]));
+ uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
break;
case UWX_KEY_FUNCSTART:
env->function_offset = ip - uvec[i+1];
@@ -572,13 +686,16 @@ int uwx_decode_uvec(struct uwx_env *env, uint64_t *uvec, uint64_t **rstate)
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 *)(uvec[i+1]));
+ uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
break;
case UWX_KEY_FUNC:
env->function_name =
- uwx_alloc_str(env, (char *)(uvec[i+1]));
+ uwx_alloc_str(env, (char *)(intptr_t)(uvec[i+1]));
break;
case UWX_KEY_FUNCSTART:
env->function_offset = env->remapped_ip - uvec[i+1];
@@ -597,7 +714,8 @@ int uwx_decode_uvec(struct uwx_env *env, uint64_t *uvec, uint64_t **rstate)
(env->remote? \
(*env->copyin)(UWX_COPYIN_MSTACK, (dest), (src), \
DWORDSZ, env->cb_token) : \
- (*(uint64_t *)(dest) = *(uint64_t *)(src), DWORDSZ) )
+ (*(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)
@@ -644,9 +762,10 @@ int uwx_restore_reg(struct uwx_env *env, uint64_t rstate,
(env->remote? \
(*env->copyin)(UWX_COPYIN_MSTACK, (dest), (src), \
2*DWORDSZ, env->cb_token) : \
- (*(uint64_t *)(dest) = *(uint64_t *)(src), \
- *(uint64_t *)((dest)+8) = *(uint64_t *)((src)+8), \
- 2*DWORDSZ) )
+ (*(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)
diff --git a/sys/contrib/ia64/libuwx/src/uwx_step.h b/sys/contrib/ia64/libuwx/src/uwx_step.h
index 4c51e9b4ad4c..157395f7dd1f 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_step.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_step.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -25,6 +25,4 @@ 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);
diff --git a/sys/contrib/ia64/libuwx/src/uwx_str.c b/sys/contrib/ia64/libuwx/src/uwx_str.c
index e8da35e51690..fb9e08dadf40 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_str.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_str.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -22,15 +22,11 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <string.h>
+
#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
*
@@ -46,21 +42,16 @@ static struct uwx_str_pool uwx_str_pool;
*/
-int uwx_init_str_pool(struct uwx_env *env)
+int uwx_init_str_pool(struct uwx_env *env, struct uwx_str_pool *pool)
{
- if (env->allocate_cb == 0)
- env->string_pool = (struct uwx_str_pool *)
- malloc(sizeof(struct uwx_str_pool));
- else
- env->string_pool = (struct uwx_str_pool *)
- (*env->allocate_cb)(sizeof(struct uwx_str_pool));
-
- if (env->string_pool == 0)
+ if (pool == 0)
return UWX_ERR_NOMEM;
- env->string_pool->next = 0;
- env->string_pool->size = STRPOOLSIZE;
- env->string_pool->used = 0;
+ pool->next = 0;
+ pool->size = STRPOOLSIZE;
+ pool->used = 0;
+
+ env->string_pool = pool;
return UWX_OK;
}
@@ -70,7 +61,11 @@ void uwx_free_str_pool(struct uwx_env *env)
struct uwx_str_pool *pool;
struct uwx_str_pool *next;
- for (pool = env->string_pool; pool != 0; 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);
diff --git a/sys/contrib/ia64/libuwx/src/uwx_str.h b/sys/contrib/ia64/libuwx/src/uwx_str.h
index f55340e53e8c..5e85d6af6085 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_str.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_str.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -22,7 +22,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
-#define STRPOOLSIZE 400
+#define STRPOOLSIZE (400-sizeof(void *)-2*sizeof(int))
struct uwx_str_pool {
struct uwx_str_pool *next;
@@ -31,7 +31,7 @@ struct uwx_str_pool {
char pool[STRPOOLSIZE];
};
-extern int uwx_init_str_pool(struct uwx_env *env);
+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);
diff --git a/sys/contrib/ia64/libuwx/src/uwx_swap.c b/sys/contrib/ia64/libuwx/src/uwx_swap.c
index 19d57bd3f67d..591739367514 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_swap.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_swap.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
diff --git a/sys/contrib/ia64/libuwx/src/uwx_swap.h b/sys/contrib/ia64/libuwx/src/uwx_swap.h
index 1eb24d4c2c24..70d921c9a217 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_swap.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_swap.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
diff --git a/sys/contrib/ia64/libuwx/src/uwx_symbols.c b/sys/contrib/ia64/libuwx/src/uwx_symbols.c
new file mode 100644
index 000000000000..b91c2db72eed
--- /dev/null
+++ b/sys/contrib/ia64/libuwx/src/uwx_symbols.c
@@ -0,0 +1,850 @@
+/*
+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;
+}
diff --git a/sys/contrib/ia64/libuwx/src/uwx_symbols.h b/sys/contrib/ia64/libuwx/src/uwx_symbols.h
new file mode 100644
index 000000000000..83b0bfef24cc
--- /dev/null
+++ b/sys/contrib/ia64/libuwx/src/uwx_symbols.h
@@ -0,0 +1,38 @@
+/*
+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);
diff --git a/sys/contrib/ia64/libuwx/src/uwx_trace.c b/sys/contrib/ia64/libuwx/src/uwx_trace.c
index 11c3db6cf1a1..10ab55d39f2b 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_trace.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_trace.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -23,12 +23,11 @@ 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;
@@ -36,7 +35,7 @@ void uwx_trace_init(struct uwx_env *env)
tstr = getenv("UWX_TRACE");
if (tstr != NULL) {
while (*tstr != '\0') {
- switch (*tstr) {
+ 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;
@@ -46,9 +45,6 @@ void uwx_trace_init(struct uwx_env *env)
case 'C': env->trace |= UWX_TRACE_COPYIN; break;
case 'L': env->trace |= UWX_TRACE_LOOKUPIP; break;
case '?':
-#ifdef _KERNEL
- printf("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");
@@ -59,9 +55,7 @@ void uwx_trace_init(struct uwx_env *env)
fprintf(stderr, " C: copyin callback\n");
fprintf(stderr, " L: lookup ip callback\n");
exit(1);
-#endif
}
- tstr++;
}
}
}
@@ -84,37 +78,37 @@ void uwx_dump_rstate(int regid, uint64_t rstate)
if (rstate == UWX_DISP_NONE)
return;
- printf(" %-7s", uwx_sb_rnames[regid]);
+ fprintf(stderr, " %-7s", uwx_sb_rnames[regid]);
switch (UWX_GET_DISP_CODE(rstate)) {
case UWX_DISP_NONE:
- printf(" unchanged\n");
+ fprintf(stderr, " unchanged\n");
break;
case UWX_DISP_SPPLUS(0):
- printf(" SP + %d\n", (int)rstate & ~0x07);
+ fprintf(stderr, " SP + %d\n", (int)rstate & ~0x07);
break;
case UWX_DISP_SPREL(0):
- printf(" [SP + %d]\n", (int)rstate & ~0x07);
+ fprintf(stderr, " [SP + %d]\n", (int)rstate & ~0x07);
break;
case UWX_DISP_PSPREL(0):
- printf(" [PSP + 16 - %d]\n", (int)rstate & ~0x07);
+ 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)
- printf(" [AR.PFS]\n");
+ fprintf(stderr, " AR.PFS\n");
else if (reg == UWX_REG_AR_UNAT)
- printf(" [AR.UNAT]\n");
+ fprintf(stderr, " AR.UNAT\n");
else if (reg >= UWX_REG_GR(0) && reg < UWX_REG_GR(128))
- printf(" [GR%d]\n", reg - UWX_REG_GR(0));
+ fprintf(stderr, " GR%d\n", reg - UWX_REG_GR(0));
else if (reg >= UWX_REG_FR(0) && reg < UWX_REG_FR(128))
- printf(" [FR%d]\n", reg - UWX_REG_FR(0));
+ fprintf(stderr, " FR%d\n", reg - UWX_REG_FR(0));
else if (reg >= UWX_REG_BR(0) && reg < UWX_REG_BR(8))
- printf(" [BR%d]\n", reg - UWX_REG_BR(0));
+ fprintf(stderr, " BR%d\n", reg - UWX_REG_BR(0));
else
- printf(" [reg %d]\n", reg);
+ fprintf(stderr, " <reg %d>\n", reg);
break;
default:
- printf(" <%08llx>\n", (unsigned long long)rstate);
+ fprintf(stderr, " <%08x>\n", rstate);
break;
}
}
@@ -129,15 +123,35 @@ void uwx_dump_scoreboard(
int i;
if (rhdr->is_prologue)
- printf(" Prologue region (start = %d, length = %d)\n",
+ fprintf(stderr, " Prologue region (start = %d, length = %d)\n",
(int)cur_slot, (int)rhdr->rlen);
else
- printf(" Body region (start = %d, length = %d, ecount = %d)\n",
+ fprintf(stderr, " Body region (start = %d, length = %d, ecount = %d)\n",
cur_slot, (int)rhdr->rlen, rhdr->ecount);
if (ip_slot < rhdr->rlen)
- printf(" IP is in this region (offset = %d)\n", ip_slot);
+ 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]);
}
-#endif /* UWX_TRACE_ENABLE */
+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, " %08lx", *uinfo++);
+ ulen -= WORDSZ;
+ }
+ fprintf(stderr, "\n");
+ }
+}
diff --git a/sys/contrib/ia64/libuwx/src/uwx_trace.h b/sys/contrib/ia64/libuwx/src/uwx_trace.h
index 38a2e9dbb9c8..741b6d1aee12 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_trace.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_trace.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -50,138 +50,146 @@ extern void uwx_dump_scoreboard(
#define TRACE_B_REUSE(id) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_alloc_scoreboard: reuse id %d\n", (id));
+ 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) \
- printf("uwx_alloc_scoreboard: alloc id %d\n", (id));
+ fprintf(stderr, "uwx_alloc_scoreboard: alloc id %d\n", (id));
#define TRACE_B_POP(id) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_pop_scoreboards: free id %d\n", (id));
+ fprintf(stderr, "uwx_pop_scoreboards: free id %d\n", (id));
#define TRACE_B_LABEL(label) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_label_scoreboard: label %d\n", (label));
+ fprintf(stderr, "uwx_label_scoreboard: label %d\n", (label));
#define TRACE_B_LABEL_COPY(id) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_label_scoreboard: copy id %d\n", (id));
+ fprintf(stderr, "uwx_label_scoreboard: copy id %d\n", (id));
#define TRACE_B_LABEL_REVERSE(back, new) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_label_scoreboard: reverse link %d -> %d\n", \
+ 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) \
- printf("uwx_copy_scoreboard: label %d, cur sb id %d\n", (label), (id));
+ 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) \
- printf("uwx_copy_scoreboard: free id %d\n", (id));
+ fprintf(stderr, "uwx_copy_scoreboard: free id %d\n", (id));
#define TRACE_B_COPY_FOUND(id) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_copy_scoreboard: found id %d\n", (id));
+ fprintf(stderr, "uwx_copy_scoreboard: found id %d\n", (id));
#define TRACE_B_COPY_COPY(id) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_copy_scoreboard: copy id %d\n", (id));
+ fprintf(stderr, "uwx_copy_scoreboard: copy id %d\n", (id));
#define TRACE_B_COPY_REVERSE(back, new) \
if (env->trace & UWX_TRACE_SB) \
- printf("uwx_copy_scoreboard: reverse link %d -> %d\n", \
+ 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) \
- printf("uwx_free_scoreboards: free id %d\n", (id));
+ fprintf(stderr, "uwx_free_scoreboards: free id %d\n", (id));
#define TRACE_I_DECODE_RHDR_1(name, b0) \
if (env->trace & UWX_TRACE_UINFO) \
- printf("uwx_decode_rhdr: %02x %s\n", \
+ 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) \
- printf("uwx_decode_rhdr: %02x %08x %s\n", \
+ 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) \
- printf("uwx_decode_rhdr: %02x %02x %08x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: %02x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: %02x %08x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: %02x %08x %08x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: %02x %02x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: %02x %02x %08x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: %02x %02x %02x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: %02x %02x %02x %02x %s\n", \
+ 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) \
- printf("uwx_decode_prologue: spill base = %08x\n", (int)(spill_base));
+ 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) \
- printf("uwx_decode_prologue: gr_mem_mask = %02x; gr_gr_mask = %02x\n", \
+ 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) \
- printf("uwx_decode_prologue: ngr = %d\n", (ngr));
+ fprintf(stderr, "uwx_decode_prologue: ngr = %d\n", (ngr));
#define TRACE_I_DECODE_BODY_1(name, b0) \
if (env->trace & UWX_TRACE_UINFO) \
- printf("uwx_decode_body: %02x %s\n", \
+ 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) \
- printf("uwx_decode_body: %02x %08x %s\n", \
+ 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) \
- printf("uwx_decode_body: %02x %08x %08x %s\n", \
+ 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) \
- printf("Unwind info block (flags = %08x %08x, ulen = %d)\n", \
+ 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));
+ (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) \
@@ -190,7 +198,7 @@ extern void uwx_dump_scoreboard(
#define TRACE_S_STEP(rstate) \
if (env->trace & UWX_TRACE_STEP) { \
- printf("uwx_restore_markers:\n"); \
+ 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]); \
@@ -198,7 +206,7 @@ extern void uwx_dump_scoreboard(
#define TRACE_S_RESTORE_REG(regname, rstate, val) \
if (env->trace & UWX_TRACE_STEP) \
- printf(" restore %-7s (rstate = %08x %08x) = %08x %08x\n", \
+ fprintf(stderr, " restore %-7s (rstate = %08x %08x) = %08x %08x\n", \
regname, \
(unsigned int) ((rstate) >> 32), \
(unsigned int) (rstate), \
@@ -207,7 +215,7 @@ extern void uwx_dump_scoreboard(
#define TRACE_S_RESTORE_GR(regid, rstate, val) \
if (env->trace & UWX_TRACE_STEP) \
- printf(" restore GR%d (rstate = %08x %08x) = %08x %08x\n", \
+ fprintf(stderr, " restore GR%d (rstate = %08x %08x) = %08x %08x\n", \
(regid) + 4, \
(unsigned int) ((rstate) >> 32), \
(unsigned int) (rstate), \
@@ -216,7 +224,7 @@ extern void uwx_dump_scoreboard(
#define TRACE_S_RESTORE_BR(regid, rstate, val) \
if (env->trace & UWX_TRACE_STEP) \
- printf(" restore BR%d (rstate = %08x %08x) = %08x %08x\n", \
+ fprintf(stderr, " restore BR%d (rstate = %08x %08x) = %08x %08x\n", \
(regid) + 1, \
(unsigned int) ((rstate) >> 32), \
(unsigned int) (rstate), \
@@ -225,7 +233,7 @@ extern void uwx_dump_scoreboard(
#define TRACE_S_RESTORE_FR(regid, rstate, fval) \
if (env->trace & UWX_TRACE_STEP) \
- printf(" restore FR%d (rstate = %08x %08x) = %08x %08x %08x %08x\n", \
+ fprintf(stderr, " restore FR%d (rstate = %08x %08x) = %08x %08x %08x %08x\n", \
(regid) + 1, \
(unsigned int) ((rstate) >> 32), \
(unsigned int) (rstate), \
@@ -236,23 +244,23 @@ extern void uwx_dump_scoreboard(
#define TRACE_T_SEARCH32(ip) \
if (env->trace & UWX_TRACE_UTABLE) \
- printf("uwx_search_utable32 (relative ip = %08x)\n", (ip));
+ 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) \
- printf(" lb/ub = %d/%d, mid = %d, start/end = %08x %08x\n", \
+ 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) \
- printf("uwx_get_reg (gr%d, bsp = %08x %08x)\n", \
+ 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) \
- printf("uwx_get_reg (gr%d, sor = %d, rrb = %d) --> gr%d\n", \
+ fprintf(stderr, "uwx_get_reg (gr%d, sor = %d, rrb = %d) --> gr%d\n", \
(regid) + 32, \
(sor), \
(rrb_gr), \
@@ -260,14 +268,14 @@ extern void uwx_dump_scoreboard(
#define TRACE_SELF_COPYIN4(rem, len, wp) \
if (info->trace & UWX_TRACE_COPYIN) \
- printf("copyin (rem = %08x %08x, len = %d, val = %08x)\n", \
+ 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) \
- printf("copyin (rem = %08x %08x, len = %d, val = %08x %08x)\n", \
+ fprintf(stderr, "copyin (rem = %08x %08x, len = %d, val = %08x %08x)\n", \
(unsigned int) ((rem) >> 32), \
(unsigned int) (rem), \
(len), \
@@ -276,25 +284,28 @@ extern void uwx_dump_scoreboard(
#define TRACE_SELF_LOOKUP(ip) \
if (info->trace & UWX_TRACE_LOOKUPIP) \
- printf("Lookup IP callback: ip = %08x %08x\n", \
+ fprintf(stderr, "Lookup IP callback: ip = %08x %08x\n", \
(unsigned int) ((ip) >> 32), \
(unsigned int) (ip));
-#define TRACE_SELF_LOOKUP_DESC(text_base, unwind_base) \
+#define TRACE_SELF_LOOKUP_DESC(text_base, linkage_ptr, unwind_base) \
if (info->trace & UWX_TRACE_LOOKUPIP) { \
- printf(" text base: %08x %08x\n", \
+ fprintf(stderr, " text base: %08x %08x\n", \
(unsigned int) ((text_base) >> 32), \
(unsigned int) (text_base)); \
- printf(" unwind base: %08x %08x\n", \
+ 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)); \
- printf(" unwind flags: %08x %08x\n", \
+ fprintf(stderr, " unwind flags: %08x %08x\n", \
(unsigned int) ((unwind_base)[0] >> 32), \
(unsigned int) (unwind_base)[0]); \
- printf(" unwind start: %08x %08x\n", \
+ fprintf(stderr, " unwind start: %08x %08x\n", \
(unsigned int) (((text_base)+(unwind_base)[1]) >> 32), \
(unsigned int) ((text_base)+(unwind_base)[1])); \
- printf(" unwind end: %08x %08x\n", \
+ fprintf(stderr, " unwind end: %08x %08x\n", \
(unsigned int) (((text_base)+(unwind_base)[2]) >> 32), \
(unsigned int) ((text_base)+(unwind_base)[2])); \
}
@@ -303,6 +314,7 @@ extern void uwx_dump_scoreboard(
#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)
@@ -344,7 +356,7 @@ extern void uwx_dump_scoreboard(
#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, unwind_base)
+#define TRACE_SELF_LOOKUP_DESC(text_base, linkage_ptr, unwind_base)
#endif /* UWX_TRACE_ENABLE */
diff --git a/sys/contrib/ia64/libuwx/src/uwx_uinfo.c b/sys/contrib/ia64/libuwx/src/uwx_uinfo.c
index bf50d20b04c1..16580174602c 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_uinfo.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_uinfo.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -28,7 +28,6 @@ OTHER DEALINGS IN THE SOFTWARE.
#include "uwx_scoreboard.h"
#include "uwx_bstream.h"
#include "uwx_trace.h"
-#include "uwx_swap.h"
int uwx_count_ones(unsigned int mask);
@@ -49,15 +48,15 @@ int uwx_count_ones(unsigned int mask);
#define COPYIN_UINFO_4(dest, src) \
(env->remote? \
- (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
+ (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
WORDSZ, env->cb_token) : \
- (*(uint32_t *)(dest) = *(uint32_t *)(src), WORDSZ) )
+ (*(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), \
+ (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
DWORDSZ, env->cb_token) : \
- (*(uint64_t *)(dest) = *(uint64_t *)(src), DWORDSZ) )
+ (*(uint64_t *)(intptr_t)(dest) = *(uint64_t *)(intptr_t)(src), DWORDSZ) )
/* uwx_default_rstate: Returns the default register state for a leaf routine */
@@ -121,6 +120,12 @@ int uwx_decode_uinfo(
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. */
@@ -344,9 +349,9 @@ int uwx_decode_prologue(
br_mem_mask = 0;
gr_gr_mask = 0;
br_gr_mask = 0;
- nfr = 0;
- ngr = 0;
- nbr = 0;
+ nfr = 127;
+ ngr = 127;
+ nbr = 127;
spill_base = 0;
/* If prologue_gr header record supplied mask and grsave, */
@@ -453,6 +458,10 @@ int uwx_decode_prologue(
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)
@@ -463,12 +472,12 @@ int uwx_decode_prologue(
TRACE_I_DECODE_PROLOGUE_2("(P3) bsp_gr", b0, b1)
/* Don't track BSP yet */
return UWX_ERR_CANTUNWIND;
- break;
+ /* 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;
+ /* break; */
case 10: /* fpsr_gr */
TRACE_I_DECODE_PROLOGUE_2("(P3) fpsr_gr", b0, b1)
newrstate[SBREG_FPSR] =
@@ -500,6 +509,9 @@ int uwx_decode_prologue(
/* 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)
@@ -669,32 +681,32 @@ int uwx_decode_prologue(
TRACE_I_DECODE_PROLOGUE_2L("(P8) bsp_when", b0, b1, parm1)
/* Don't track BSP yet */
return UWX_ERR_CANTUNWIND;
- break;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* 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;
+ /* break; */
case 13: /* rnat_when */
TRACE_I_DECODE_PROLOGUE_2L("(P8) rnat_when", b0, b1, parm1)
tspill[SBREG_RNAT] = (int) parm1;
@@ -1092,7 +1104,7 @@ int uwx_decode_body(
/* is restored, update the scoreboard entry for PSP */
/* and reset any entries for registers saved in memory. */
- if (ip_slot > t_sp_restore) {
+ 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) ||
diff --git a/sys/contrib/ia64/libuwx/src/uwx_uinfo.h b/sys/contrib/ia64/libuwx/src/uwx_uinfo.h
index bdd05cb6d686..1bb477c4e9b1 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_uinfo.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_uinfo.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
diff --git a/sys/contrib/ia64/libuwx/src/uwx_utable.c b/sys/contrib/ia64/libuwx/src/uwx_utable.c
index bedaab75cd81..4b73d69c55ce 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_utable.c
+++ b/sys/contrib/ia64/libuwx/src/uwx_utable.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -76,15 +76,12 @@ int uwx_search_utable(
/* 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;
- text_base = *uvec++;
+ env->text_base = text_base = *uvec++;
break;
case UWX_KEY_UFLAGS:
unwind_flags = *uvec++;
@@ -97,6 +94,9 @@ int uwx_search_utable(
keys |= 4;
unwind_end = *uvec++;
break;
+ case UWX_KEY_GP:
+ uwx_set_reg(env, UWX_REG_GP, *uvec++);
+ break;
default:
return UWX_ERR_BADKEY;
}
@@ -134,6 +134,8 @@ int uwx_search_utable(
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,
@@ -142,6 +144,7 @@ int uwx_search_utable32(
uint32_t unwind_end,
struct uwx_utable_entry *uentry)
{
+ int status;
int lb;
int ub;
int mid;
@@ -162,13 +165,11 @@ int uwx_search_utable32(
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_start, unwind_start+mid*3*WORDSZ);
len += COPYIN_UINFO_4((char *)&code_end,
- (uintptr_t)(unwind_start+mid*3*WORDSZ+WORDSZ));
+ unwind_start+mid*3*WORDSZ+WORDSZ);
if (len != 2 * WORDSZ)
return UWX_ERR_COPYIN_UTBL;
if (env->byte_swap) {
@@ -186,14 +187,15 @@ int uwx_search_utable32(
if (ub <= lb)
return UWX_ERR_NOUENTRY;
len = COPYIN_UINFO_4((char *)&unwind_info,
- (uintptr_t)(unwind_start+mid*3*WORDSZ+2*WORDSZ));
+ unwind_start+mid*3*WORDSZ+2*WORDSZ);
if (len != WORDSZ)
return UWX_ERR_COPYIN_UTBL;
if (env->byte_swap)
uwx_swap4(&unwind_info);
- uentry->code_start = text_base + code_start;
- uentry->code_end = text_base + code_end;
- uentry->unwind_info = text_base + 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;
}
@@ -202,9 +204,9 @@ int uwx_search_utable32(
#define COPYIN_UINFO_8(dest, src) \
(env->remote? \
- (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
+ (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \
DWORDSZ, env->cb_token) : \
- (*(uint64_t *)(dest) = *(uint64_t *)(src), DWORDSZ) )
+ (*(uint64_t *)(intptr_t)(dest) = *(uint64_t *)(intptr_t)(src), DWORDSZ) )
int uwx_search_utable64(
struct uwx_env *env,
@@ -214,6 +216,7 @@ int uwx_search_utable64(
uint64_t unwind_end,
struct uwx_utable_entry *uentry)
{
+ int status;
int lb;
int ub;
int mid;
@@ -232,7 +235,6 @@ int uwx_search_utable64(
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);
@@ -259,6 +261,7 @@ int uwx_search_utable64(
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;
diff --git a/sys/contrib/ia64/libuwx/src/uwx_utable.h b/sys/contrib/ia64/libuwx/src/uwx_utable.h
index cf81b0761bad..69f1cc7b758b 100644
--- a/sys/contrib/ia64/libuwx/src/uwx_utable.h
+++ b/sys/contrib/ia64/libuwx/src/uwx_utable.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+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
@@ -23,6 +23,7 @@ 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;