# endif // SANITIZER_FUCHSIA
-void ScanRootRegion(Frontier *frontier, const Region &root_region,
- uptr region_begin, uptr region_end, bool is_readable) {
+bool HasRootRegions() { return !root_regions.empty(); }
+
+static void ScanRootRegion(Frontier *frontier, const Region &root_region,
+ uptr region_begin, uptr region_end,
+ bool is_readable) {
uptr intersection_begin = Max(root_region.begin, region_begin);
uptr intersection_end = Min(region_end, root_region.end);
if (intersection_begin >= intersection_end)
kReachable);
}
+void ScanRootRegions(Frontier *frontier,
+ const InternalMmapVectorNoCtor<Region> &mapped_regions) {
+ if (!flags()->use_root_regions || mapped_regions.empty())
+ return;
+
+ for (const auto &m : mapped_regions)
+ for (const auto &r : root_regions)
+ ScanRootRegion(frontier, r, m.begin, m.end, true);
+}
+
static void ProcessRootRegion(Frontier *frontier, const Region &root_region) {
MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
MemoryMappedSegment segment;
bool success = false;
};
-InternalMmapVectorNoCtor<Region> const *GetRootRegions();
-void ScanRootRegion(Frontier *frontier, const Region ®ion, uptr region_begin,
- uptr region_end, bool is_readable);
+bool HasRootRegions();
+void ScanRootRegions(Frontier *frontier,
+ const InternalMmapVectorNoCtor<Region> ®ion);
// Run stoptheworld while holding any platform-specific locks, as well as the
// allocator and thread registry locks.
void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
vm_address_t address = 0;
kern_return_t err = KERN_SUCCESS;
- InternalMmapVectorNoCtor<Region> const *root_regions = GetRootRegions();
+ InternalMmapVectorNoCtor<Region> mapped_regions;
+ bool use_root_regions = flags()->use_root_regions && HasRootRegions();
RegionScanState scan_state;
while (err == KERN_SUCCESS) {
// Recursing over the full memory map is very slow, break out
// early if we don't need the full iteration.
- if (scan_state.seen_regions == SeenRegion::All &&
- !(flags()->use_root_regions && root_regions->size() > 0)) {
+ if (scan_state.seen_regions == SeenRegion::All && !use_root_regions) {
break;
}
//
// TODO(fjricci) - remove this once sanitizer_procmaps_mac has the same
// behavior as sanitizer_procmaps_linux and traverses all memory regions
- if (flags()->use_root_regions) {
- for (uptr i = 0; i < root_regions->size(); i++) {
- ScanRootRegion(frontier, (*root_regions)[i], address, end_address,
- info.protection & kProtectionRead);
- }
- }
+ if (use_root_regions && (info.protection & kProtectionRead))
+ mapped_regions.push_back({address, end_address});
address = end_address;
}
+ ScanRootRegions(frontier, mapped_regions);
}
// On darwin, we can intercept _exit gracefully, and return a failing exit code