AutoInUseEnumerator.cpp [plain text]
#include "AutoBlockIterator.h"
#include "AutoDefs.h"
#include "AutoInUseEnumerator.h"
#include "AutoLarge.h"
#include "AutoZone.h"
namespace Auto {
kern_return_t InUseEnumerator::scan() {
usword_t zone_size = Zone::bytes_needed();
Zone *zone = (Zone *)read((void *)_zone_address, zone_size);
if (!zone) return _error;
record((void *)_zone_address, zone_size, MALLOC_ADMIN_REGION_RANGE_TYPE);
PointerList& garbage_list = zone->garbage_list();
record((void*)garbage_list.buffer(), garbage_list.size(), MALLOC_ADMIN_REGION_RANGE_TYPE);
Region *region = zone->region_list();
while (region != NULL) {
Region *regionReader = (Region *)read(region, Region::bytes_needed());
if (!regionReader) return _error;
record(region, Region::bytes_needed(), MALLOC_ADMIN_REGION_RANGE_TYPE);
record(regionReader->address(), regionReader->size(), MALLOC_PTR_REGION_RANGE_TYPE);
if (_type_mask & (MALLOC_ADMIN_REGION_RANGE_TYPE | MALLOC_PTR_IN_USE_RANGE_TYPE)) {
SubzoneRangeIterator iterator(regionReader->subzone_range());
while (Subzone *subzone = iterator.next()) {
Subzone *subzoneReader = (Subzone *)read(subzone, sizeof(Subzone));
record(subzone, subzoneReader->base_data_size(), MALLOC_ADMIN_REGION_RANGE_TYPE);
if (_type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
subzoneReader = (Subzone *)read(subzone, subzoneReader->base_data_size());
usword_t n = subzoneReader->allocation_limit();
MemoryReader reader(_task, _reader);
for (usword_t q = 0; q < n; q = subzoneReader->next_quantum(q, reader)) {
if (!subzoneReader->is_free(q)) {
record(subzoneReader->quantum_address(q), subzoneReader->size(q), MALLOC_PTR_IN_USE_RANGE_TYPE);
}
}
}
}
}
for (Large *large = zone->large_list(); large; large = large->next()) {
record(large, sizeof(Large), MALLOC_ADMIN_REGION_RANGE_TYPE);
Large *largeReader = (Large *)read(large, sizeof(Large));
record(largeReader->address(), largeReader->size(), MALLOC_PTR_IN_USE_RANGE_TYPE);
record(displace(large, sizeof(Large) + largeReader->size()), largeReader->vm_size() - (sizeof(Large) + largeReader->size()), MALLOC_ADMIN_REGION_RANGE_TYPE);
large = largeReader;
}
region = regionReader->next();
}
return KERN_SUCCESS;
}
};