diff options
| author | Mark Rowe <mrowe@bdash.net.nz> | 2025-02-17 11:04:35 -0800 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-04-03 12:17:12 -0400 |
| commit | 254fd7b1f48c0e79889e4c786c7e507e7ac2e067 (patch) | |
| tree | 07503712d127478725601f979b3d59a70cfc536e /view/sharedcache/core/ObjC.cpp | |
| parent | a82ef16042a6abd97fd736545788952714809426 (diff) | |
[SharedCache] Fix detection of the class name of categories
The logic for determining the class name of a category did not correctly
handle classes defined in other images in the shared cache. There were
two problems:
1. If the class is defined in another image that is already loaded,
`ObjCProcessor` has already renamed the symbol from `_OBJC_CLASS_$_`
to `cls_`. Both forms of symbol name are now handled.
2. If the class is defined in an image that is not yet loaded, no symbol
name is available. The category's class is now looked up in the
shared cache symbol table, and the symbol's name is parsed as if it
were an import symbol.
This fixes almost all cases of "Failed to determine base classname for
category" that I have come across.
Mason Reed: Fixed up to make objective-c processor always consult GetSymbol
Diffstat (limited to 'view/sharedcache/core/ObjC.cpp')
| -rw-r--r-- | view/sharedcache/core/ObjC.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/view/sharedcache/core/ObjC.cpp b/view/sharedcache/core/ObjC.cpp index bb483542..9fee4628 100644 --- a/view/sharedcache/core/ObjC.cpp +++ b/view/sharedcache/core/ObjC.cpp @@ -148,6 +148,28 @@ uint64_t SharedCacheObjCProcessor::GetObjCRelativeMethodBaseAddress(ObjCReader* return m_customRelativeMethodSelectorBase.value_or(0); } +Ref<Symbol> SharedCacheObjCProcessor::GetSymbol(uint64_t address) +{ + if (const auto symbol = m_data->GetSymbolByAddress(address)) + return symbol; + + const auto controller = DSC::SharedCacheController::FromView(*m_data); + if (!controller) + return nullptr; + + // No existing symbol located, try and search through the symbols of the cache. + auto cacheSymbol = controller->GetCache().GetSymbolAt(address); + if (!cacheSymbol.has_value()) + return nullptr; + + // Define the new symbol! + // While the method is "getting a symbol" and not applying it to the view, currently this is the more effective + // approach than monitoring every usage of this function to make sure they also define the symbol. + Ref<Symbol> symbol(new Symbol(cacheSymbol->type, cacheSymbol->name, address)); + m_data->DefineAutoSymbol(symbol); + return symbol; +} + SharedCacheObjCProcessor::SharedCacheObjCProcessor(BinaryView* data, bool isBackedByDatabase) : ObjCProcessor(data, "SharedCache.ObjC", isBackedByDatabase, true) {} |
