@@ -203,55 +203,57 @@ void MMAP::Unmap()
203
203
}
204
204
205
205
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)
207
207
{
208
208
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 ;
253
211
}
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;
255
257
}
256
258
257
259
@@ -482,7 +484,7 @@ VM::~VM()
482
484
}
483
485
484
486
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)
486
488
{
487
489
// The mappings provided for shared caches will always be page aligned.
488
490
// 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
495
497
}
496
498
497
499
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));
499
501
if (m_safe && !inserted)
500
502
{
501
503
BNLogWarn (" Remapping page 0x%zx (f: 0x%zx)" , vm_address, fileoff);
0 commit comments