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