int main (void) { return filesym (0); }
/* * All is there: now use it */ int main(int argc, char **argv) { char s[512]; char *subs=NULL, *savedsubs; int status=0, offset; unsigned int j, k, esp, eip; unsigned int i[16]; /* 8 suffice by now, but who knows... */ char names[16][8], c[20]; /* [8][8] suffice, but who knows */ char *ptr; char *prgname=argv[0]; struct ksym *symlist=NULL; char defaultmap[]="/usr/src/linux/System.map"; char *mapname=defaultmap; if (argc>2) { fprintf(stderr,"%s: Usage: \"%s [mapfile_name] < oops-log\"\n", prgname, prgname); exit(1); } if (argc==2) mapname=argv[1]; fprintf(stderr,"%s: Using %s as map\n", prgname, mapname); symlist = filesym(symlist,NULL,mapname); symlist = filesym(symlist,NULL,"/proc/ksyms"); symlist=fixlist(symlist); /* dumplist(symlist); */ gsymlist=symlist; /* * Ok, the symbol table is there, now get the message */ if (isatty(0)) { fprintf(stderr,"%s: please paste the oops on my stdin\n",prgname); } while (fgets(s,512,stdin)) { if (!subs) { /* nothing yet */ savedsubs = subs = strstr(s,"EIP: "); } switch(status) { case 0: /* not found */ if (!subs) continue; status++; offset=0; esp=0; j=sscanf(subs,"%s %x:[<%x>]",s,&i[0],&i[1]); if (j!=3) { fprintf(stderr,"Wrong \"EIP\" line\n"); continue; } printf("\n%-7s %04x:%08x %s\n",s,i[0],i[1],decode(i[1],0)); eip=i[1]; /* keep to disass */ break; case 1: /* before the stack */ j=sscanf(subs,"%s %x %s %x %s %x %s %x",names[0+offset],i+offset, names[1+offset],i+1+offset,names[2+offset],i+2+offset, names[3+offset],i+3+offset); if (j==8 && strlen(names[0])==4) { /* registers */ /* * The problem with registers is that I need "esp" * first, on order to refer registers to the stack. * So, I save them, and decode later on */ if ( (ptr=strstr(subs,"esp:")) ) { sscanf(ptr,"%*s %x",&esp); } if (esp) { /* decode only when they can be ref'd to stack */ for (j=0; j<4+offset; j++) printf("%s %08x %s\n",names[j],i[j],decode(i[j],esp)); offset=0; } else { offset+=4; /* next time, write after these ones */ } continue; } else if (strncmp(subs,"Stack: ",7)) { printf("%s",subs); continue; } else { status++; offset=0; subs+=6; /* skip the string, and fall through */ } case 2: /* stack and trace*/ if (strncmp(subs,"Call Trace",4) != 0) { k=sscanf(subs,"%x %x %x %x %x %x %x %x",i,i+1,i+2,i+3, i+4,i+5,i+6,i+7); if (k<=0) { fprintf(stderr,"Bad stack line (%i items)\n",j); } else { for (j=0; j<k; j++) printf("esp+%02x: %08x %s\n",(offset+j)*4,i[j], decode(i[j],esp)); } if (!offset) subs = savedsubs; /* restore */ offset+=8; continue; } /* call trace */ status++; offset=0; subs+=12; /* skip the string, and fall through */ case 3: /* the trace */ if (strncmp(subs,"Code",4)) { k=sscanf(subs," [<%x>] [<%x>] [<%x>] [<%x>] " "[<%x>] [<%x>] [<%x>] [<%x>]",i,i+1,i+2,i+3, i+4,i+5,i+6,i+7); if (k==0) { fprintf(stderr,"Bad trace line %s(no add found)\n",subs); } else { for (j=0; j<k; j++) printf("Trace: %08x %s\n", i[j], decode(i[j],esp)); } subs = savedsubs; /* restore */ continue; } /* the code */ ptr = subs+5; /* skip "Code:" */ for (j=0; j<20; j++) { long l=strtol(ptr,&ptr,16); c[j]=(char)l; } disass(c, eip, esp); esp=0; status=0; subs=NULL; /* ready for another oops */ } } return 0; }