@@ -203,55 +203,57 @@ void MMAP::Unmap()
203203}
204204
205205
206- std::shared_ptr<SelfAllocatingWeakPtr<MMappedFileAccessor> > MMappedFileAccessor::Open (BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const uint64_t sessionID, const std::string &path, std::function<void (std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine)
206+ std::shared_ptr<LazyMappedFileAccessor > MMappedFileAccessor::Open (BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const uint64_t sessionID, const std::string &path, std::function<void (std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine)
207207{
208208 std::scoped_lock<std::mutex> lock (fileAccessorsMutex);
209- if (fileAccessors.count (path) == 0 )
210- {
211- auto fileAcccessor = std::shared_ptr<SelfAllocatingWeakPtr<MMappedFileAccessor>>(new SelfAllocatingWeakPtr<MMappedFileAccessor>(
212- // Allocator logic for the SelfAllocatingWeakPtr
213- [path=path, sessionID=sessionID, dscView](){
214- std::unique_lock<std::mutex> _lock (fileAccessorDequeMutex);
215-
216- // Iterate through held references and start removing them until we can get a file pointer
217- // FIXME: This could clear all currently used file pointers and still not get one. FIX!
218- // We should probably use a condition variable here to wait for a file pointer to be released!!!
219- for (auto & [_, fileAccessorDeque] : fileAccessorReferenceHolder)
220- {
221- if (fileAccessorSemaphore.try_acquire ())
222- break ;
223- fileAccessorDeque.pop_front ();
224- }
225-
226- mmapCount++;
227- _lock.unlock ();
228- auto accessor = std::shared_ptr<MMappedFileAccessor>(new MMappedFileAccessor (ResolveFilePath (dscView, path)), [](MMappedFileAccessor* accessor){
229- // worker thread or we can deadlock on exit here.
230- BinaryNinja::WorkerEnqueue ([accessor](){
231- fileAccessorSemaphore.release ();
232- mmapCount--;
233- if (fileAccessors.count (accessor->m_path ))
234- {
235- std::scoped_lock<std::mutex> lock (fileAccessorsMutex);
236- fileAccessors.erase (accessor->m_path );
237- }
238- delete accessor;
239- }, " MMappedFileAccessor Destructor" );
240- });
241- _lock.lock ();
242- // If some background thread has managed to try and open a file when the BV was already closed,
243- // we can still give them the file they want so they dont crash, but as soon as they let go it's gone.
244- if (!blockedSessionIDs.count (sessionID))
245- fileAccessorReferenceHolder[sessionID].push_back (accessor);
246- return accessor;
247- },
248- [postAllocationRoutine=postAllocationRoutine](std::shared_ptr<MMappedFileAccessor> accessor){
249- if (postAllocationRoutine)
250- postAllocationRoutine (accessor);
251- }));
252- fileAccessors.insert_or_assign (path, fileAcccessor);
209+ if (auto it = fileAccessors.find (path); it != fileAccessors.end ()) {
210+ return it->second ;
253211 }
254- return fileAccessors.at (path);
212+
213+ auto fileAcccessor = std::make_shared<LazyMappedFileAccessor>(
214+ path,
215+ // Allocator logic for the SelfAllocatingWeakPtr
216+ [path=path, sessionID=sessionID, dscView](){
217+ std::unique_lock<std::mutex> _lock (fileAccessorDequeMutex);
218+
219+ // Iterate through held references and start removing them until we can get a file pointer
220+ // FIXME: This could clear all currently used file pointers and still not get one. FIX!
221+ // We should probably use a condition variable here to wait for a file pointer to be released!!!
222+ for (auto & [_, fileAccessorDeque] : fileAccessorReferenceHolder)
223+ {
224+ if (fileAccessorSemaphore.try_acquire ())
225+ break ;
226+ fileAccessorDeque.pop_front ();
227+ }
228+
229+ mmapCount++;
230+ _lock.unlock ();
231+ auto accessor = std::shared_ptr<MMappedFileAccessor>(new MMappedFileAccessor (ResolveFilePath (dscView, path)), [](MMappedFileAccessor* accessor){
232+ // worker thread or we can deadlock on exit here.
233+ BinaryNinja::WorkerEnqueue ([accessor](){
234+ fileAccessorSemaphore.release ();
235+ mmapCount--;
236+ if (fileAccessors.count (accessor->m_path ))
237+ {
238+ std::scoped_lock<std::mutex> lock (fileAccessorsMutex);
239+ fileAccessors.erase (accessor->m_path );
240+ }
241+ delete accessor;
242+ }, " MMappedFileAccessor Destructor" );
243+ });
244+ _lock.lock ();
245+ // If some background thread has managed to try and open a file when the BV was already closed,
246+ // we can still give them the file they want so they dont crash, but as soon as they let go it's gone.
247+ if (!blockedSessionIDs.count (sessionID))
248+ fileAccessorReferenceHolder[sessionID].push_back (accessor);
249+ return accessor;
250+ },
251+ [postAllocationRoutine=postAllocationRoutine](std::shared_ptr<MMappedFileAccessor> accessor){
252+ if (postAllocationRoutine)
253+ postAllocationRoutine (std::move (accessor));
254+ });
255+ fileAccessors.insert_or_assign (path, fileAcccessor);
256+ return fileAcccessor;
255257}
256258
257259
@@ -482,7 +484,7 @@ VM::~VM()
482484}
483485
484486
485- void VM::MapPages (BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, uint64_t sessionID, size_t vm_address, size_t fileoff, size_t size, std::string filePath, std::function<void (std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine)
487+ void VM::MapPages (BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, uint64_t sessionID, size_t vm_address, size_t fileoff, size_t size, const std::string& filePath, std::function<void (std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine)
486488{
487489 // The mappings provided for shared caches will always be page aligned.
488490 // We can use this to our advantage and gain considerable performance via page tables.
@@ -495,7 +497,7 @@ void VM::MapPages(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, uint64_t se
495497 }
496498
497499 auto accessor = MMappedFileAccessor::Open (std::move (dscView), sessionID, filePath, postAllocationRoutine);
498- auto [it, inserted] = m_map.insert_or_assign ({vm_address, vm_address + size}, PageMapping (std::move (filePath), std::move ( accessor), fileoff));
500+ auto [it, inserted] = m_map.insert_or_assign ({vm_address, vm_address + size}, PageMapping (std::move (accessor), fileoff));
499501 if (m_safe && !inserted)
500502 {
501503 BNLogWarn (" Remapping page 0x%zx (f: 0x%zx)" , vm_address, fileoff);
0 commit comments