1115013Smarcel/* 2160157SmarcelCopyright (c) 2003-2006 Hewlett-Packard Development Company, L.P. 3121642SmarcelPermission is hereby granted, free of charge, to any person 4121642Smarcelobtaining a copy of this software and associated documentation 5121642Smarcelfiles (the "Software"), to deal in the Software without 6121642Smarcelrestriction, including without limitation the rights to use, 7121642Smarcelcopy, modify, merge, publish, distribute, sublicense, and/or sell 8121642Smarcelcopies of the Software, and to permit persons to whom the 9121642SmarcelSoftware is furnished to do so, subject to the following 10121642Smarcelconditions: 11115013Smarcel 12121642SmarcelThe above copyright notice and this permission notice shall be 13121642Smarcelincluded in all copies or substantial portions of the Software. 14121642Smarcel 15121642SmarcelTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16121642SmarcelEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17121642SmarcelOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18121642SmarcelNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19121642SmarcelHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20121642SmarcelWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21121642SmarcelFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22121642SmarcelOTHER DEALINGS IN THE SOFTWARE. 23121642Smarcel*/ 24121642Smarcel 25115013Smarcel#include "uwx_env.h" 26160157Smarcel#include "uwx_utable.h" 27115013Smarcel#include "uwx_uinfo.h" 28115013Smarcel#include "uwx_scoreboard.h" 29115013Smarcel#include "uwx_trace.h" 30115013Smarcel 31160163Smarcel#ifdef UWX_TRACE_ENABLE 32160163Smarcel 33115013Smarcelvoid uwx_trace_init(struct uwx_env *env) 34115013Smarcel{ 35115013Smarcel char *tstr; 36115013Smarcel 37115013Smarcel tstr = getenv("UWX_TRACE"); 38115013Smarcel if (tstr != NULL) { 39115013Smarcel while (*tstr != '\0') { 40160163Smarcel switch (*tstr) { 41115013Smarcel case 'i': env->trace |= UWX_TRACE_UINFO; break; 42115013Smarcel case 't': env->trace |= UWX_TRACE_UTABLE; break; 43115013Smarcel case 'b': env->trace |= UWX_TRACE_SB; break; 44115013Smarcel case 'r': env->trace |= UWX_TRACE_RSTATE; break; 45115013Smarcel case 's': env->trace |= UWX_TRACE_STEP; break; 46115013Smarcel case 'c': env->trace |= UWX_TRACE_CONTEXT; break; 47115013Smarcel case 'C': env->trace |= UWX_TRACE_COPYIN; break; 48115013Smarcel case 'L': env->trace |= UWX_TRACE_LOOKUPIP; break; 49115013Smarcel case '?': 50160163Smarcel#ifdef _KERNEL 51160163Smarcel fprintf(stderr, "UWX_TRACE flag `%c' unknown.\n", *tstr); 52160163Smarcel#else 53115013Smarcel fprintf(stderr, "UWX_TRACE flags:\n"); 54115013Smarcel fprintf(stderr, " i: unwind info\n"); 55115013Smarcel fprintf(stderr, " t: unwind table searching\n"); 56115013Smarcel fprintf(stderr, " b: scoreboard management\n"); 57115013Smarcel fprintf(stderr, " r: register state vector\n"); 58115013Smarcel fprintf(stderr, " s: step\n"); 59115013Smarcel fprintf(stderr, " c: context\n"); 60115013Smarcel fprintf(stderr, " C: copyin callback\n"); 61115013Smarcel fprintf(stderr, " L: lookup ip callback\n"); 62115013Smarcel exit(1); 63160163Smarcel#endif 64115013Smarcel } 65160163Smarcel tstr++; 66115013Smarcel } 67115013Smarcel } 68115013Smarcel} 69115013Smarcel 70115013Smarcelchar *uwx_sb_rnames[] = { 71115013Smarcel "RP", "PSP", "PFS", 72115013Smarcel "PREDS", "UNAT", "PRIUNAT", "RNAT", "LC", "FPSR", 73115013Smarcel "GR4", "GR5", "GR6", "GR7", 74115013Smarcel "BR1", "BR2", "BR3", "BR4", "BR5", 75115013Smarcel "FR2", "FR3", "FR4", "FR5", 76115013Smarcel "FR16", "FR17", "FR18", "FR19", 77115013Smarcel "FR20", "FR21", "FR22", "FR23", 78115013Smarcel "FR24", "FR25", "FR26", "FR27", 79115013Smarcel "FR28", "FR29", "FR30", "FR31", 80115013Smarcel}; 81115013Smarcel 82115013Smarcelvoid uwx_dump_rstate(int regid, uint64_t rstate) 83115013Smarcel{ 84115013Smarcel int reg; 85115013Smarcel 86115013Smarcel if (rstate == UWX_DISP_NONE) 87115013Smarcel return; 88160157Smarcel fprintf(stderr, " %-7s", uwx_sb_rnames[regid]); 89115013Smarcel switch (UWX_GET_DISP_CODE(rstate)) { 90115013Smarcel case UWX_DISP_NONE: 91160157Smarcel fprintf(stderr, " unchanged\n"); 92115013Smarcel break; 93115013Smarcel case UWX_DISP_SPPLUS(0): 94160157Smarcel fprintf(stderr, " SP + %d\n", (int)rstate & ~0x07); 95115013Smarcel break; 96115013Smarcel case UWX_DISP_SPREL(0): 97160157Smarcel fprintf(stderr, " [SP + %d]\n", (int)rstate & ~0x07); 98115013Smarcel break; 99115013Smarcel case UWX_DISP_PSPREL(0): 100160157Smarcel fprintf(stderr, " [PSP + 16 - %d]\n", (int)rstate & ~0x07); 101115013Smarcel break; 102115013Smarcel case UWX_DISP_REG(0): 103115013Smarcel reg = UWX_GET_DISP_REGID(rstate); 104120925Smarcel if (reg == UWX_REG_AR_PFS) 105160157Smarcel fprintf(stderr, " AR.PFS\n"); 106120925Smarcel else if (reg == UWX_REG_AR_UNAT) 107160157Smarcel fprintf(stderr, " AR.UNAT\n"); 108115013Smarcel else if (reg >= UWX_REG_GR(0) && reg < UWX_REG_GR(128)) 109160157Smarcel fprintf(stderr, " GR%d\n", reg - UWX_REG_GR(0)); 110115013Smarcel else if (reg >= UWX_REG_FR(0) && reg < UWX_REG_FR(128)) 111160157Smarcel fprintf(stderr, " FR%d\n", reg - UWX_REG_FR(0)); 112115013Smarcel else if (reg >= UWX_REG_BR(0) && reg < UWX_REG_BR(8)) 113160157Smarcel fprintf(stderr, " BR%d\n", reg - UWX_REG_BR(0)); 114115013Smarcel else 115160157Smarcel fprintf(stderr, " <reg %d>\n", reg); 116115013Smarcel break; 117115013Smarcel default: 118160163Smarcel fprintf(stderr, " <%08lx>\n", (long)rstate); 119115013Smarcel break; 120115013Smarcel } 121115013Smarcel} 122115013Smarcel 123115013Smarcelvoid uwx_dump_scoreboard( 124115013Smarcel struct uwx_scoreboard *scoreboard, 125115013Smarcel int nsbreg, 126115013Smarcel struct uwx_rhdr *rhdr, 127115013Smarcel int cur_slot, 128115013Smarcel int ip_slot) 129115013Smarcel{ 130115013Smarcel int i; 131115013Smarcel 132115013Smarcel if (rhdr->is_prologue) 133160157Smarcel fprintf(stderr, " Prologue region (start = %d, length = %d)\n", 134115013Smarcel (int)cur_slot, (int)rhdr->rlen); 135115013Smarcel else 136160157Smarcel fprintf(stderr, " Body region (start = %d, length = %d, ecount = %d)\n", 137115013Smarcel cur_slot, (int)rhdr->rlen, rhdr->ecount); 138115013Smarcel if (ip_slot < rhdr->rlen) 139160157Smarcel fprintf(stderr, " IP is in this region (offset = %d)\n", ip_slot); 140115013Smarcel for (i = 0; i < nsbreg; i++) 141115013Smarcel uwx_dump_rstate(i, scoreboard->rstate[i]); 142115013Smarcel} 143115013Smarcel 144160157Smarcelvoid uwx_dump_uinfo_block( 145160157Smarcel struct uwx_utable_entry *uentry, 146160157Smarcel unsigned int ulen) 147160157Smarcel{ 148160157Smarcel int i; 149160157Smarcel uint32_t *uinfo = (uint32_t *)(intptr_t)uentry->unwind_info; 150160157Smarcel 151160157Smarcel ulen += DWORDSZ; /* Include unwind info header */ 152160157Smarcel if (uentry->unwind_flags & UNWIND_TBL_32BIT) /* and personality routine */ 153160157Smarcel ulen += WORDSZ; 154160157Smarcel else 155160157Smarcel ulen += DWORDSZ; 156160157Smarcel while (ulen >= WORDSZ) { 157160157Smarcel fprintf(stderr, " %08lx: ", (unsigned long)uinfo); 158160157Smarcel for (i = 0; i < 4 * WORDSZ && ulen >= WORDSZ; i += WORDSZ) { 159160163Smarcel fprintf(stderr, " %04x", *uinfo++); 160160157Smarcel ulen -= WORDSZ; 161160157Smarcel } 162160157Smarcel fprintf(stderr, "\n"); 163160157Smarcel } 164160157Smarcel} 165160163Smarcel 166160163Smarcel#endif /* UWX_TRACE_ENABLE */ 167