Esempio n. 1
0
/* prof_FuncConfig():
 * This function builds a table of pdata structures based on the
 * content of the symbol table.
 * It assumes the file is a list of symbols and addresses listed
 * in ascending address order.
 */
void
prof_FuncConfig(void)
{
    int     tfd, i;
    struct  pdata *pfp;
    char    line[80], *space;

    tfd = prof_GetSymFile();
    if(tfd < 0) {
        return;
    }

    prof_FuncTot = 0;
    pfp = prof_FuncTbl;

    while(tfsgetline(tfd,line,sizeof(line)-1)) {
        space = strpbrk(line,"\t ");
        if(!space) {
            continue;
        }
        *space++ = 0;
        while(isspace(*space)) {
            space++;
        }
        pfp->data = strtoul(space,0,0);
        pfp->pcount = 0;
        pfp++;
        prof_FuncTot++;
    }
    tfsclose(tfd,0);

    /* Add one last item to the list so that there is an upper limit for
     * the final symbol in the table:
     */
    pfp->data = 0xffffffff;
    pfp->pcount = 0;

    /* Test to verify that all symbols are in ascending address order...
     */
    for(i=0; i<prof_FuncTot; i++) {
        if(prof_FuncTbl[i].data > prof_FuncTbl[i+1].data) {
            printf("Warning: function addresses not in order\n");
            break;
        }
    }
    prof_FuncTot++;
}
Esempio n. 2
0
int
Strace(int argc,char *argv[])
{
    char	*symfile, fname[64];
    TFILE	*tfp;
    ulong	*framepointer, pc, fp, offset;
    int		tfd, opt, maxdepth, pass, verbose, bullseye;

    tfd = fp = 0;
    maxdepth = 20;
    verbose = 0;
    pc = ExceptionAddr;
    while ((opt=getopt(argc,argv,"d:F:P:rs:v")) != -1) {
        switch(opt) {
        case 'd':
            maxdepth = atoi(optarg);
            break;
        case 'F':
            fp = strtoul(optarg,0,0);
            break;
        case 'P':
            pc = strtoul(optarg,0,0);
            break;
        case 'r':
            showregs();
            break;
        case 'v':
            verbose = 1;
            break;
        default:
            return(0);
        }
    }

    if (!fp)
        getreg("A6", (ulong *)&framepointer);
    else
        framepointer = (ulong *)fp;

    /* Start by detecting the presence of a symbol table file... */
    symfile = getenv("SYMFILE");
    if (!symfile)
        symfile = SYMFILE;

    tfp = tfsstat(symfile);
    if (tfp)  {
        tfd = tfsopen(symfile,TFS_RDONLY,0);
        if (tfd < 0)
            tfp = (TFILE *)0;
    }

    /* Show current position: */
    printf("   0x%08lx",pc);
    if (tfp) {
        AddrToSym(tfd,pc,fname,&offset);
        printf(": %s()",fname);
        if (offset)
            printf(" + 0x%lx",offset);
    }
    putchar('\n');

    /* Now step through the stack frame... */
    bullseye = pass = 0;
    while(maxdepth) {
        /* ADD_CODE_HERE */
    }

    if (!maxdepth)
        printf("Max depth termination\n");

    if (tfp) {
        tfsclose(tfd,0);
    }
    return(0);
}
Esempio n. 3
0
void
tfslog(int action, char *string)
{
#if TFS_CHANGELOG_SIZE
	static char *tfslogaction[] = { "ADD", "DEL", "IPM", " ON", "OFF" };
	
	extern	void *setTmpMaxUsrLvl();
	static	char buf[TFS_CHANGELOG_SIZE];
	TFILE	*tfp;
	int		(*fptr)();
	char	*eol, *eob, *logaction, tbuf[32];
	int		newfsize, fsize, lsize, tfd, err, len, tbuflen;

	switch(action) {
		case TFSLOG_ADD:		/* Return here if logging is off,	*/
		case TFSLOG_DEL:		/* or this tfslog() call is on the 	*/
		case TFSLOG_IPM:		/* TFS_CHANGELOG_FILE itself.		*/
			if (!tfsLogging || !strcmp(string,TFS_CHANGELOG_FILE))
				return;
			break;
		case TFSLOG_ON:
			if (tfsLogging == 1)
				return;
			tfsLogging = 1;
			break;
		case TFSLOG_OFF:
			if (tfsLogging == 0)
				return;
			tfsLogging = 0;
			break;
	}

	/* Force the getUsrLvl() function to return MAX: */
	fptr = (int(*)())setTmpMaxUsrLvl();

	logaction = tfslogaction[action];
	tfp = tfsstat(TFS_CHANGELOG_FILE);
	tfsGetAtime(0,tbuf,sizeof(tbuf));
	tbuflen = strlen(tbuf); 

	if (tfp) {
		tfd = tfsopen(TFS_CHANGELOG_FILE,TFS_RDONLY,0);
		fsize = tfsread(tfd,buf,TFS_CHANGELOG_SIZE);
		tfsclose(tfd,0);

		newfsize = (fsize+strlen(logaction)+strlen(string)+3);
		if (tbuflen)
			newfsize += tbuflen + 3;

		eob = buf + fsize;

		/* If newfsize is greater than the maximum size the file is
		 * allowed to grow, then keep removing the first line
		 * (oldest entry) until new size is within the limit...
		 */
		if (newfsize > TFS_CHANGELOG_SIZE) {
			lsize = 0;
			eol = buf;
			while ((newfsize-lsize) > TFS_CHANGELOG_SIZE) {
				while((*eol != '\r') && (*eol != '\n')) eol++;
				while((*eol == '\r') || (*eol == '\n')) eol++;
				lsize = eol-buf;
			}
			fsize -= lsize;
			newfsize -= lsize;
			eob -= lsize;
			memcpy(buf,eol,fsize);
		}
		if (tbuflen)
			sprintf(eob,"%s: %s @ %s\n",logaction,string,tbuf);
		else
			sprintf(eob,"%s: %s\n",logaction,string);
		err = _tfsunlink(TFS_CHANGELOG_FILE);
		if (err < 0)
			printf("%s: %s\n",TFS_CHANGELOG_FILE,
				(char *)tfsctrl(TFS_ERRMSG,err,0));
		err = tfsadd(TFS_CHANGELOG_FILE,0,"u3",buf,newfsize);
		if (err < 0)
			printf("%s: %s\n",TFS_CHANGELOG_FILE,
				(char *)tfsctrl(TFS_ERRMSG,err,0));
	}
	else {
		if (tbuflen)
			len = sprintf(buf,"%s: %s @ %s\n",logaction,string,tbuf);
		else
			len = sprintf(buf,"%s: %s\n",logaction,string);
		err = tfsadd(TFS_CHANGELOG_FILE,0,"u3",buf,len);
		if (err < 0)
			printf("%s: %s\n",TFS_CHANGELOG_FILE,
				(char *)tfsctrl(TFS_ERRMSG,err,0));
	}

	/* Restore the original getUsrLvl() functionality: */
	clrTmpMaxUsrLvl(fptr);
#endif
}
Esempio n. 4
0
int
Cast(int argc,char *argv[])
{
	long	flags;
	int		opt, tfd, index;
	char	*structtype, *structfile, *tablename, *linkname, *name;

	flags = 0;
	name = (char *)0;
	linkname = (char *)0;
	tablename = (char *)0;
	while((opt=getopt(argc,argv,"apl:n:t:")) != -1) {
		switch(opt) {
		case 'a':
			flags |= STRUCT_SHOWADD;
			break;
		case 'l':
			linkname = optarg;
			break;
		case 'n':
			name = optarg;
			break;
		case 'p':
			flags |= STRUCT_SHOWPAD;
			break;
		case 't':
			tablename = optarg;
			break;
		default:
			return(CMD_PARAM_ERROR);
		}
	}
	if (argc != optind + 2)
		return(CMD_PARAM_ERROR);

	structtype = argv[optind];
	memAddr = strtoul(argv[optind+1],0,0);

	/* Start by detecting the presence of a structure definition file... */
	structfile = getenv("STRUCTFILE");
	if (!structfile)
		structfile = STRUCTFILE;

	tfd = tfsopen(structfile,TFS_RDONLY,0);
	if (tfd < 0) {
		printf("Structure definition file '%s' not found\n",structfile);
		return(CMD_FAILURE);
	}

	index = 0;
	do {
		castDepth = 0;
		showStruct(tfd,flags,structtype,name,linkname);
		index++;
		if (linkname)
			printf("Link #%d = 0x%lx\n",index,memAddr);
		if (tablename || linkname) {
			if (askuser("next?"))  {
				if (tablename)
					printf("%s[%d]:\n",tablename,index);
			}
			else
				tablename = linkname = (char *)0;
		}
	} while(tablename || linkname);

	tfsclose(tfd,0);
	return(CMD_SUCCESS);
}
Esempio n. 5
0
int
tfsscript(TFILE *fp,int verbose)
{
	char	lcpy[CMDLINESIZE], *sv;
	int		tfd, lnsize, lno, verbosity, ignoreerror, cmdstat;

	tfd = tfsopen(fp->name,TFS_RDONLY,0);
	if (tfd < 0)
		return(tfd);

	lno = 0;

	/* If ScriptIsRunning is zero, then we know that this is the top-level
	 * script, so we can initialize state here...
	 */
	if (ScriptIsRunning == 0)
		ReturnToDepth = 0;

	CurrentScriptfdTbl[++ScriptIsRunning] = tfd;
	
	while(1) {
		lno++;
		lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE);
		if (lnsize == 0)	/* end of file? */
			break;
		if (lnsize < 0) {
			printf("tfsscript(): %s\n",tfserrmsg(lnsize));
			break;
		}
		if ((lcpy[0] == '\r') || (lcpy[0] == '\n'))	/* empty line? */
			continue;

		lcpy[lnsize-1] = 0;			/* Remove the newline */

		/* Just in case the goto tag was set outside a script, */
		/* clear it now. */
		if (ScriptGotoTag) {
			free(ScriptGotoTag);
			ScriptGotoTag = (char *)0;
		}

		ScriptExitFlag = 0;

		/* Execute the command line.
		 * If the shell variable "SCRIPTVERBOSE" is set, then enable
		 * verbosity for this command; else use what was passed in 
		 * the parameter list of the function.  Note that the variable
		 * is tested for each command so that verbosity can be enabled
		 * or disabled within a script.
		 * If the command returns a status that indicates that there was
		 * some parameter error, then exit the script.
		 */
		sv = getenv("SCRIPTVERBOSE");
		if (sv)
			verbosity = atoi(sv);
		else
			verbosity = verbose;

		if ((lcpy[0] == '-') || (getenv("SCRIPT_IGNORE_ERROR")))
			ignoreerror = 1;
		else
			ignoreerror = 0;

		if (verbosity)
			printf("[%02d]: %s\n",lno,lcpy);

		cmdstat = tfsDocommand(lcpy[0] == '-' ? lcpy+1 : lcpy, 0);

		if (cmdstat != CMD_SUCCESS) {
			setenv("CMDSTAT","FAIL");
			if (ignoreerror == 0) {
				printf("Terminating script '%s' at line %d\n",
					TFS_NAME(fp),lno);
				ScriptExitFlag = EXIT_SCRIPT;
				break;
			}
		}
		else {
			setenv("CMDSTAT","PASS");
		}

		/* Check for exit flag.  If set, then in addition to terminating the
		 * script, clear the return depth here so that the "missing return"
		 * warning  is not printed.  This is done because there is likely
		 * to be a subroutine with an exit in it and this should not
		 * cause a warning.
		 */
		if (ScriptExitFlag) {
			ReturnToDepth = 0;
			break;
		}

		/* If ScriptGotoTag is set, then attempt to reposition the line 
		 * pointer to the line that contains the tag.
		 */
		if (ScriptGotoTag) {
			int		tlen;

			tlen = strlen(ScriptGotoTag);
			lno = 0;
			tfsseek(tfd,0,TFS_BEGIN);
			while(1) {
				lnsize = tfsgetline(tfd,lcpy,CMDLINESIZE);
				if (lnsize == 0) {
					printf("Tag '%s' not found\n",ScriptGotoTag+2);
					free(ScriptGotoTag);
					ScriptGotoTag = (char *)0;
					tfsclose(tfd,0);
					return(TFS_OKAY);
				}
				lno++;
				if (!strncmp(lcpy,ScriptGotoTag,tlen) &&
					(isspace(lcpy[tlen]) || (lcpy[tlen] == ':'))) {
					free(ScriptGotoTag);
					ScriptGotoTag = (char *)0;
					break;
				}
			}
		}
		/* After each line, poll ethernet interface. */
		pollethernet();
	}
	tfsclose(tfd,0);
	if (ScriptExitFlag & REMOVE_SCRIPT)
		tfsunlink(fp->name);
	if (ScriptIsRunning > 0) {
		ScriptIsRunning--;
		if ((ScriptIsRunning == 0) && (ReturnToDepth != 0)) {
			printf("Error: script is done, but return-to-depth != 0\n");
			printf("(possible gosub/return imbalance)\n");
		}
	}
	else  {
		printf("Script run-depth error\n");
	}

	/* If the EXECUTE_AFTER_EXIT flag is set (by exit -e), then automatically
	 * start up the file specified in ExecuteAfterExit[]...
	 */
	if (ScriptExitFlag & EXECUTE_AFTER_EXIT) {
		char	*argv[2];

		argv[0] = ExecuteAfterExit;
		argv[1] = 0;
		ScriptExitFlag = 0;
		tfsrun(argv,0);
	}

	/* Upon completion of a script, clear the ScriptExitFlag variable so
	 * that it is not accidentally applied to another script that may have
	 * called this script.
	 */
	if ((ScriptExitFlag & EXIT_ALL_SCRIPTS) != EXIT_ALL_SCRIPTS)
		ScriptExitFlag = 0;
	return(TFS_OKAY);
}
Esempio n. 6
0
void
prof_ShowStats(int minhit, int more)
{
    int     i, tfd, linecount;
    ulong   notused;
    char    symname[64];
    struct  pdata   *pptr;

    printf("FuncCount Cfg: tbl: 0x%08lx, size: 0x%x\n",
           (ulong)prof_FuncTbl, prof_FuncTot);
    printf("TidCount  Cfg: tbl: 0x%08lx, size: 0x%x\n",
           (ulong)prof_TidTbl, prof_TidTot);
    printf("PcCount   Cfg: tbl: 0x%08lx, size: 0x%x\n",
           (ulong)prof_PcTbl, prof_PcTot*prof_PcWidth);

    if(prof_CallCnt == 0) {
        printf("No data collected%s",
               prof_Enabled == 0 ? " (profiling disabled)\n" : "\n");
        return;
    }
    linecount = 0;
    tfd = prof_GetSymFile();
    if((prof_FuncTbl) && (prof_FuncTot > 0)) {
        printf("\nFUNC_PROF stats:\n");
        pptr = prof_FuncTbl;
        for(i=0; i<prof_FuncTot; pptr++,i++) {
            if(pptr->pcount < minhit) {
                continue;
            }
            if((tfd < 0) ||
                    (AddrToSym(tfd,pptr->data,symname,&notused) == 0)) {
                printf(" %08lx    :  %d\n",pptr->data,pptr->pcount);
            } else {
                printf(" %-25s:  %d\n",symname,pptr->pcount);
            }
            if((more) && (++linecount >= more)) {
                linecount = 0;
                if(More() == 0) {
                    goto showdone;
                }
            }
        }
    }
    if((prof_TidTbl) && (prof_TidTot > 0)) {
        printf("\nTID_PROF stats:\n");
        pptr = prof_TidTbl;
        for(i=0; i<prof_TidTot; pptr++,i++) {
            if(pptr->pcount < minhit) {
                continue;
            }
            printf(" %08lx    :  %d\n",pptr->data,pptr->pcount);
            if((more) && (++linecount >= more)) {
                linecount = 0;
                if(More() == 0) {
                    goto showdone;
                }
            }
        }
    }
    if(prof_PcTbl) {
        ushort *sp;
        ulong  *lp;

        sp = (ushort *)prof_PcTbl;
        lp = (ulong *)prof_PcTbl;
        printf("\nPC_PROF stats:\n");
        for(i=0; i<prof_PcTot; i++) {
            switch(prof_PcWidth) {
            case 2:
                if(*sp >= minhit) {
                    printf(" %08x    :  %d\n",
                           (int)sp + prof_PcDelta,*sp);
                    linecount++;
                }
                sp++;
                break;
            case 4:
                if(*lp >= minhit) {
                    printf(" %08x    :  %ld\n",
                           (int)lp + prof_PcDelta,*lp);
                    linecount++;
                }
                lp++;
                break;
            }
            if((more) && (linecount >= more)) {
                linecount = 0;
                if(More() == 0) {
                    goto showdone;
                }
            }
        }
    }
showdone:
    putchar('\n');
    if(prof_BadSymCnt) {
        printf("%d out-of-range symbols\n",prof_BadSymCnt);
    }
    if(prof_TidOverflow) {
        printf("%d tid overflow attempts\n",prof_TidOverflow);
    }
    if(prof_PcOORCnt) {
        printf("%d pc out-of-range hits\n",prof_PcOORCnt);
    }
    printf("%d total profiler calls\n",prof_CallCnt);

    if(tfd >= 0) {
        tfsclose(tfd,0);
    }
    return;
}