At this point all relevant mapping should be loaded in the virtual memory.
| 319 | |
| 320 | // At this point all relevant mapping should be loaded in the virtual memory. |
| 321 | void SharedCache::ProcessEntryRegions(const CacheEntry& entry) |
| 322 | { |
| 323 | const auto& entryHeader = entry.GetHeader(); |
| 324 | |
| 325 | // Collect pool addresses as non image memory regions. |
| 326 | for (size_t i = 0; i < entryHeader.branchPoolsCount; i++) |
| 327 | { |
| 328 | auto branchPoolAddr = entryHeader.branchPoolsOffset + (i * m_vm->GetAddressSize()); |
| 329 | auto header = SharedCacheMachOHeader::ParseHeaderForAddress( |
| 330 | m_vm, branchPoolAddr, "dyld_shared_cache_branch_islands_" + std::to_string(i)); |
| 331 | // Stop processing branch pools if a header fails to parse. |
| 332 | if (!header.has_value()) |
| 333 | break; |
| 334 | |
| 335 | // Gather all non image regions from the branch islands. |
| 336 | for (const auto& segment : header->segments) |
| 337 | { |
| 338 | CacheRegion stubIslandRegion; |
| 339 | stubIslandRegion.start = segment.vmaddr; |
| 340 | stubIslandRegion.size = segment.filesize; |
| 341 | char segName[17]; |
| 342 | memcpy(segName, segment.segname, 16); |
| 343 | segName[16] = 0; |
| 344 | std::string segNameStr = std::string(segName); |
| 345 | stubIslandRegion.name = fmt::format("dyld_shared_cache_branch_islands_{}::{}", i, segNameStr); |
| 346 | stubIslandRegion.flags = static_cast<BNSegmentFlag>(SegmentReadable | SegmentExecutable); |
| 347 | stubIslandRegion.type = CacheRegionType::StubIsland; |
| 348 | |
| 349 | // Add the stub islands to the cache. |
| 350 | AddRegion(std::move(stubIslandRegion)); |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | // Get the mapping. |
| 355 | const auto& entryMappings = entry.GetMappings(); |
| 356 | |
| 357 | // Add the mapping regions for the given entry type. |
| 358 | // By default, we will just add all the mappings as read-write. |
| 359 | switch (entry.GetType()) |
| 360 | { |
| 361 | case CacheEntryType::DyldData: |
| 362 | { |
| 363 | size_t lastMappingIndex = 0; |
| 364 | for (const auto& mapping : entryMappings) |
| 365 | { |
| 366 | CacheRegion mappingRegion; |
| 367 | mappingRegion.start = mapping.address; |
| 368 | mappingRegion.size = mapping.size; |
| 369 | mappingRegion.name = fmt::format("{}::_data_{}", entry.GetFileName(), lastMappingIndex++); |
| 370 | mappingRegion.flags = SegmentReadable; |
| 371 | mappingRegion.type = CacheRegionType::DyldData; |
| 372 | |
| 373 | // Add the dyld data mapping as a region to the cache. |
| 374 | AddRegion(std::move(mappingRegion)); |
| 375 | } |
| 376 | break; |
| 377 | } |
| 378 | case CacheEntryType::Stub: |
no test coverage detected