static void
showStats(const std::string &label1, const FunctionByAddress &code1, const FunctionByAddress &data1,
          const std::string &label2, const FunctionByAddress &code2, const FunctionByAddress &data2) {

    AddressIntervalSet code1set(code1), code2set(code2);

    std::ostream &out = std::cout;
    std::pair<size_t, size_t> widths(std::max(size_t(20), label1.size()), std::max(size_t(20), label2.size()));
    show(out, widths, "",                   label1,         label2);

    show(out, widths, "bytes disassembled", code1set.size(),   code2set.size());
    show(out, widths, "intervals disassembled", code1set.nIntervals(), code2set.nIntervals());

    AddressIntervalSet bytesInCommon = code1set & code2set;
    show(out, widths, "bytes in common", bytesInCommon.size(), bytesInCommon.size());
    show(out, widths, "bytes in only one", (code1set-code2set).size(), (code2set-code1set).size());

    AddressIntervalSet functions1, functions2;          // could use std::set, but we want set-theoretic operators
    BOOST_FOREACH (const FunctionByAddress::Value &va, code1.values())
        functions1.insert(va);
    BOOST_FOREACH (const FunctionByAddress::Value &va, code2.values())
        functions2.insert(va);
    show(out, widths, "number of functions", functions1.size(), functions2.size());

    AddressIntervalSet functionsInCommon = functions1 & functions2;
    show(out, widths, "functions in common", functionsInCommon.size(), functionsInCommon.size());
    show(out, widths, "functions in only one", (functions1-functions2).size(), (functions2-functions1).size());
}
Exemple #2
0
void
SgAsmGenericFile::dump(FILE *f) const
{
    fprintf(f, "Encoding: %s\n", get_data_converter() ? escapeString(get_data_converter()->name()).c_str() : "none");

    SgAsmGenericSectionPtrList sections = get_sections();
    if (sections.size()==0) {
        fprintf(f, "No sections defined for file.\n");
        return;
    }

    /* Sort sections by offset (lowest to highest), then size (largest to smallest but zero-sized entries first) */
    for (size_t i = 1; i < sections.size(); i++) {
        for (size_t j=0; j<i; j++) {
            if (sections[j]->get_offset() == sections[i]->get_offset()) {
                rose_addr_t size_i = sections[i]->get_size();
                if (0==size_i) size_i = ~(rose_addr_t)0;
                rose_addr_t size_j = sections[j]->get_size();
                if (0==size_j) size_j = ~(rose_addr_t)0;
                if (size_j < size_i) {
                    SgAsmGenericSection *x = sections[j];
                    sections[j] = sections[i];
                    sections[i] = x;
                }
            } else if (sections[j]->get_offset() > sections[i]->get_offset()) {
                SgAsmGenericSection *x = sections[j];
                sections[j] = sections[i];
                sections[i] = x;
            }
        }
    }

    /* Print results */
    fprintf(f, "File sections:\n");
    fprintf(f, "  Flg File-Addr  File-Size  File-End    Base-VA    Start-RVA  Virt-Size  End-RVA    Perm  ID Name\n");
    fprintf(f, "  --- ---------- ---------- ----------  ---------- ---------- ---------- ---------- ---- --- -----------------\n");
    rose_addr_t high_water = 0;
    for (size_t i=0; i<sections.size(); i++) {
        SgAsmGenericSection *section = sections[i];

        /* Does section overlap with any other (before or after)? */
        char overlap[4] = "   "; /* status characters: overlap prior, overlap subsequent, hole */
        for (size_t j=0; overlap[0]==' ' && j<i; j++) {
            if (sections[j]->get_offset()+sections[j]->get_size() > section->get_offset()) {
                overlap[0] = '<';
            }
        }
        for (size_t j=i+1; overlap[1]==' ' && j<sections.size(); j++) {
            if (section->get_offset()+section->get_size() > sections[j]->get_offset()) {
                overlap[1] = '>';
            }
        }

        /* Is there a hole before section[i]? */
        if (high_water < section->get_offset()) {
            overlap[2] = 'H'; /* truly unaccounted region of the file */
        } else if (i>0 && sections[i-1]->get_offset()+sections[i-1]->get_size() < section->get_offset()) {
            overlap[2] = 'h'; /* unaccounted only if overlaps are not allowed */
        }
        high_water = std::max(high_water, section->get_offset() + section->get_size());
        fprintf(f, "  %3s", overlap);

        /* File addresses */
        fprintf(f, "%c0x%08" PRIx64 " 0x%08" PRIx64 " 0x%08" PRIx64,
                section->get_file_alignment()==0 || section->get_offset()%section->get_file_alignment()==0?' ':'!',
                section->get_offset(), section->get_size(), section->get_offset()+section->get_size());

        /* Mapped addresses */
        if (section->is_mapped()) {
            fprintf(f, " %c0x%08" PRIx64 " 0x%08" PRIx64 " 0x%08" PRIx64 " 0x%08" PRIx64,
                    (section->get_mapped_alignment()==0 ||
                     section->get_mapped_preferred_rva()%section->get_mapped_alignment()==0?' ':'!'),
                    section->get_base_va(), section->get_mapped_preferred_rva(), section->get_mapped_size(),
                    section->get_mapped_preferred_rva()+section->get_mapped_size());
        } else {
            fprintf(f, " %*s", 4*11, "");
        }

        /* Permissions */
        if (section->is_mapped()) {
            fprintf(f, " %c%c%c ",
                    section->get_mapped_rperm()?'r':'-',
                    section->get_mapped_wperm()?'w':'-',
                    section->get_mapped_xperm()?'x':'-');
        } else {
            fputs("     ", f);
        }

        /* Section ID, name */
        if (section->get_id()>=0) {
            fprintf(f, " %3d", section->get_id());
        } else {
            fputs("    ", f);
        }
        fprintf(f, " %s\n", section->get_name()->get_string(true).c_str());
    }

    char overlap[4] = "   ";
    if (high_water < get_current_size()) {
        overlap[2] = 'H';
    } else if (sections.back()->get_offset() + sections.back()->get_size() < get_current_size()) {
        overlap[2] = 'h';
    }
    fprintf(f, "  %3s 0x%08" PRIx64 "%*s EOF", overlap, get_current_size(), 76, "");
    if (get_current_size()!=p_data.size())
        fprintf(f, " (original EOF was 0x%08zx)", p_data.size());
    if (get_truncate_zeros())
        fputs(" [ztrunc]", f);
    fputc('\n', f);
    fprintf(f, "  --- ---------- ---------- ----------  ---------- ---------- ---------- ---------- ---- --- -----------------\n");

    /* Show what part of the file has not been referenced */
    AddressIntervalSet holes = get_unreferenced_extents();
    if (holes.size()>0) {
        fprintf(f, "These parts of the file have not been referenced during parsing:\n");
        BOOST_FOREACH (const AddressInterval &interval, holes.intervals()) {
            std::ostringstream ss;
            using namespace StringUtility;
            ss <<"    " <<toHex(interval.least()) <<" + " <<toHex(interval.size()) <<" = " <<toHex(interval.greatest()+1) <<"\n";
            fputs(ss.str().c_str(), f);
        }
    }