
程序代码:
#include <stdio.h>
#include <string.h>
#define MAX_BUFFER_LEN  4096    /* max line length */
#define INSN_NUM  3             /* the number of entry and retw insns */
/* specify insns which need to be consider */
const char *insns[INSN_NUM] = {
    "entry",
    "retw",
    "retw.n"
};
/* record current status */
static int sequence = 0;                   /* the sequence of access specify function */
static int status = 0, laststatus = 0;     /* entry: +1, retw: -1 */
int main(int argc, char **argv)
{
    char linebuf[MAX_BUFFER_LEN];             /* record line info */
    char functionAddr[16] = {"0x20000000"};   /* record function address string */
    unsigned int enableprint = 0;
    if (argc != 2 ) {
        fprintf(stderr, "usage  : <tracefile> <functionAddrStr>\n");
        fprintf(stderr, "example: xtensa_assemble_trace 0x20000000\n");
        return -1;
    }
    FILE *fp = fopen(argv[1], "r");
    // FILE *fp = fopen("assemble_trace.txt", "r");
    if (!fp) {
        fprintf(stderr, "cannot open %s\n", argv[1]);
        return -1;
    }
   
    memset(functionAddr, 0, sizeof(functionAddr));
    memcpy(functionAddr, argv[2], sizeof(functionAddr));
    while(fgets(linebuf, MAX_BUFFER_LEN, fp)) {
       
        unsigned int i = 0;
        unsigned int statusflag = 0;
        /* only check the call address when the statusflag =0 to avoid recursive call*/
        if (enableprint == 0) {
            if (strstr(linebuf, "call") && strstr(linebuf, functionAddr))
                enableprint = 1;        /* enable to print the content */
        } else {
         
            /* check there is entry or retw insns */
            for (i=0; i<INSN_NUM; i++) {
                if (strstr(linebuf, insns[i])) {
                    statusflag = 1;        /* exist entry or retw insns */
                    break;
                }
            }
            /* update the status , no need to update if flag == 0 */
            if (statusflag == 1)
            {
                switch(i) {
                case 0: status += 1; break; /* entry: +1 */
                case 1:                     /* retw: -1 */
                case 2: status -= 1; break; /* retw.n: -1 */
                default: printf("error flag status\n"); return -1;
                }
               
                /* check current status */
                // printf("current status = %d\n", status);
                if ( status < 0 ) {
                    printf("error status value\n");
                    return -1;
                }
            }
           
        }
        
        if ( (status != 0) || (laststatus != 0) ) {
            printf("%s\n", linebuf);
        }
       
        if ( (status == 0) && (laststatus == 1) )
           enableprint = 0;
        laststatus = status;  /* make sure print the last retw insn */
    }
   
    return 0;
   
}
/*  trace file format:
    call8  0x10000000
    entry   a1,320
    {  /"dd1" /ds  /#dsd
    s32i    a6,a1,112
    nop      \//dd
    movi    a6,0
    }
    call8  0x20000000
    entry   a1,320
    {  /"dd2" /ds  /#dsd
    s32i    a6,a1,112
    nop      \//dd
    movi    a6,0
    }
    retw
    {  /"dd3" /ds  /#dsd
    s32i    a6,a1,112
    nop      \//dd
    movi    a6,0
    }
    retw.n
    {  /"dd4" /ds  /#dsd
    s32i    a6,a1,112
    nop      \//dd
    movi    a6,0
    }
*/