uwx_trace.c revision 160157
1/*
2Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
3Permission is hereby granted, free of charge, to any person
4obtaining a copy of this software and associated documentation
5files (the "Software"), to deal in the Software without
6restriction, including without limitation the rights to use,
7copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the
9Software is furnished to do so, subject to the following
10conditions:
11
12The above copyright notice and this permission notice shall be
13included in all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23*/
24
25#include "uwx_env.h"
26#include "uwx_utable.h"
27#include "uwx_uinfo.h"
28#include "uwx_scoreboard.h"
29#include "uwx_trace.h"
30
31void uwx_trace_init(struct uwx_env *env)
32{
33    char *tstr;
34
35    tstr = getenv("UWX_TRACE");
36    if (tstr != NULL) {
37	while (*tstr != '\0') {
38	    switch (*tstr++) {
39		case 'i': env->trace |= UWX_TRACE_UINFO; break;
40		case 't': env->trace |= UWX_TRACE_UTABLE; break;
41		case 'b': env->trace |= UWX_TRACE_SB; break;
42		case 'r': env->trace |= UWX_TRACE_RSTATE; break;
43		case 's': env->trace |= UWX_TRACE_STEP; break;
44		case 'c': env->trace |= UWX_TRACE_CONTEXT; break;
45		case 'C': env->trace |= UWX_TRACE_COPYIN; break;
46		case 'L': env->trace |= UWX_TRACE_LOOKUPIP; break;
47		case '?':
48		    fprintf(stderr, "UWX_TRACE flags:\n");
49		    fprintf(stderr, "  i: unwind info\n");
50		    fprintf(stderr, "  t: unwind table searching\n");
51		    fprintf(stderr, "  b: scoreboard management\n");
52		    fprintf(stderr, "  r: register state vector\n");
53		    fprintf(stderr, "  s: step\n");
54		    fprintf(stderr, "  c: context\n");
55		    fprintf(stderr, "  C: copyin callback\n");
56		    fprintf(stderr, "  L: lookup ip callback\n");
57		    exit(1);
58	    }
59	}
60    }
61}
62
63char *uwx_sb_rnames[] = {
64    "RP", "PSP", "PFS",
65    "PREDS", "UNAT", "PRIUNAT", "RNAT", "LC", "FPSR",
66    "GR4", "GR5", "GR6", "GR7",
67    "BR1", "BR2", "BR3", "BR4", "BR5",
68    "FR2", "FR3", "FR4", "FR5",
69    "FR16", "FR17", "FR18", "FR19",
70    "FR20", "FR21", "FR22", "FR23",
71    "FR24", "FR25", "FR26", "FR27",
72    "FR28", "FR29", "FR30", "FR31",
73};
74
75void uwx_dump_rstate(int regid, uint64_t rstate)
76{
77    int reg;
78
79    if (rstate == UWX_DISP_NONE)
80	return;
81    fprintf(stderr, "    %-7s", uwx_sb_rnames[regid]);
82    switch (UWX_GET_DISP_CODE(rstate)) {
83	case UWX_DISP_NONE:
84	    fprintf(stderr, "    unchanged\n");
85	    break;
86	case UWX_DISP_SPPLUS(0):
87	    fprintf(stderr, "    SP + %d\n", (int)rstate & ~0x07);
88	    break;
89	case UWX_DISP_SPREL(0):
90	    fprintf(stderr, "    [SP + %d]\n", (int)rstate & ~0x07);
91	    break;
92	case UWX_DISP_PSPREL(0):
93	    fprintf(stderr, "    [PSP + 16 - %d]\n", (int)rstate & ~0x07);
94	    break;
95	case UWX_DISP_REG(0):
96	    reg = UWX_GET_DISP_REGID(rstate);
97	    if (reg == UWX_REG_AR_PFS)
98		fprintf(stderr, "    AR.PFS\n");
99	    else if (reg == UWX_REG_AR_UNAT)
100		fprintf(stderr, "    AR.UNAT\n");
101	    else if (reg >= UWX_REG_GR(0) && reg < UWX_REG_GR(128))
102		fprintf(stderr, "    GR%d\n", reg - UWX_REG_GR(0));
103	    else if (reg >= UWX_REG_FR(0) && reg < UWX_REG_FR(128))
104		fprintf(stderr, "    FR%d\n", reg - UWX_REG_FR(0));
105	    else if (reg >= UWX_REG_BR(0) && reg < UWX_REG_BR(8))
106		fprintf(stderr, "    BR%d\n", reg - UWX_REG_BR(0));
107	    else
108		fprintf(stderr, "    <reg %d>\n", reg);
109	    break;
110	default:
111	    fprintf(stderr, "    <%08x>\n", rstate);
112	    break;
113    }
114}
115
116void uwx_dump_scoreboard(
117    struct uwx_scoreboard *scoreboard,
118    int nsbreg,
119    struct uwx_rhdr *rhdr,
120    int cur_slot,
121    int ip_slot)
122{
123    int i;
124
125    if (rhdr->is_prologue)
126	fprintf(stderr, "  Prologue region (start = %d, length = %d)\n",
127		    (int)cur_slot, (int)rhdr->rlen);
128    else
129	fprintf(stderr, "  Body region (start = %d, length = %d, ecount = %d)\n",
130		    cur_slot, (int)rhdr->rlen, rhdr->ecount);
131    if (ip_slot < rhdr->rlen)
132	fprintf(stderr, "    IP is in this region (offset = %d)\n", ip_slot);
133    for (i = 0; i < nsbreg; i++)
134	uwx_dump_rstate(i, scoreboard->rstate[i]);
135}
136
137void uwx_dump_uinfo_block(
138	struct uwx_utable_entry *uentry,
139	unsigned int ulen)
140{
141    int i;
142    uint32_t *uinfo = (uint32_t *)(intptr_t)uentry->unwind_info;
143
144    ulen += DWORDSZ;		/* Include unwind info header */
145    if (uentry->unwind_flags & UNWIND_TBL_32BIT) /* and personality routine */
146	ulen += WORDSZ;
147    else
148	ulen += DWORDSZ;
149    while (ulen >= WORDSZ) {
150	fprintf(stderr, "  %08lx: ", (unsigned long)uinfo);
151	for (i = 0; i < 4 * WORDSZ && ulen >= WORDSZ; i += WORDSZ) {
152	    fprintf(stderr, " %08lx", *uinfo++);
153	    ulen -= WORDSZ;
154	}
155	fprintf(stderr, "\n");
156    }
157}
158