/** Returns a list of parts of a single section that have been referenced. The offsets are relative to the start of the * section. */ AddressIntervalSet SgAsmGenericSection::get_referenced_extents() const { if (0==get_size()) return AddressIntervalSet(); AddressIntervalSet retval; AddressInterval segment = AddressInterval::baseSize(get_offset(), get_size()); const AddressIntervalSet &fileExtents = get_file()->get_referenced_extents(); BOOST_FOREACH (const AddressInterval &interval, fileExtents.intervals()) { if (segment.isContaining(interval)) { retval.insert(AddressInterval::baseSize(interval.least()-get_offset(), interval.size())); } else if (interval.isLeftOf(segment) || interval.isRightOf(segment)) { // no overlap } else if (interval.isContaining(segment)) { retval.insert(AddressInterval::baseSize(0, get_size())); break; // no point in continuing since we've referenced whole segment now } else if (interval.least() < segment.least()) { retval.insert(AddressInterval::baseSize(0, interval.least()+interval.size()-get_offset())); } else if (interval.greatest() > segment.greatest()) { retval.insert(AddressInterval::baseSize(interval.least()-get_offset(), get_offset()+get_size()-interval.least())); } else { ASSERT_not_reachable("invalid extent overlap category"); } } return retval; }
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); }
/** Obtains the virtual address of the Hint/Name Table. The Hint/Name Table is an implicit table--the PE file format * specification talks about such a table, but it is not actually defined anywhere in the PE file. Instead, various Import * Lookup Table and Import Address Table entries might point to individual Hint/Name pairs, which collectively form an * implicit Hint/Name Table. There is no requirement that the Hint/Name pairs are contiguous in the address space, and indeed * they often are not. Therefore, the only way to describe the location of the Hint/Name Table is by a list of addresses. * * This function will scan this Import Directory's import items, observe which items make references to Hint/Name pairs that * have known addresses, and add those areas of virtual memory to the specified extent map. This function returns the number * of ILT entries that reference a Hint/Name pair. */ size_t SgAsmPEImportDirectory::hintname_table_extent(AddressIntervalSet &extent/*in,out*/) const { size_t retval = 0; const SgAsmPEImportItemPtrList &imports = get_imports()->get_vector(); for (SgAsmPEImportItemPtrList::const_iterator ii=imports.begin(); ii!=imports.end(); ++ii) { SgAsmPEImportItem *import = *ii; if (!import->get_by_ordinal() && import->get_hintname_rva().get_rva()!=0 && import->get_hintname_nalloc()>0) { size_t nbytes = std::min(import->get_hintname_nalloc(), import->hintname_required_size()); extent.insert(AddressInterval::baseSize(import->get_hintname_rva().get_va(), nbytes)); ++retval; } } return retval; }
AddressIntervalSet toAddressIntervalSet(const ExtentMap &x) { AddressIntervalSet retval; for (ExtentMap::const_iterator iter=x.begin(); iter!=x.end(); ++iter) retval.insert(toAddressInterval(iter->first)); return retval; }