summaryrefslogtreecommitdiff
path: root/objectivec/objc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'objectivec/objc.cpp')
-rw-r--r--objectivec/objc.cpp19
1 files changed, 15 insertions, 4 deletions
diff --git a/objectivec/objc.cpp b/objectivec/objc.cpp
index f650500a..2fa6fb0d 100644
--- a/objectivec/objc.cpp
+++ b/objectivec/objc.cpp
@@ -581,13 +581,19 @@ void ObjCProcessor::LoadCategories(ObjCReader* reader, Ref<Section> classPtrSect
categoryBaseClassName = it->second.name;
category.associatedName = it->second.associatedName;
}
- else if (auto symbol = m_data->GetSymbolByAddress(catLocation + m_data->GetAddressSize()))
+ else if (const auto symbol = GetSymbol(cat.cls))
{
- if (symbol->GetType() == ImportedDataSymbol || symbol->GetType() == ImportAddressSymbol)
+ if (symbol->GetType() == ImportedDataSymbol || symbol->GetType() == ImportAddressSymbol || symbol->GetType() == DataSymbol)
{
- const auto& symbolName = symbol->GetFullName();
+ // Symbols named `_OBJC_CLASS_$_` are references to external classes.
+ // Symbols named `cls_` are classes defined in a loaded image other than
+ // the image currently being analyzed. Classes from the current image
+ // are found via `m_classes`.
+ const std::string_view symbolName = symbol->GetFullNameRef();
if (symbolName.size() > 14 && symbolName.rfind("_OBJC_CLASS_$_", 0) == 0)
- categoryBaseClassName = symbolName.substr(14, symbolName.size() - 14);
+ categoryBaseClassName = symbolName.substr(14);
+ else if (symbolName.size() > 4 && symbolName.rfind("cls_", 0) == 0)
+ categoryBaseClassName = symbolName.substr(4);
}
}
if (categoryBaseClassName.empty())
@@ -1247,6 +1253,11 @@ uint64_t ObjCProcessor::GetObjCRelativeMethodBaseAddress(ObjCReader* reader)
return 0;
}
+Ref<Symbol> ObjCProcessor::GetSymbol(uint64_t address)
+{
+ return m_data->GetSymbolByAddress(address);
+}
+
void ObjCProcessor::ProcessObjCData(std::optional<std::string> imageName)
{
m_symbolQueue = new SymbolQueue();