⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strace_sh2.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
字号:
/* strace.c: * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Note1: the majority of this code was edited with 4-space tabs. *  Note2: as more and more contributions are accepted, the term "author" *         is becoming a mis-representation of credit. * *  Original author:    Ed Sutter *  Email:              esutter@lucent.com *  Phone:              908-582-2351 */#include "config.h"#if INCLUDE_STRACE#include "tfs.h"#include "tfsprivate.h"#include "ctype.h"#include "genlib.h"#include "stddefs.h"#define ADDI_INSTR  0x7f            /* add  #imm,r15 */#define RTS_INSTR   0x000b          /* rts */#define STS_PR_R15  0x4f22          /* sts.l pr,@-r15 */extern  int getreg();extern  int AddrToSym(int,ulong,char *,ulong *);extern  ulong ExceptionAddr;char *StraceHelp[] = {    "Stack trace", "-[d:F:P:rs:]",    " -d #  max depth count (def=20)",    " -F #  specify frame-pointer (don't use content of R1)",    " -P #  specify PC (don't use content of SRR#)",    " -r    dump regs",    0,};intStrace(int argc,char *argv[]){    uchar   *ftext, dlta;    char    *symfile, fname[64];    ulong   *framepointer, pc, fp, offset;    int     fdelta, leaf, tfd, opt, maxdepth, debug;    tfd = fp = debug = 0;    maxdepth = 20;    pc = ExceptionAddr;    while ((opt=getopt(argc,argv,"Dd:F:P:r")) != -1) {        switch(opt) {        case 'D':            debug = 1;            break;        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;        default:            return(0);        }    }        /* Start by detecting the presence of a symbol table file... */    symfile = getenv("SYMFILE");    if (!symfile)        symfile = SYMFILE;    tfd = tfsopen(symfile,TFS_RDONLY,0);    if (tfd < 0) {        printf("Stack trace needs %s file\n",symfile);        return(0);    }    /* Load initial frame pointer: */    if (!fp)        getreg("R14", &framepointer);    else        framepointer = (ulong *)fp;    /* Show current position: */    AddrToSym(tfd,pc,fname,&offset);    printf("   0x%08lx: %s()",pc,fname);    if (offset)        printf(" + 0x%lx",offset);    putchar('\n');    /* Now the tricky stuff...     * If there are no arguments passed to the functions in the stack's     * function nesting, then all we need to do is jump from one frame     * pointer to the next.  Unfortunately, this is not usually the case,     * so we need to figure out how many arguments each function has as we     * are processing the stack trace.  Also, for the first function of the     * nesting, we must determine if it is a leaf function because the frame     * will be a bit different in that case.  In either case, we need to     * be able to take an address in text space, determine what function it     * is, and then determine where the starting address for that function is.     * This is done with the AddrToSym() function.  It takes in an address,     * returns the name of the function as well as the gap between the      * incoming address and the actual starting point of the function's text.     * Point being: without the symbol table, this is likely not to work.     *     * Determining if function is a leaf:     * This is done by searching through the text of the function and     * looking for the "STS.L PR,@-R15" instruction.  If this instruction     * is found prior to the RTS, then we assume the function is NOT a leaf     * because the Procedture Register is being pushed onto the stack     * (meaning that the compiler added the code to prepare for the fact     * that another function may be called from within the current function).     *     * Determining number of arguments:     * Since the arguments passed into a function are placed on the stack     * frame, and the code for a function must be aware of this, we can once     * again, look to the code for hints.  In this case we look for the     * first occurrence of the instruction "ADD #IMM,R15".  This is code     * that adjusts the stack pointer based on the number of arguments passed     * into the function that are on the stack frame.  The value of #IMM is     * what we use to determine the number of arguments.  For example, if     * the instruction is ADD #0xFC,R15 then we know that one argument is      * using stack space.  Similarly "ADD #0xF8,R15" is 2, "ADD #0xF4,R15"     * is 3 and so on.     */    ftext = (uchar *)pc;    ftext -= offset;    leaf = 1;    fdelta = 0;    while((*ftext != ADDI_INSTR) && (*(ushort*)ftext != RTS_INSTR)) {        if (*(ushort *)ftext == STS_PR_R15)            leaf = 0;        ftext+=2;    }    if (*(ushort*)ftext != RTS_INSTR) {        dlta = (int)*(ftext+1);        while(dlta) {            fdelta++;            dlta += 4;        }    }    if (debug) {        printf("                     FRAME_PTR=0x%08lx, DLTA=%d, LEAF=%d\n",            (ulong)framepointer, fdelta, leaf);    }    framepointer += (fdelta+leaf);    /* Now step through the stack frame... */    while(maxdepth) {        if (((int)framepointer & 3) || (!framepointer) || (!*framepointer))            break;        if (debug)            printf("                     FUNC_ADDR=0x%08lx\n",*framepointer);                if (!AddrToSym(tfd,*framepointer,fname,&offset))            break;        printf("   0x%08lx: %s()",*framepointer,fname);        if (offset)            printf(" + 0x%lx",offset);        putchar('\n');        /* See notes above regarding the computation of fdelta... */        fdelta = 0;        ftext = (uchar *)*framepointer;        ftext -= offset;        while((*ftext != ADDI_INSTR) && (*(ushort*)ftext != RTS_INSTR))            ftext+=2;        if (*(ushort*)ftext != RTS_INSTR) {            dlta = (int)*(ftext+1);            while(dlta) {                fdelta++;                dlta += 4;            }        }        if (debug) {            printf("                     FRAME_PTR=0x%08lx, DLTA=%d\n",                (ulong)framepointer, fdelta);        }        framepointer = (ulong *)*(framepointer+1);        framepointer += fdelta;        maxdepth--;    }    if (!maxdepth)        printf("Max depth termination\n");        if (tfd >= 0)        tfsclose(tfd,0);    return(0);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -