uwx_trace.c revision 160158
1250079Scarl/*
2250079ScarlCopyright (c) 2003-2006 Hewlett-Packard Development Company, L.P.
3289542ScemPermission is hereby granted, free of charge, to any person
4250079Scarlobtaining a copy of this software and associated documentation
5250079Scarlfiles (the "Software"), to deal in the Software without
6250079Scarlrestriction, including without limitation the rights to use,
7250079Scarlcopy, modify, merge, publish, distribute, sublicense, and/or sell
8250079Scarlcopies of the Software, and to permit persons to whom the
9250079ScarlSoftware is furnished to do so, subject to the following
10250079Scarlconditions:
11250079Scarl
12250079ScarlThe above copyright notice and this permission notice shall be
13250079Scarlincluded in all copies or substantial portions of the Software.
14250079Scarl
15250079ScarlTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16250079ScarlEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17250079ScarlOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18250079ScarlNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19250079ScarlHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20250079ScarlWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21250079ScarlFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22250079ScarlOTHER DEALINGS IN THE SOFTWARE.
23250079Scarl*/
24250079Scarl
25250079Scarl#include "uwx_env.h"
26250079Scarl#include "uwx_utable.h"
27250079Scarl#include "uwx_uinfo.h"
28250079Scarl#include "uwx_scoreboard.h"
29250079Scarl#include "uwx_trace.h"
30250079Scarl
31250079Scarlvoid uwx_trace_init(struct uwx_env *env)
32250079Scarl{
33250079Scarl    char *tstr;
34250079Scarl
35250079Scarl    tstr = getenv("UWX_TRACE");
36250079Scarl    if (tstr != NULL) {
37250079Scarl	while (*tstr != '\0') {
38250079Scarl	    switch (*tstr++) {
39289207Scem		case 'i': env->trace |= UWX_TRACE_UINFO; break;
40250079Scarl		case 't': env->trace |= UWX_TRACE_UTABLE; break;
41250079Scarl		case 'b': env->trace |= UWX_TRACE_SB; break;
42250079Scarl		case 'r': env->trace |= UWX_TRACE_RSTATE; break;
43250079Scarl		case 's': env->trace |= UWX_TRACE_STEP; break;
44250079Scarl		case 'c': env->trace |= UWX_TRACE_CONTEXT; break;
45250079Scarl		case 'C': env->trace |= UWX_TRACE_COPYIN; break;
46250079Scarl		case 'L': env->trace |= UWX_TRACE_LOOKUPIP; break;
47250079Scarl		case '?':
48250079Scarl		    fprintf(stderr, "UWX_TRACE flags:\n");
49250079Scarl		    fprintf(stderr, "  i: unwind info\n");
50250079Scarl		    fprintf(stderr, "  t: unwind table searching\n");
51250079Scarl		    fprintf(stderr, "  b: scoreboard management\n");
52250079Scarl		    fprintf(stderr, "  r: register state vector\n");
53250079Scarl		    fprintf(stderr, "  s: step\n");
54250079Scarl		    fprintf(stderr, "  c: context\n");
55250079Scarl		    fprintf(stderr, "  C: copyin callback\n");
56250079Scarl		    fprintf(stderr, "  L: lookup ip callback\n");
57250079Scarl		    exit(1);
58250079Scarl	    }
59250079Scarl	}
60250079Scarl    }
61250079Scarl}
62250079Scarl
63289538Scemchar *uwx_sb_rnames[] = {
64250079Scarl    "RP", "PSP", "PFS",
65289539Scem    "PREDS", "UNAT", "PRIUNAT", "RNAT", "LC", "FPSR",
66289539Scem    "GR4", "GR5", "GR6", "GR7",
67250079Scarl    "BR1", "BR2", "BR3", "BR4", "BR5",
68250079Scarl    "FR2", "FR3", "FR4", "FR5",
69250079Scarl    "FR16", "FR17", "FR18", "FR19",
70250079Scarl    "FR20", "FR21", "FR22", "FR23",
71250079Scarl    "FR24", "FR25", "FR26", "FR27",
72250079Scarl    "FR28", "FR29", "FR30", "FR31",
73250079Scarl};
74250079Scarl
75289539Scemvoid uwx_dump_rstate(int regid, uint64_t rstate)
76289539Scem{
77289539Scem    int reg;
78289539Scem
79289539Scem    if (rstate == UWX_DISP_NONE)
80289539Scem	return;
81289539Scem    fprintf(stderr, "    %-7s", uwx_sb_rnames[regid]);
82289539Scem    switch (UWX_GET_DISP_CODE(rstate)) {
83255274Scarl	case UWX_DISP_NONE:
84255274Scarl	    fprintf(stderr, "    unchanged\n");
85255274Scarl	    break;
86255274Scarl	case UWX_DISP_SPPLUS(0):
87250079Scarl	    fprintf(stderr, "    SP + %d\n", (int)rstate & ~0x07);
88250079Scarl	    break;
89255274Scarl	case UWX_DISP_SPREL(0):
90250079Scarl	    fprintf(stderr, "    [SP + %d]\n", (int)rstate & ~0x07);
91289397Scem	    break;
92250079Scarl	case UWX_DISP_PSPREL(0):
93250079Scarl	    fprintf(stderr, "    [PSP + 16 - %d]\n", (int)rstate & ~0x07);
94250079Scarl	    break;
95250079Scarl	case UWX_DISP_REG(0):
96250079Scarl	    reg = UWX_GET_DISP_REGID(rstate);
97250079Scarl	    if (reg == UWX_REG_AR_PFS)
98250079Scarl		fprintf(stderr, "    AR.PFS\n");
99250079Scarl	    else if (reg == UWX_REG_AR_UNAT)
100250079Scarl		fprintf(stderr, "    AR.UNAT\n");
101250079Scarl	    else if (reg >= UWX_REG_GR(0) && reg < UWX_REG_GR(128))
102250079Scarl		fprintf(stderr, "    GR%d\n", reg - UWX_REG_GR(0));
103250079Scarl	    else if (reg >= UWX_REG_FR(0) && reg < UWX_REG_FR(128))
104250079Scarl		fprintf(stderr, "    FR%d\n", reg - UWX_REG_FR(0));
105250079Scarl	    else if (reg >= UWX_REG_BR(0) && reg < UWX_REG_BR(8))
106250079Scarl		fprintf(stderr, "    BR%d\n", reg - UWX_REG_BR(0));
107250079Scarl	    else
108250079Scarl		fprintf(stderr, "    <reg %d>\n", reg);
109250079Scarl	    break;
110250079Scarl	default:
111250079Scarl	    fprintf(stderr, "    <%08x>\n", rstate);
112250079Scarl	    break;
113250079Scarl    }
114250079Scarl}
115289281Scem
116289343Scemvoid uwx_dump_scoreboard(
117250079Scarl    struct uwx_scoreboard *scoreboard,
118250079Scarl    int nsbreg,
119289542Scem    struct uwx_rhdr *rhdr,
120289542Scem    int cur_slot,
121289542Scem    int ip_slot)
122289542Scem{
123289542Scem    int i;
124289542Scem
125289542Scem    if (rhdr->is_prologue)
126289542Scem	fprintf(stderr, "  Prologue region (start = %d, length = %d)\n",
127289542Scem		    (int)cur_slot, (int)rhdr->rlen);
128289542Scem    else
129289542Scem	fprintf(stderr, "  Body region (start = %d, length = %d, ecount = %d)\n",
130289542Scem		    cur_slot, (int)rhdr->rlen, rhdr->ecount);
131289542Scem    if (ip_slot < rhdr->rlen)
132289542Scem	fprintf(stderr, "    IP is in this region (offset = %d)\n", ip_slot);
133289542Scem    for (i = 0; i < nsbreg; i++)
134289542Scem	uwx_dump_rstate(i, scoreboard->rstate[i]);
135289542Scem}
136289542Scem
137289542Scemvoid uwx_dump_uinfo_block(
138289542Scem	struct uwx_utable_entry *uentry,
139289542Scem	unsigned int ulen)
140289542Scem{
141289542Scem    int i;
142289542Scem    uint32_t *uinfo = (uint32_t *)(intptr_t)uentry->unwind_info;
143289542Scem
144289542Scem    ulen += DWORDSZ;		/* Include unwind info header */
145289542Scem    if (uentry->unwind_flags & UNWIND_TBL_32BIT) /* and personality routine */
146250079Scarl	ulen += WORDSZ;
147250079Scarl    else
148250079Scarl	ulen += DWORDSZ;
149255274Scarl    while (ulen >= WORDSZ) {
150250079Scarl	fprintf(stderr, "  %08lx: ", (unsigned long)uinfo);
151250079Scarl	for (i = 0; i < 4 * WORDSZ && ulen >= WORDSZ; i += WORDSZ) {
152250079Scarl	    fprintf(stderr, " %08lx", *uinfo++);
153250079Scarl	    ulen -= WORDSZ;
154250079Scarl	}
155250079Scarl	fprintf(stderr, "\n");
156250079Scarl    }
157250079Scarl}
158250079Scarl