@@ -18,7 +18,7 @@ bool DxeResolver::resolveProtocolGuid(Ref<Function> func, uint64_t addr, size_t
1818 if (m_view->Read (&guid, *guidDataAddr, 16 ) < 16 )
1919 continue ;
2020
21- auto info = Resolver::resolveProtocolGuid (guid, addr);
21+ auto info = Resolver::resolveProtocolGuid (guid, addr, guidDataAddr );
2222 if (defineGuidDataVariable (*guidDataAddr, info.guidName ))
2323 changed = true ;
2424 }
@@ -46,7 +46,7 @@ bool DxeResolver::resolveProtocolInterfaces(
4646 if (m_view->Read (&guid, *guidDataAddr, 16 ) < 16 )
4747 continue ;
4848
49- auto info = Resolver::resolveProtocolGuid (guid, addr);
49+ auto info = Resolver::resolveProtocolGuid (guid, addr, guidDataAddr );
5050 if (defineGuidDataVariable (*guidDataAddr, info.guidName ))
5151 changed = true ;
5252
@@ -76,14 +76,17 @@ bool DxeResolver::resolveProtocolInterfaceList(Ref<Function> func, uint64_t addr
7676 for (size_t guidParam = firstGuidParam; guidParam + 1 < params.size (); guidParam += 2 )
7777 {
7878 auto guidDataAddr = GetConstantDataAddress (params[guidParam]);
79- if (!guidDataAddr || *guidDataAddr == 0 )
79+ if (!guidDataAddr)
80+ continue ;
81+ // Only a proven null GUID terminates the list; unresolved pairs can precede known ones.
82+ if (*guidDataAddr == 0 )
8083 break ;
8184
8285 EFI_GUID guid;
8386 if (m_view->Read (&guid, *guidDataAddr, 16 ) < 16 )
8487 continue ;
8588
86- auto info = Resolver::resolveProtocolGuid (guid, addr);
89+ auto info = Resolver::resolveProtocolGuid (guid, addr, guidDataAddr );
8790 if (!defineGuidDataVariable (*guidDataAddr, info.guidName ))
8891 continue ;
8992 changed = true ;
@@ -103,6 +106,7 @@ bool DxeResolver::resolveBootServices()
103106 auto refs = m_view->GetCodeReferencesForType (QualifiedName (" EFI_BOOT_SERVICES" ));
104107 // search reference of `EFI_BOOT_SERVICES` so that we can easily parse different services
105108
109+ SortCodeReferences (refs);
106110 for (auto & ref : refs)
107111 {
108112 if (IsCancelled ())
@@ -188,6 +192,7 @@ bool DxeResolver::resolveRuntimeServices()
188192 SetProgressText (" Resolving Runtime Services..." );
189193 auto refs = m_view->GetCodeReferencesForType (QualifiedName (" EFI_RUNTIME_SERVICES" ));
190194
195+ SortCodeReferences (refs);
191196 for (auto & ref : refs)
192197 {
193198 if (IsCancelled ())
@@ -230,6 +235,7 @@ bool DxeResolver::resolveSmmTables(string serviceName, string tableName)
230235 SetProgressText (" Defining MM tables..." );
231236 auto refs = m_view->GetCodeReferencesForType (QualifiedName (serviceName));
232237 // both versions use the same type, so we only need to search for this one
238+ SortCodeReferences (refs);
233239 for (auto & ref : refs)
234240 {
235241 if (IsCancelled ())
@@ -274,8 +280,11 @@ bool DxeResolver::resolveSmmTables(string serviceName, string tableName)
274280 bool ok = m_view->ParseTypeString (tableName, result, errors);
275281 if (!ok)
276282 return false ;
277- m_view->DefineDataVariable (smstAddr.GetValue ().value , result.type );
278- m_view->DefineUserSymbol (new Symbol (DataSymbol, " gMmst" , smstAddr.GetValue ().value ));
283+ auto address = smstAddr.GetValue ().value ;
284+ m_updates.Apply ([&]() {
285+ m_view->DefineDataVariable (address, result.type );
286+ m_view->DefineUserSymbol (new Symbol (DataSymbol, " gMmst" , address));
287+ });
279288 m_view->UpdateAnalysis ();
280289 }
281290 return true ;
@@ -289,6 +298,7 @@ bool DxeResolver::resolveSmmServices()
289298 // These tables have same type information, we can just iterate once
290299 refs.insert (refs.end (), refs_smm.begin (), refs_smm.end ());
291300
301+ SortCodeReferences (refs);
292302 for (auto & ref : refs)
293303 {
294304 if (IsCancelled ())
@@ -345,6 +355,7 @@ bool DxeResolver::resolveSmiHandlers()
345355 refs.insert (refs.end (), refs_smm_sx.begin (), refs_smm_sx.end ());
346356 refs.insert (refs.end (), refs_mm_sx.begin (), refs_mm_sx.end ());
347357
358+ SortCodeReferences (refs);
348359 for (auto & ref : refs)
349360 {
350361 if (IsCancelled ())
@@ -409,13 +420,14 @@ bool DxeResolver::resolveSmiHandlers()
409420 bool ok = m_view->ParseTypeString (handleTypeStr, result, errors);
410421 if (!ok)
411422 return false ;
412- targetFunc->SetUserType (result.type );
413- m_view->DefineUserSymbol (new Symbol (FunctionSymbol, funcName, funcAddr));
423+ m_updates.Apply ([&]() {
424+ targetFunc->SetUserType (result.type );
425+ m_view->DefineUserSymbol (new Symbol (FunctionSymbol, funcName, funcAddr));
426+ });
414427 m_view->UpdateAnalysis ();
415428
416429 // After setting the type, we want to propagate the parameters' type
417- TypePropagation propagator (m_view);
418- propagator.propagateFuncParamTypes (targetFunc);
430+ m_propagation.QueueFunction (targetFunc);
419431 }
420432 }
421433 }
@@ -431,20 +443,7 @@ bool DxeResolver::resolveDxe()
431443 return true ;
432444}
433445
434- bool DxeResolver::resolveSmm ()
435- {
436- if (!resolveSmmTables (" EFI_SMM_GET_SMST_LOCATION2" , " EFI_SMM_SYSTEM_TABLE2*" ))
437- return false ;
438- if (!resolveSmmTables (" EFI_MM_GET_MMST_LOCATION" , " EFI_MM_SYSTEM_TABLE*" ))
439- return false ;
440- if (!resolveSmmServices ())
441- return false ;
442- if (!resolveSmiHandlers ())
443- return false ;
444- return true ;
445- }
446-
447- DxeResolver::DxeResolver (Ref<BinaryView> view, Ref<BackgroundTask> task) : Resolver(view, task)
446+ DxeResolver::DxeResolver (Ref<BinaryView> view, Ref<BackgroundTask> task, TypePropagation& propagation) : Resolver(view, task, propagation)
448447{
449448 initProtocolMapping ();
450449}
0 commit comments