Skip to content

Commit 28aef35

Browse files
WeiN76LQh0cyn
authored andcommitted
[SharedCache] Improve the types for m_exportInfos
This commit changes 2 things; 1. `m_exportInfos` is now a map where its values are also a map rather than a vector of pairs. The reason for this is that `SharedCache::FindSymbolAtAddrAndApplyToAddr` is a hot path which does by far the most accesses to `m_exportInfos`. In that function it must find the correct symbol for a given address so a map lookup will be much quicker than iterating a vector. The other use cases of `m_exportInfos` would prefer a vector but they are executed very infrequently. 2. The symbols are stored in `m_exportInfos` as references to the `Symbol` type. This makes more sense because otherwise there is a lot of time spent converting to and from a `Symbol` type and a pair of `BNSymbolType` + a `std::string`.
1 parent e90a08f commit 28aef35

File tree

2 files changed

+49
-54
lines changed

2 files changed

+49
-54
lines changed

view/sharedcache/core/SharedCache.cpp

Lines changed: 47 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ int count_trailing_zeros(uint64_t value) {
5757

5858
struct SharedCache::State
5959
{
60-
std::unordered_map<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>>
60+
std::unordered_map<uint64_t, std::unordered_map<uint64_t, Ref<Symbol>>>
6161
exportInfos;
6262
std::unordered_map<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>>
6363
symbolInfos;
@@ -2668,31 +2668,31 @@ void SharedCache::InitializeHeader(
26682668
auto symbols = GetExportListForHeader(header, [&]() {
26692669
return vm->MappingAtAddress(header.linkeditSegment.vmaddr).first.fileAccessor->lock();
26702670
});
2671-
for (const auto& symbol : symbols)
2671+
for (const auto& symPair : symbols)
26722672
{
2673-
auto bnSymbol = new Symbol(symbol.second.first, symbol.second.second, symbol.first);
26742673
if (typeLib)
26752674
{
2676-
auto type = m_dscView->ImportTypeLibraryObject(typeLib, {symbol.second.second});
2675+
auto type = m_dscView->ImportTypeLibraryObject(typeLib, symPair.second->GetRawName());
26772676

26782677
if (type)
26792678
{
2680-
view->DefineAutoSymbolAndVariableOrFunction(view->GetDefaultPlatform(), bnSymbol, type);
2679+
view->DefineAutoSymbolAndVariableOrFunction(view->GetDefaultPlatform(), symPair.second, type);
26812680
}
26822681
else
2683-
view->DefineAutoSymbol(bnSymbol);
2682+
view->DefineAutoSymbol(symPair.second);
26842683

2685-
if (view->GetAnalysisFunction(view->GetDefaultPlatform(), symbol.first))
2684+
if (view->GetAnalysisFunction(view->GetDefaultPlatform(), symPair.first))
26862685
{
2687-
auto func = view->GetAnalysisFunction(view->GetDefaultPlatform(), symbol.first);
2688-
if (symbol.second.second == "_objc_msgSend")
2686+
auto func = view->GetAnalysisFunction(view->GetDefaultPlatform(), symPair.first);
2687+
auto name = symPair.second->GetFullName();
2688+
if (name == "_objc_msgSend")
26892689
{
26902690
func->SetHasVariableArguments(false);
26912691
}
2692-
else if (symbol.second.second.find("_objc_retain_x") != std::string::npos || symbol.second.second.find("_objc_release_x") != std::string::npos)
2692+
else if (name.find("_objc_retain_x") != std::string::npos || name.find("_objc_release_x") != std::string::npos)
26932693
{
2694-
auto x = symbol.second.second.rfind("x");
2695-
auto num = symbol.second.second.substr(x + 1);
2694+
auto x = name.rfind("x");
2695+
auto num = name.substr(x + 1);
26962696

26972697
std::vector<BinaryNinja::FunctionParameter> callTypeParams;
26982698
auto cc = m_dscView->GetDefaultArchitecture()->GetCallingConventionByName("apple-arm64-objc-fast-arc-" + num);
@@ -2705,7 +2705,7 @@ void SharedCache::InitializeHeader(
27052705
}
27062706
}
27072707
else
2708-
view->DefineAutoSymbol(bnSymbol);
2708+
view->DefineAutoSymbol(symPair.second);
27092709
}
27102710
}
27112711
view->EndBulkModifySymbols();
@@ -2808,7 +2808,7 @@ std::vector<Ref<Symbol>> SharedCache::ParseExportTrie(std::shared_ptr<MMappedFil
28082808
}
28092809

28102810

2811-
std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> SharedCache::GetExportListForHeader(SharedCacheMachOHeader header, std::function<std::shared_ptr<MMappedFileAccessor>()> provideLinkeditFile, bool* didModifyExportList)
2811+
std::unordered_map<uint64_t, Ref<Symbol>> SharedCache::GetExportListForHeader(SharedCacheMachOHeader header, std::function<std::shared_ptr<MMappedFileAccessor>()> provideLinkeditFile, bool* didModifyExportList)
28122812
{
28132813
if (auto it = m_state->exportInfos.find(header.textBase); it != m_state->exportInfos.end())
28142814
{
@@ -2824,14 +2824,14 @@ std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> SharedCac
28242824
{
28252825
if (didModifyExportList)
28262826
*didModifyExportList = false;
2827-
return std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>();
2827+
return std::unordered_map<uint64_t, Ref<Symbol>>();
28282828
}
28292829

28302830
auto exportList = SharedCache::ParseExportTrie(linkeditFile, header);
2831-
std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> exportMapping(exportList.size());
2831+
std::unordered_map<uint64_t, Ref<Symbol>> exportMapping(exportList.size());
28322832
for (const auto& sym : exportList)
28332833
{
2834-
exportMapping.push_back({sym->GetAddress(), {sym->GetType(), sym->GetRawName()}});
2834+
exportMapping[sym->GetAddress()] = sym;
28352835
}
28362836
m_state->exportInfos[header.textBase] = exportMapping;
28372837
if (didModifyExportList)
@@ -2874,9 +2874,9 @@ std::vector<std::pair<std::string, Ref<Symbol>>> SharedCache::LoadAllSymbolsAndW
28742874
return std::shared_ptr<MMappedFileAccessor>(nullptr);
28752875
}
28762876
}, &doSave);
2877-
for (const auto& sym : exportList)
2877+
for (const auto& symPair : exportList)
28782878
{
2879-
symbols.push_back({img.installName, new Symbol(sym.second.first, sym.second.second, sym.first)});
2879+
symbols.push_back({img.installName, symPair.second});
28802880
}
28812881
}
28822882

@@ -2978,35 +2978,31 @@ void SharedCache::FindSymbolAtAddrAndApplyToAddr(
29782978
auto typeLib = TypeLibraryForImage(header->installName);
29792979
id = m_dscView->BeginUndoActions();
29802980
m_dscView->BeginBulkModifySymbols();
2981-
for (const auto& sym : exportList)
2981+
if (auto it = exportList.find(symbolLocation); it != exportList.end())
29822982
{
2983-
if (sym.first == symbolLocation)
2983+
if (auto func = m_dscView->GetAnalysisFunction(m_dscView->GetDefaultPlatform(), targetLocation))
29842984
{
2985-
if (auto func = m_dscView->GetAnalysisFunction(m_dscView->GetDefaultPlatform(), targetLocation))
2986-
{
2987-
m_dscView->DefineUserSymbol(
2988-
new Symbol(FunctionSymbol, prefix + sym.second.second, targetLocation));
2985+
m_dscView->DefineUserSymbol(
2986+
new Symbol(FunctionSymbol, prefix + it->second->GetFullName(), targetLocation));
29892987

2990-
if (typeLib)
2991-
if (auto type = m_dscView->ImportTypeLibraryObject(typeLib, {sym.second.second}))
2992-
func->SetUserType(type);
2993-
}
2994-
else
2995-
{
2996-
m_dscView->DefineUserSymbol(
2997-
new Symbol(sym.second.first, prefix + sym.second.second, targetLocation));
2988+
if (typeLib)
2989+
if (auto type = m_dscView->ImportTypeLibraryObject(typeLib, {it->second->GetFullName()}))
2990+
func->SetUserType(type);
2991+
}
2992+
else
2993+
{
2994+
m_dscView->DefineUserSymbol(
2995+
new Symbol(it->second->GetType(), prefix + it->second->GetFullName(), targetLocation));
29982996

2999-
if (typeLib)
3000-
if (auto type = m_dscView->ImportTypeLibraryObject(typeLib, {sym.second.second}))
3001-
m_dscView->DefineUserDataVariable(targetLocation, type);
3002-
}
3003-
if (triggerReanalysis)
3004-
{
3005-
auto func = m_dscView->GetAnalysisFunction(m_dscView->GetDefaultPlatform(), targetLocation);
3006-
if (func)
3007-
func->Reanalyze();
3008-
}
3009-
break;
2997+
if (typeLib)
2998+
if (auto type = m_dscView->ImportTypeLibraryObject(typeLib, {it->second->GetFullName()}))
2999+
m_dscView->DefineUserDataVariable(targetLocation, type);
3000+
}
3001+
if (triggerReanalysis)
3002+
{
3003+
auto func = m_dscView->GetAnalysisFunction(m_dscView->GetDefaultPlatform(), targetLocation);
3004+
if (func)
3005+
func->Reanalyze();
30103006
}
30113007
}
30123008
m_dscView->EndBulkModifySymbols();
@@ -3474,8 +3470,8 @@ void SharedCache::Store(SerializationContext& context) const
34743470
{
34753471
context.writer.StartObject();
34763472
Serialize(context, "key", pair2.first);
3477-
Serialize(context, "val1", pair2.second.first);
3478-
Serialize(context, "val2", pair2.second.second);
3473+
Serialize(context, "val1", pair2.second->GetType());
3474+
Serialize(context, "val2", pair2.second->GetRawName());
34793475
context.writer.EndObject();
34803476
}
34813477
context.writer.EndArray();
@@ -3546,12 +3542,13 @@ void SharedCache::Load(DeserializationContext& context)
35463542

35473543
for (const auto& obj1 : context.doc["exportInfos"].GetArray())
35483544
{
3549-
std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> innerVec;
3545+
std::unordered_map<uint64_t, Ref<Symbol>> innerVec;
35503546
for (const auto& obj2 : obj1["value"].GetArray())
35513547
{
3552-
std::pair<BNSymbolType, std::string> innerPair = {
3553-
(BNSymbolType)obj2["val1"].GetUint64(), obj2["val2"].GetString()};
3554-
innerVec.push_back({obj2["key"].GetUint64(), innerPair});
3548+
std::string raw = obj2["val2"].GetString();
3549+
uint64_t addr = obj2["key"].GetUint64();
3550+
innerVec[addr] = new Symbol(BNCreateSymbol((BNSymbolType)obj2["val1"].GetUint64(), raw.c_str(),
3551+
raw.c_str(), raw.c_str(), addr, NoBinding, nullptr, 0));
35553552
}
35563553

35573554
MutableState().exportInfos[obj1["key"].GetUint64()] = std::move(innerVec);

view/sharedcache/core/SharedCache.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ namespace SharedCacheCore {
567567

568568
struct ViewSpecificState;
569569

570+
570571
private:
571572
Ref<Logger> m_logger;
572573
/* VIEW STATE BEGIN -- SERIALIZE ALL OF THIS AND STORE IT IN RAW VIEW */
@@ -641,10 +642,7 @@ namespace SharedCacheCore {
641642
const uint8_t *end, const uint8_t* current, uint64_t textBase, const std::string& currentText);
642643
std::vector<Ref<Symbol>> ParseExportTrie(
643644
std::shared_ptr<MMappedFileAccessor> linkeditFile, const SharedCacheMachOHeader& header);
644-
645-
std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> GetExportListForHeader(
646-
SharedCacheMachOHeader header, std::function<std::shared_ptr<MMappedFileAccessor>()> provideLinkeditFile,
647-
bool* didModifyExportList = nullptr);
645+
std::unordered_map<uint64_t, Ref<Symbol>> GetExportListForHeader(SharedCacheMachOHeader header, std::function<std::shared_ptr<MMappedFileAccessor>()> provideLinkeditFile, bool* didModifyExportList = nullptr);
648646

649647
Ref<TypeLibrary> TypeLibraryForImage(const std::string& installName);
650648

0 commit comments

Comments
 (0)