@@ -104,11 +104,13 @@ WeakFileAccessor CacheEntry::GetAccessor() const
104104 return FileAccessorCache::Global ().Open (m_filePath);
105105}
106106
107- SharedCache::SharedCache ()
107+ SharedCache::SharedCache (uint64_t addressSize )
108108{
109+ m_addressSize = addressSize;
109110 m_vm = std::make_shared<VirtualMemory>();
110111}
111112
113+
112114void SharedCache::AddImage (CacheImage image)
113115{
114116 m_images.insert ({image.headerAddress , std::move (image)});
@@ -189,15 +191,14 @@ CacheEntryId SharedCache::AddEntry(CacheEntry entry)
189191 return id;
190192}
191193
192- void SharedCache::ProcessEntries (BinaryView &view )
194+ void SharedCache::ProcessEntries ()
193195{
194196 for (const auto & [id, entry] : m_entries)
195- ProcessEntry (view, entry);
197+ ProcessEntry (entry);
196198}
197199
198- void SharedCache::ProcessEntry (BinaryView &view, const CacheEntry &entry)
200+ void SharedCache::ProcessEntry (const CacheEntry &entry)
199201{
200- uint64_t addrSize = view.GetAddressSize ();
201202 // !!! At this point in time we should have loaded all relevant mappings for the virtual memory.
202203 // If we do not we will throw an exception!
203204 auto machoProcessor = SharedCacheMachOProcessor (m_vm);
@@ -213,7 +214,7 @@ void SharedCache::ProcessEntry(BinaryView &view, const CacheEntry &entry)
213214 // Collect pool addresses as non image memory regions.
214215 for (size_t i = 0 ; i < entryHeader.branchPoolsCount ; i++)
215216 {
216- auto branchPoolAddr = entryHeader.branchPoolsOffset + (i * addrSize );
217+ auto branchPoolAddr = entryHeader.branchPoolsOffset + (i * m_addressSize );
217218 auto header = machoProcessor.ParseHeaderForAddress (branchPoolAddr, " dyld_shared_cache_branch_islands_" + std::to_string (i));
218219 // Stop processing branch pools if a header fails to parse.
219220 if (!header.has_value ())
@@ -274,73 +275,77 @@ void SharedCache::ProcessEntry(BinaryView &view, const CacheEntry &entry)
274275 AddRegion (std::move (stubIslandRegion));
275276 }
276277
277- // Process all images.
278- for (const auto & [imagePath, imageInfo] : entry.GetImages ())
278+ // Process all images. Only for primary right now i guess.
279+ // TODO: When can an entry have images not found in the primary?
280+ if (entry.GetType () == CacheEntryType::Primary)
279281 {
280- auto imageHeader = machoProcessor.ParseHeaderForAddress (imageInfo.address , imagePath);
281- if (!imageHeader.has_value ())
282- continue ;
283-
284- // Add the image to the cache.
285- CacheImage image;
286- image.headerAddress = imageInfo.address ;
287- image.path = imagePath;
288-
289- // Add all image regions.
290- for (const auto & segment : imageHeader->segments )
282+ for (const auto & [imagePath, imageInfo] : entry.GetImages ())
291283 {
292- char segName[17 ];
293- memcpy (segName, segment.segname , 16 );
294- segName[16 ] = 0 ;
284+ auto imageHeader = machoProcessor.ParseHeaderForAddress (imageInfo.address , imagePath);
285+ if (!imageHeader.has_value ())
286+ continue ;
287+
288+ // Add the image to the cache.
289+ CacheImage image;
290+ image.headerAddress = imageInfo.address ;
291+ image.path = imagePath;
295292
296- // Many images include a __LINKEDIT segment that share a single region in the shared cache.
297- // Reuse the same `MemoryRegion` to represent all of these link edit regions.
298- // Check to see if we have a shared region, if so skip it.
299- if (std::string (segName) == " __LINKEDIT" )
293+ // Add all image regions.
294+ for (const auto & segment : imageHeader->segments )
300295 {
301- auto existingRegion = m_regions.find (AddressRange (segment.vmaddr , segment.vmaddr + segment.vmsize ));
302- if (existingRegion != m_regions.end ())
296+ char segName[17 ];
297+ memcpy (segName, segment.segname , 16 );
298+ segName[16 ] = 0 ;
299+
300+ // Many images include a __LINKEDIT segment that share a single region in the shared cache.
301+ // Reuse the same `MemoryRegion` to represent all of these link edit regions.
302+ // Check to see if we have a shared region, if so skip it.
303+ if (std::string (segName) == " __LINKEDIT" )
303304 {
304- image.regionStarts .push_back (existingRegion->second .start );
305- continue ;
305+ // TODO: Loosen this to any shared region?
306+ if (auto linkEditRegion = GetRegionAt (segment.vmaddr ))
307+ {
308+ image.regionStarts .push_back (linkEditRegion->start );
309+ continue ;
310+ }
306311 }
307- }
308312
309- CacheRegion sectionRegion;
310- sectionRegion.type = CacheRegionType::Image;
311- sectionRegion.name = imageHeader->identifierPrefix + " ::" + std::string (segName);
312- sectionRegion.start = segment.vmaddr ;
313- sectionRegion.size = segment.vmsize ;
314- // Associate this region with this image, this makes it easier to identify what image owns this region.
315- sectionRegion.imageStart = image.headerAddress ;
316-
317- uint32_t flags = SegmentFlagsFromMachOProtections (segment.initprot , segment.maxprot );
318- // if we're positive we have an entry point for some reason, force the segment
319- // executable. this helps with kernel images.
320- for (auto &entryPoint : imageHeader->m_entryPoints )
321- if (segment.vmaddr <= entryPoint && (entryPoint < (segment.vmaddr + segment.filesize )))
322- flags |= SegmentExecutable;
323- sectionRegion.flags = static_cast <BNSegmentFlag>(flags);
324-
325- // Add the image section to the cache and also to the image region starts
326- if (AddNonOverlappingRegion (sectionRegion))
327- image.regionStarts .push_back (sectionRegion.start );
328- }
313+ CacheRegion sectionRegion;
314+ sectionRegion.type = CacheRegionType::Image;
315+ sectionRegion.name = imageHeader->identifierPrefix + " ::" + std::string (segName);
316+ sectionRegion.start = segment.vmaddr ;
317+ sectionRegion.size = segment.vmsize ;
318+ // Associate this region with this image, this makes it easier to identify what image owns this region.
319+ sectionRegion.imageStart = image.headerAddress ;
320+
321+ uint32_t flags = SegmentFlagsFromMachOProtections (segment.initprot , segment.maxprot );
322+ // if we're positive we have an entry point for some reason, force the segment
323+ // executable. this helps with kernel images.
324+ for (auto &entryPoint : imageHeader->m_entryPoints )
325+ if (segment.vmaddr <= entryPoint && (entryPoint < (segment.vmaddr + segment.filesize )))
326+ flags |= SegmentExecutable;
327+ sectionRegion.flags = static_cast <BNSegmentFlag>(flags);
328+
329+ // Add the image section to the cache and also to the image region starts
330+ if (AddNonOverlappingRegion (sectionRegion))
331+ image.regionStarts .push_back (sectionRegion.start );
332+ }
329333
330- // TODO: Populating symbols here means that we have all of the symbols for the entire shared cache loaded always.
331- // TODO: We should make this lazy (i.e. GetSymbolAt should check the symbols list then do actual work).
332- // Populate symbols with this images symbols.
333- // std::vector<CacheSymbol> symbols = imageHeader->ReadSymbolTable(view, *m_vm);
334- // AddSymbols(std::move(symbols));
334+ // TODO: Populating symbols here means that we have all of the symbols for the entire shared cache loaded always.
335+ // TODO: We should make this lazy (i.e. GetSymbolAt should check the symbols list then do actual work).
336+ // Populate symbols with this images symbols.
337+ // std::vector<CacheSymbol> symbols = imageHeader->ReadSymbolTable(view, *m_vm);
338+ // AddSymbols(std::move(symbols));
335339
336- // TODO: Should export symbols be put in a different bucket? How are they consumed differently?
337- std::vector<CacheSymbol> exportSymbols = imageHeader->ReadExportSymbolTable (view, *m_vm);
338- AddSymbols (std::move (exportSymbols));
340+ // TODO: Should export symbols be put in a different bucket? How are they consumed differently?
341+ std::vector<CacheSymbol> exportSymbols = imageHeader->ReadExportSymbolTable (*m_vm);
342+ AddSymbols (std::move (exportSymbols));
339343
340- // This is behind a shared pointer as the header itself is very large.
341- image.header = std::make_shared<SharedCacheMachOHeader>(*imageHeader);
344+ // This is behind a shared pointer as the header itself is very large.
345+ image.header = std::make_shared<SharedCacheMachOHeader>(*imageHeader);
342346
343- AddImage (std::move (image));
347+ AddImage (std::move (image));
348+ }
344349 }
345350
346351 // TODO: See note above about slide info writes.
0 commit comments