summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2025-07-04 23:44:30 -0700
committerMark Rowe <mark@vector35.com>2025-07-07 18:57:44 -0700
commit9aa5359a82e3a9ecf27355c3dba1c2453897db68 (patch)
tree05f7b3a8f699dfb8c276160c793728db9d110fac
parent402cf087cfcf69e0c38b027d2b8488d5cdcbed76 (diff)
[ObjC] Fix handling of relative method selectors with MSVC
The order that the operands to `+` are evaluated in is unspecified. Clang happens to evaluate them left to right and gives the expected answer. MSVC picks the opposite order and so the value it computes is off by 4. This was resulting in missing method names when arm64 binaries containing Objective-C are analyzed on Windows.
-rw-r--r--objectivec/objc.cpp11
-rw-r--r--view/sharedcache/core/ObjC.cpp8
2 files changed, 14 insertions, 5 deletions
diff --git a/objectivec/objc.cpp b/objectivec/objc.cpp
index 4c574600..e4b21ff6 100644
--- a/objectivec/objc.cpp
+++ b/objectivec/objc.cpp
@@ -838,9 +838,14 @@ void ObjCProcessor::LoadProtocols(ObjCReader* reader, Ref<Section> listSection)
void ObjCProcessor::GetRelativeMethod(ObjCReader* reader, method_t& meth)
{
- meth.name = reader->GetOffset() + reader->ReadS32();
- meth.types = reader->GetOffset() + reader->ReadS32();
- meth.imp = reader->GetOffset() + reader->ReadS32();
+ uint64_t offset = reader->GetOffset();
+ meth.name = offset + reader->ReadS32();
+
+ offset += sizeof(int32_t);
+ meth.types = offset + reader->ReadS32();
+
+ offset += sizeof(int32_t);
+ meth.imp = offset + reader->ReadS32();
}
void ObjCProcessor::ReadListOfMethodLists(ObjCReader* reader, ClassBase& cls, std::string_view name, view_ptr_t start)
diff --git a/view/sharedcache/core/ObjC.cpp b/view/sharedcache/core/ObjC.cpp
index dc3012a5..b6de8ba6 100644
--- a/view/sharedcache/core/ObjC.cpp
+++ b/view/sharedcache/core/ObjC.cpp
@@ -97,8 +97,12 @@ void SharedCacheObjCProcessor::GetRelativeMethod(ObjCReader* reader, method_t& m
if (m_customRelativeMethodSelectorBase.has_value())
{
meth.name = m_customRelativeMethodSelectorBase.value() + reader->ReadS32();
- meth.types = reader->GetOffset() + reader->ReadS32();
- meth.imp = reader->GetOffset() + reader->ReadS32();
+
+ uint64_t offset = reader->GetOffset();
+ meth.types = offset + reader->ReadS32();
+
+ offset += sizeof(int32_t);
+ meth.imp = offset + reader->ReadS32();
}
else
{