Skip to content

Commit 833375c

Browse files
committed
[SharedCache] Prevent some unneeded copies when processing
Also swapped out CacheEntry::m_images to a vector as its never actually used as a lookup
1 parent c22d54c commit 833375c

File tree

4 files changed

+33
-33
lines changed

4 files changed

+33
-33
lines changed

view/sharedcache/core/MachO.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -556,17 +556,17 @@ std::vector<CacheSymbol> SharedCacheMachOHeader::ReadSymbolTable(BinaryView& vie
556556
return symbolList;
557557
}
558558

559-
std::optional<CacheSymbol> SharedCacheMachOHeader::AddExportTerminalSymbol(
560-
const std::string& symbolName, const uint8_t* current, const uint8_t* end) const
559+
bool SharedCacheMachOHeader::AddExportTerminalSymbol(
560+
std::vector<CacheSymbol>& symbols, const std::string& symbolName, const uint8_t *current, const uint8_t *end) const
561561
{
562562
uint64_t symbolFlags = readValidULEB128(current, end);
563563
if (symbolFlags & EXPORT_SYMBOL_FLAGS_REEXPORT)
564-
return std::nullopt;
564+
return false;
565565

566566
uint64_t imageOffset = readValidULEB128(current, end);
567567
uint64_t symbolAddress = textBase + imageOffset;
568568
if (symbolName.empty() || symbolAddress == 0)
569-
return std::nullopt;
569+
return false;
570570

571571
// Tries to get the symbol type based off the section containing it.
572572
auto sectionSymbolType = [&]() -> BNSymbolType {
@@ -595,13 +595,17 @@ std::optional<CacheSymbol> SharedCacheMachOHeader::AddExportTerminalSymbol(
595595
{
596596
case EXPORT_SYMBOL_FLAGS_KIND_REGULAR:
597597
case EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL:
598-
return CacheSymbol(sectionSymbolType(), symbolAddress, symbolName);
598+
symbols.emplace_back(sectionSymbolType(), symbolAddress, symbolName);
599+
break;
599600
case EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE:
600-
return CacheSymbol(DataSymbol, symbolAddress, symbolName);
601+
symbols.emplace_back(DataSymbol, symbolAddress, symbolName);
602+
break;
601603
default:
602604
LogWarn("Unhandled export symbol kind: %llx", symbolFlags & EXPORT_SYMBOL_FLAGS_KIND_MASK);
603-
return std::nullopt;
605+
return false;
604606
}
607+
608+
return true;
605609
}
606610

607611
// TODO: This is like 90% of the runtime.
@@ -616,12 +620,7 @@ bool SharedCacheMachOHeader::ProcessLinkEditTrie(std::vector<CacheSymbol>& symbo
616620

617621
// The terminal is an export symbol.
618622
if (terminalSize != 0)
619-
{
620-
// Add the export symbol is applicable.
621-
auto symbol = AddExportTerminalSymbol(currentText, current, end);
622-
if (symbol.has_value())
623-
symbols.push_back(*symbol);
624-
}
623+
AddExportTerminalSymbol(symbols, currentText, current, end);
625624

626625
// TODO: Make this look better
627626
current = child;

view/sharedcache/core/MachO.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ struct SharedCacheMachOHeader
6464
// TODO: Replace view with address size?
6565
std::vector<CacheSymbol> ReadSymbolTable(BinaryNinja::BinaryView& view, VirtualMemory& vm) const;
6666

67-
std::optional<CacheSymbol> AddExportTerminalSymbol(
68-
const std::string& symbolName, const uint8_t* current, const uint8_t* end) const;
67+
bool AddExportTerminalSymbol(
68+
std::vector<CacheSymbol>& symbols, const std::string& symbolName, const uint8_t* current,
69+
const uint8_t* end) const;
6970

7071
bool ProcessLinkEditTrie(std::vector<CacheSymbol>& symbols, const std::string& currentText, const uint8_t* begin,
7172
const uint8_t* current, const uint8_t* end) const;

view/sharedcache/core/SharedCache.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ std::vector<std::string> CacheImage::GetDependencies() const
2929
}
3030

3131
CacheEntry::CacheEntry(std::string filePath, std::string fileName, CacheEntryType type, dyld_cache_header header,
32-
std::vector<dyld_cache_mapping_info> mappings, std::unordered_map<std::string, dyld_cache_image_info> images)
32+
std::vector<dyld_cache_mapping_info> mappings, std::vector<std::pair<std::string, dyld_cache_image_info>> images)
3333
{
3434
m_filePath = std::move(filePath);
3535
m_fileName = std::move(fileName);
@@ -88,14 +88,15 @@ std::optional<CacheEntry> CacheEntry::FromFile(const std::string& filePath, cons
8888
}
8989

9090
// Gather all images for the entry.
91-
std::unordered_map<std::string, dyld_cache_image_info> images;
91+
std::vector<std::pair<std::string, dyld_cache_image_info>> images;
92+
images.reserve(header.imagesCountOld ? header.imagesCountOld : header.imagesCount);
9293
dyld_cache_image_info currentImg {};
9394
for (size_t i = 0; i < header.imagesCount; i++)
9495
{
9596
file->Read(
9697
&currentImg, header.imagesOffset + (i * sizeof(dyld_cache_image_info)), sizeof(dyld_cache_image_info));
9798
auto imagePath = file->ReadNullTermString(currentImg.pathFileOffset);
98-
images.insert_or_assign(imagePath, currentImg);
99+
images.emplace_back(imagePath, currentImg);
99100
}
100101

101102
// Handle old dyld format that uses old images field.
@@ -104,7 +105,7 @@ std::optional<CacheEntry> CacheEntry::FromFile(const std::string& filePath, cons
104105
file->Read(
105106
&currentImg, header.imagesOffsetOld + (i * sizeof(dyld_cache_image_info)), sizeof(dyld_cache_image_info));
106107
auto imagePath = file->ReadNullTermString(currentImg.pathFileOffset);
107-
images.insert_or_assign(imagePath, currentImg);
108+
images.emplace_back(imagePath, currentImg);
108109
}
109110

110111
// NOTE: I am not sure how the header type has changed over time but if apple is replacing fields with other ones
@@ -119,7 +120,7 @@ std::optional<CacheEntry> CacheEntry::FromFile(const std::string& filePath, cons
119120
branchIslandImg.address = header.branchPoolsOffset + (i * sizeof(uint64_t));
120121
// Mason: why such a long name for the image???
121122
auto imageName = fmt::format("dyld_shared_cache_branch_islands_{}", i);
122-
images.insert_or_assign(imageName, branchIslandImg);
123+
images.emplace_back(imageName, branchIslandImg);
123124
}
124125

125126
return CacheEntry(filePath, fileName, type, header, mappings, images);
@@ -151,12 +152,12 @@ SharedCache::SharedCache(uint64_t addressSize)
151152
}
152153

153154

154-
void SharedCache::AddImage(CacheImage image)
155+
void SharedCache::AddImage(CacheImage&& image)
155156
{
156157
m_images.insert({image.headerAddress, std::move(image)});
157158
}
158159

159-
void SharedCache::AddRegion(CacheRegion region)
160+
void SharedCache::AddRegion(CacheRegion&& region)
160161
{
161162
// Handle overlapping regions here.
162163
const auto regionRange = region.AsAddressRange();
@@ -203,8 +204,8 @@ void SharedCache::AddSymbol(CacheSymbol symbol)
203204

204205
void SharedCache::AddSymbols(std::vector<CacheSymbol>&& symbols)
205206
{
206-
for (auto&& symbol : symbols)
207-
m_symbols.emplace(symbol.address, std::move(symbol));
207+
for (auto& symbol : symbols)
208+
m_symbols.insert({symbol.address, std::move(symbol)});
208209
}
209210

210211
CacheEntryId SharedCache::AddEntry(CacheEntry entry)
@@ -281,18 +282,17 @@ bool SharedCache::ProcessEntryImage(const std::string& path, const dyld_cache_im
281282
flags |= SegmentExecutable;
282283
sectionRegion.flags = static_cast<BNSegmentFlag>(flags);
283284

284-
// Add the image section to the cache and also to the image region starts
285-
AddRegion(sectionRegion);
286285
image.regionStarts.push_back(sectionRegion.start);
286+
// Add the image section to the cache and also to the image region starts
287+
AddRegion(std::move(sectionRegion));
287288
}
288289

289290
// Add the exported symbols to the available symbols.
290291
std::vector<CacheSymbol> exportSymbols = imageHeader->ReadExportSymbolTrie(*m_vm);
291292
AddSymbols(std::move(exportSymbols));
292293

293294
// This is behind a shared pointer as the header itself is very large.
294-
// TODO: Make this a unique pointer? I think the image should own the header at this point?
295-
image.header = std::make_shared<SharedCacheMachOHeader>(*imageHeader);
295+
image.header = std::make_shared<SharedCacheMachOHeader>(std::move(*imageHeader));
296296

297297
AddImage(std::move(image));
298298
return true;

view/sharedcache/core/SharedCache.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ class CacheEntry
136136
std::vector<dyld_cache_mapping_info> m_mappings {};
137137
// Mapping of image path to image info, used within ProcessImagesAndRegions to add them to the cache.
138138
// Also used to retrieve the image dependencies.
139-
std::unordered_map<std::string, dyld_cache_image_info> m_images {};
139+
std::vector<std::pair<std::string, dyld_cache_image_info>> m_images {};
140140

141141
public:
142142
CacheEntry(std::string filePath, std::string fileName, CacheEntryType type, dyld_cache_header header,
143-
std::vector<dyld_cache_mapping_info> mappings, std::unordered_map<std::string, dyld_cache_image_info> images);
143+
std::vector<dyld_cache_mapping_info> mappings, std::vector<std::pair<std::string, dyld_cache_image_info>> images);
144144

145145
CacheEntry() = default;
146146

@@ -173,7 +173,7 @@ class CacheEntry
173173
const std::string GetFileName() const { return m_fileName; }
174174
const dyld_cache_header& GetHeader() const { return m_header; }
175175
const std::vector<dyld_cache_mapping_info>& GetMappings() const { return m_mappings; }
176-
const std::unordered_map<std::string, dyld_cache_image_info>& GetImages() const { return m_images; }
176+
const std::vector<std::pair<std::string, dyld_cache_image_info>>& GetImages() const { return m_images; }
177177
};
178178

179179
// The ID for a given CacheEntry, use this instead of passing a pointer around to avoid complexity :V
@@ -227,10 +227,10 @@ class SharedCache
227227
const std::unordered_map<uint64_t, CacheSymbol>& GetSymbols() const { return m_symbols; }
228228
const std::unordered_map<std::string, uint64_t>& GetNamedSymbols() const { return m_namedSymbols; }
229229

230-
void AddImage(CacheImage image);
230+
void AddImage(CacheImage&& image);
231231

232232
// Add a region that may overlap with another.
233-
void AddRegion(CacheRegion region);
233+
void AddRegion(CacheRegion&& region);
234234

235235
void AddSymbol(CacheSymbol symbol);
236236

0 commit comments

Comments
 (0)