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