//! Returns true if the address filter overlaps \a region. bool StExecutableImage::AddressFilter::matchesMemoryRegion(const MemoryRegion ®ion) const { uint32_t firstByte = region.m_address; // first byte occupied by this region uint32_t lastByte = region.endAddress(); // last used byte in this region return (firstByte >= m_fromAddress && firstByte <= m_toAddress) || (lastByte >= m_fromAddress && lastByte <= m_toAddress); }
//! There are several possible cases here: //! - No overlap at all. Nothing is done. //! //! - All of the memory region is matched by the \a filter. The region is //! removed from #StExecutableImage::m_image and its data memory freed. //! //! - The remaining portion of the region is one contiguous chunk. In this //! case, \a region is simply modified. //! //! - The region is split in the middle by the filter. The original \a region //! is modified to match the first remaining chunk. And a new #StExecutableImage::MemoryRegion //! instance is created to hold the other leftover piece. void StExecutableImage::cropRegionToFilter(MemoryRegion ®ion, const AddressFilter &filter) { uint32_t firstByte = region.m_address; // first byte occupied by this region uint32_t lastByte = region.endAddress(); // last used byte in this region // compute new address range uint32_t cropFrom = filter.m_fromAddress; if (cropFrom < firstByte) { cropFrom = firstByte; } uint32_t cropTo = filter.m_toAddress; if (cropTo > lastByte) { cropTo = lastByte; } // is there actually a match? if (cropFrom > filter.m_toAddress || cropTo < filter.m_fromAddress) { // nothing to do, so bail return; } printf("Deleting region 0x%08x-0x%08x\n", cropFrom, cropTo); // handle if the entire region is to be deleted if (cropFrom == firstByte && cropTo == lastByte) { delete[] region.m_data; region.m_data = NULL; m_image.remove(region); } // there is at least a little of the original region remaining uint32_t newLength = cropTo - cropFrom + 1; uint32_t leftoverLength = lastByte - cropTo; uint8_t *oldData = region.m_data; // update the region region.m_address = cropFrom; region.m_length = newLength; // crop data buffer for text regions if (region.m_type == TEXT_REGION && oldData) { region.m_data = new uint8_t[newLength]; memcpy(region.m_data, &oldData[cropFrom - firstByte], newLength); // dispose of old data delete[] oldData; } // create a new region for any part of the original region that was past // the crop to address. this will happen if the filter range falls in the // middle of the region. if (leftoverLength) { MemoryRegion newRegion; newRegion.m_type = region.m_type; newRegion.m_flags = region.m_flags; newRegion.m_address = cropTo + 1; newRegion.m_length = leftoverLength; if (region.m_type == TEXT_REGION && oldData) { newRegion.m_data = new uint8_t[leftoverLength]; memcpy(newRegion.m_data, &oldData[cropTo - firstByte + 1], leftoverLength); } insertOrMergeRegion(newRegion); } }