void MemoryMap::eraseZeros(size_t minsize) { if (isEmpty()) return; unsigned permissions = READABLE | EXECUTABLE; // access permissions that must be present AddressIntervalSet toRemove; // to save up intervals until we're done iterating AddressInterval zeroInterval; uint8_t buf[8192]; rose_addr_t va = hull().least(); while (AddressInterval accessed = atOrAfter(va).require(permissions).limit(sizeof buf).read(buf)) { for (size_t offset=0; offset<accessed.size(); ++offset) { if (0 == buf[offset]) { if (zeroInterval.isEmpty()) { zeroInterval = AddressInterval(accessed.least()+offset); } else if (zeroInterval.greatest()+1 < offset) { if (zeroInterval.size() >= minsize) toRemove.insert(zeroInterval); zeroInterval = AddressInterval(accessed.least()+offset); } else { zeroInterval = AddressInterval::hull(zeroInterval.least(), zeroInterval.greatest()+1); } } else if (!zeroInterval.isEmpty()) { if (zeroInterval.size() >= minsize) toRemove.insert(zeroInterval); zeroInterval = AddressInterval(); } } if (accessed.greatest() == hull().greatest()) break; // prevent overflow in next statement va += accessed.size(); } if (zeroInterval.size() >= minsize) toRemove.insert(zeroInterval); BOOST_FOREACH (const AddressInterval &interval, toRemove.intervals()) erase(interval); }
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); } }
ExtentMap toExtentMap(const AddressIntervalSet &x) { ExtentMap retval; BOOST_FOREACH (const AddressInterval &interval, x.intervals()) retval.insert(toExtent(interval)); return retval; }