Esempio n. 1
0
int main(int argc, char *argv[])
{
#if defined(USE_DECODE_CACHE)
    out = new std::ofstream("xed-with-cache.out");
#else
    out = new std::ofstream("xed-no-cache.out");
#endif

    if( PIN_Init(argc,argv) )
        return Usage();
    INS_AddInstrumentFunction(Instruction, 0);

    memset(histo,0,sizeof(UINT64)*MAX_BINS);
    /* FIXME: single threaded tests only */
    UINT32 cache_limit = 16*1024;
    xed_decode_cache_initialize(&cache, new xed_decode_cache_entry_t[cache_limit], cache_limit);
    PIN_AddFiniFunction(Fini, 0);
    PIN_StartProgram();    // Never returns
    return 0;
}
void xed_disas_test(xed_disas_info_t* di)
{

    static int first = 1;
#if !defined(XED_ILD_ONLY) && !defined(XED2_PERF_MEASURE)
    xed_uint64_t errors = 0;
#endif
    unsigned int m;
    unsigned char* z;
    unsigned char* zlimit;
    unsigned int length;

    int skipping;
    int last_all_zeros;
    unsigned int i;

    int okay;

    xed_decoded_inst_t xedd;


    xed_uint64_t runtime_instruction_address;

    xed_dot_graph_supp_t* gs = 0;
    xed_bool_t graph_empty = 1;

    //#define     XED_USE_DECODE_CACHE
#if defined(XED_USE_DECODE_CACHE)
    xed_decode_cache_t cache;
    xed_uint32_t n_cache_entries = 16 * 1024;
    xed_decode_cache_entry_t* cache_entries =
        (xed_decode_cache_entry_t*) malloc(n_cache_entries *
                                           sizeof(xed_decode_cache_entry_t));
    xed_decode_cache_initialize(&cache, cache_entries, n_cache_entries);
#endif


    if(di->dot_graph_output)
    {
        xed_syntax_enum_t syntax = XED_SYNTAX_INTEL;
        gs = xed_dot_graph_supp_create(syntax);
    }

    if(first)
    {
        xed_decode_stats_zero(&xed_stats, di);
        first = 0;
    }

    m = di->ninst; // number of things to decode
    z = di->a;

    if(di->runtime_vaddr_disas_start)
        if(di->runtime_vaddr_disas_start > di->runtime_vaddr)
            z = (di->runtime_vaddr_disas_start - di->runtime_vaddr) + di->a;

    zlimit = 0;
    if(di->runtime_vaddr_disas_end)
    {
        if(di->runtime_vaddr_disas_end > di->runtime_vaddr)
            zlimit = (di->runtime_vaddr_disas_end - di->runtime_vaddr) + di->a;
        else  /* end address is before start of this region -- skip it */
            goto finish;
    }


    if(z >= di->q)    /* start pointer  is after end of section */
        goto finish;

    // for skipping long strings of zeros
    skipping = 0;
    last_all_zeros = 0;
    for(i = 0; i < m; i++)
    {
        int ilim, elim;
        if(zlimit && z >= zlimit)
        {
            if(di->xml_format == 0)
                printf("# end of range.\n");
            break;
        }
        if(z >= di->q)
        {
            if(di->xml_format == 0)
#if !defined(XED_ILD_ONLY)
                printf("# end of text section.\n");
#endif
            break;
        }

        /* if we get near the end of the section, clip the itext length */
        ilim = 15;
        elim = di->q - z;
        if(elim < ilim)
            ilim = elim;

        if(CLIENT_VERBOSE3)
        {
            printf("\n==============================================\n");
            printf("Decoding instruction " XED_FMT_U "\n", i);
            printf("==============================================\n");
        }

        // if we get two full things of 0's in a row, start skipping.
        if(all_zeros((xed_uint8_t*) z, ilim))
        {
            if(skipping)
            {
                z = z + ilim;
                continue;
            }
            else if(last_all_zeros)
            {
#if !defined(XED_ILD_ONLY) && !defined(XED2_PERF_MEASURE)
                printf("...\n");
#endif
                z = z + ilim;
                skipping = 1;
                continue;
            }
            else
                last_all_zeros = 1;
        }
        else
        {
            skipping = 0;
            last_all_zeros = 0;
        }

        runtime_instruction_address = ((xed_uint64_t)(z - di->a)) +
                                      di->runtime_vaddr;

        if(CLIENT_VERBOSE3)
        {
            char tbuf[XED_HEX_BUFLEN];
            printf("Runtime Address " XED_FMT_LX , runtime_instruction_address);
            xed_print_hex_line(tbuf, (xed_uint8_t*) z, ilim, XED_HEX_BUFLEN);
            printf(" [%s]\n", tbuf);
        }
        okay = 0;
        length = 0;

        xed_decoded_inst_zero_set_mode(&xedd, di->dstate);
        if(di->late_init)
            (*di->late_init)(&xedd);

        if(di->decode_only)
        {
            xed_uint64_t t1;
            xed_uint64_t t2;
            xed_error_enum_t xed_error = XED_ERROR_NONE;

            t1 = xed_get_time();


#if defined(XED_USE_DECODE_CACHE)
            xed_error = xed_decode_cache(&xedd,
                                         XED_REINTERPRET_CAST(const xed_uint8_t*, z),
                                         ilim,
                                         &cache);
#else
            xed_error = decode_internal(
                            &xedd,
                            XED_REINTERPRET_CAST(const xed_uint8_t*, z),
                            ilim);
#endif
            t2 = xed_get_time();

            okay = (xed_error == XED_ERROR_NONE);
#if defined(PTI_XED_TEST)
            if(okay)
                pti_xed_test(&xedd,
                             XED_REINTERPRET_CAST(const xed_uint8_t*, z),
                             ilim,
                             runtime_instruction_address);
#endif

            xed_decode_stats_reset(&xed_stats, t1, t2);
            length = xed_decoded_inst_get_length(&xedd);

            if(okay && length == 0)
            {
                printf("Zero length on decoded instruction!\n");
                xed_decode_error(runtime_instruction_address,
                                 z - di->a, z, xed_error);
                xedex_derror("Dieing");
            }

            if(di->resync && di->symfn)
            {
                xed_bool_t resync = 0;
                unsigned int x;
                for(x = 1; x < length; x++)
                {

                    char* name = (*di->symfn)(runtime_instruction_address + x,
                                              di->caller_symbol_data);
                    if(name)
                    {
                        char buf[XED_HEX_BUFLEN];
                        /* bad news. We found a symbol in the middle of an
                         * instruction. That probably means decoding is
                         * messed up.  This usually happens because of
                         * data-in the code/text section.  We should reject
                         * the current instruction and pick up at the
                         * symbol address. */
                        printf("ERROR: found symbol in the middle of"
                               " an instruction. Resynchronizing...\n");
                        printf("ERROR: Rejecting: [");
                        xed_print_hex_line(buf, z, x, XED_HEX_BUFLEN);
                        printf("%s]\n", buf);

                        z += x;
                        resync = 1;
                        break;
                    }
                }
                if(resync)
                    continue;
            }

            xed_stats.total_ilen += length;

            //we don't want to print out disassembly with ILD perf
#if !defined(XED_ILD_ONLY) && !defined(XED2_PERF_MEASURE)

            if(okay)
            {
                if(CLIENT_VERBOSE1)
                {
                    char tbuf[XED_TMP_BUF_LEN];
                    xed_decoded_inst_dump(&xedd, tbuf, XED_TMP_BUF_LEN);
                    printf("%s\n", tbuf);
                }
                if(CLIENT_VERBOSE)
                {
                    char buffer[XED_TMP_BUF_LEN];
                    unsigned int dec_len;
                    unsigned int sp;
                    if(di->symfn)
                    {
                        char* name = (*di->symfn)(runtime_instruction_address,
                                                  di->caller_symbol_data);
                        if(name)
                        {
                            if(di->xml_format)
                                printf("\n<SYM>%s</SYM>\n", name);
                            else
                                printf("\nSYM %s:\n", name);
                        }
                    }
                    if(di->xml_format)
                    {
                        printf("<ASMLINE>\n");
                        printf("  <ADDR>" XED_FMT_LX "</ADDR>\n",
                               runtime_instruction_address);
                        printf("  <CATEGORY>%s</CATEGORY>\n",
                               xed_category_enum_t2str(
                                   xed_decoded_inst_get_category(&xedd)));
                        printf("  <EXTENSION>%s</EXTENSION>\n",
                               xed_extension_enum_t2str(
                                   xed_decoded_inst_get_extension(&xedd)));
                        printf("  <ITEXT>");
                        dec_len = xed_decoded_inst_get_length(&xedd);
                        xed_print_hex_line(buffer, (xed_uint8_t*) z,
                                           dec_len, XED_TMP_BUF_LEN);
                        printf("%s</ITEXT>\n", buffer);
                        buffer[0] = 0;
                        disassemble(buffer, XED_TMP_BUF_LEN,
                                    &xedd, runtime_instruction_address,
                                    di->caller_symbol_data);
                        printf("  %s\n", buffer);
                        printf("</ASMLINE>\n");
                    }
                    else
                    {
                        printf("XDIS " XED_FMT_LX ": ",
                               runtime_instruction_address);
#if 0  /* test code for the new API */
                        if(xed_decoded_inst_masked_vector_operation(&xedd))
                            printf("MSK ");
                        else
                            printf("    ");
#endif

                        if(di->ast)
                        {
                            printf("%-6s ",
                                   xed_ast_input_enum_t2str(
                                       classify_avx_sse(&xedd)));
                        }
                        else
                        {
                            printf("%-9s ",
                                   xed_category_enum_t2str(
                                       xed_decoded_inst_get_category(&xedd)));
                            printf("%-6s ",
                                   xed_extension_enum_t2str(
                                       xed_decoded_inst_get_extension(&xedd)));
                        }


                        dec_len = xed_decoded_inst_get_length(&xedd);
                        xed_print_hex_line(buffer, (xed_uint8_t*) z,
                                           dec_len, XED_HEX_BUFLEN);
                        printf("%s", buffer);
                        // pad out the instruction bytes
                        for(sp = dec_len; sp < 12; sp++)
                            printf("  ");
                        printf(" ");
                        buffer[0] = 0;
                        disassemble(buffer, XED_TMP_BUF_LEN,
                                    &xedd,
                                    runtime_instruction_address,
                                    di->caller_symbol_data);
                        printf("%s", buffer);
                        if(gs)
                        {
                            graph_empty = 0;
                            xed_dot_graph_add_instruction(
                                gs,
                                &xedd,
                                runtime_instruction_address,
                                di->caller_symbol_data);
                        }

                        if(di->line_number_info_fn)
                            (*di->line_number_info_fn)(runtime_instruction_address);

                        printf("\n");
                    }
                }
            }
            else
            {
                errors++;
                xed_decode_error(runtime_instruction_address, z - di->a, z,
                                 xed_error);
                // just give a length of 1B to see if we can restart decode...
                length = 1;
            }
        }
#if defined(XED_ENCODER)
        else
        {