summaryrefslogtreecommitdiff
path: root/view/sharedcache/api/sharedcacheapi.h
diff options
context:
space:
mode:
authorMark Rowe <mrowe@bdash.net.nz>2024-11-13 15:48:14 -0800
committerkat <kat@vector35.com>2024-12-10 10:39:14 -0500
commitce88a94adc42807f1cda3b97a7fa8f16320d48a8 (patch)
tree30bd98dc08dff4cf494c202de01fa7d1d0fc0eed /view/sharedcache/api/sharedcacheapi.h
parenta371d925e2957c2dd7adf9722a803e7bf7fba4e1 (diff)
[SharedCache] Rework metadata serialization to reduce memory overhead
api/MetadataSerializable.hpp is removed in favor of including core/MetadataSerializable.hpp. Both headers defined types with the same name leading to One Definition Rule violations and surprising behavior. The serialization and deserialization context are now created on-demand during serialization rather than being a member of `MetadataSerializable`. This reduces the size of every serializable object by ~220 bytes. The context is passed explicitly as an argument to `Serialize` / `Deserialize`. As a result, `Serialize` / `Deserialize` can now be free functions rather than member functions. Since `MetadataSerializable` is not used for dynamic dispatch, the virtual methods are removed and the class is updated to be a class template using CRTP. This allows delegating to the derived class's `Load` and `Store` methods without the additional size overhead of the vtable pointer in every serializable object. These changes reduce the memory footprint of Binary Ninja after loading the macOS shared cache and loading a single dylib from it from 8.3GB to 4.6GB.
Diffstat (limited to 'view/sharedcache/api/sharedcacheapi.h')
-rw-r--r--view/sharedcache/api/sharedcacheapi.h439
1 files changed, 31 insertions, 408 deletions
diff --git a/view/sharedcache/api/sharedcacheapi.h b/view/sharedcache/api/sharedcacheapi.h
index 19f021e7..a9a67a29 100644
--- a/view/sharedcache/api/sharedcacheapi.h
+++ b/view/sharedcache/api/sharedcacheapi.h
@@ -1,13 +1,39 @@
#pragma once
#include <binaryninjaapi.h>
-#include "MetadataSerializable.hpp"
+#include "../core/MetadataSerializable.hpp"
#include "view/macho/machoview.h"
#include "sharedcachecore.h"
using namespace BinaryNinja;
namespace SharedCacheAPI {
+
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const mach_header_64& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, mach_header_64& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const symtab_command& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, symtab_command& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const dysymtab_command& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, dysymtab_command& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const dyld_info_command& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, dyld_info_command& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const routines_command_64& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, routines_command_64& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const function_starts_command& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, function_starts_command& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const std::vector<section_64>& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector<section_64>& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const linkedit_data_command& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, linkedit_data_command& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const segment_command_64& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, segment_command_64& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const std::vector<segment_command_64>& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector<segment_command_64>& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const build_version_command& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, build_version_command& b);
+ void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const std::vector<build_tool_version>& b);
+ void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector<build_tool_version>& b);
+
template<class T>
class SCRefCountObject {
void AddRefInternal() { m_refs.fetch_add(1); }
@@ -131,7 +157,7 @@ namespace SharedCacheAPI {
};
using namespace BinaryNinja;
- struct SharedCacheMachOHeader : public MetadataSerializable {
+ struct SharedCacheMachOHeader : public SharedCacheCore::MetadataSerializable<SharedCacheMachOHeader> {
uint64_t textBase = 0;
uint64_t loadCommandOffset = 0;
mach_header_64 ident;
@@ -174,412 +200,8 @@ namespace SharedCacheAPI {
bool routinesPresent = false;
bool functionStartsPresent = false;
bool relocatable = false;
- void Serialize(const std::string& name, mach_header_64 b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.magic, m_activeContext.allocator);
- bArr.PushBack(b.cputype, m_activeContext.allocator);
- bArr.PushBack(b.cpusubtype, m_activeContext.allocator);
- bArr.PushBack(b.filetype, m_activeContext.allocator);
- bArr.PushBack(b.ncmds, m_activeContext.allocator);
- bArr.PushBack(b.sizeofcmds, m_activeContext.allocator);
- bArr.PushBack(b.flags, m_activeContext.allocator);
- bArr.PushBack(b.reserved, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, mach_header_64& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.magic = bArr[0].GetInt64();
- b.cputype = bArr[1].GetInt64();
- b.cpusubtype = bArr[2].GetInt64();
- b.filetype = bArr[3].GetInt64();
- b.ncmds = bArr[4].GetInt64();
- b.sizeofcmds = bArr[5].GetInt64();
- b.flags = bArr[6].GetInt64();
- b.reserved = bArr[7].GetInt64();
- }
-
- void Serialize(const std::string& name, symtab_command b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.cmd, m_activeContext.allocator);
- bArr.PushBack(b.cmdsize, m_activeContext.allocator);
- bArr.PushBack(b.symoff, m_activeContext.allocator);
- bArr.PushBack(b.nsyms, m_activeContext.allocator);
- bArr.PushBack(b.stroff, m_activeContext.allocator);
- bArr.PushBack(b.strsize, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, symtab_command& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.cmd = bArr[0].GetUint();
- b.cmdsize = bArr[1].GetUint();
- b.symoff = bArr[2].GetUint();
- b.nsyms = bArr[3].GetUint();
- b.stroff = bArr[4].GetUint();
- b.strsize = bArr[5].GetUint();
- }
-
- void Serialize(const std::string& name, dysymtab_command b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.cmd, m_activeContext.allocator);
- bArr.PushBack(b.cmdsize, m_activeContext.allocator);
- bArr.PushBack(b.ilocalsym, m_activeContext.allocator);
- bArr.PushBack(b.nlocalsym, m_activeContext.allocator);
- bArr.PushBack(b.iextdefsym, m_activeContext.allocator);
- bArr.PushBack(b.nextdefsym, m_activeContext.allocator);
- bArr.PushBack(b.iundefsym, m_activeContext.allocator);
- bArr.PushBack(b.nundefsym, m_activeContext.allocator);
- bArr.PushBack(b.tocoff, m_activeContext.allocator);
- bArr.PushBack(b.ntoc, m_activeContext.allocator);
- bArr.PushBack(b.modtaboff, m_activeContext.allocator);
- bArr.PushBack(b.nmodtab, m_activeContext.allocator);
- bArr.PushBack(b.extrefsymoff, m_activeContext.allocator);
- bArr.PushBack(b.nextrefsyms, m_activeContext.allocator);
- bArr.PushBack(b.indirectsymoff, m_activeContext.allocator);
- bArr.PushBack(b.nindirectsyms, m_activeContext.allocator);
- bArr.PushBack(b.extreloff, m_activeContext.allocator);
- bArr.PushBack(b.nextrel, m_activeContext.allocator);
- bArr.PushBack(b.locreloff, m_activeContext.allocator);
- bArr.PushBack(b.nlocrel, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, dysymtab_command& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.cmd = bArr[0].GetUint();
- b.cmdsize = bArr[1].GetUint();
- b.ilocalsym = bArr[2].GetUint();
- b.nlocalsym = bArr[3].GetUint();
- b.iextdefsym = bArr[4].GetUint();
- b.nextdefsym = bArr[5].GetUint();
- b.iundefsym = bArr[6].GetUint();
- b.nundefsym = bArr[7].GetUint();
- b.tocoff = bArr[8].GetUint();
- b.ntoc = bArr[9].GetUint();
- b.modtaboff = bArr[10].GetUint();
- b.nmodtab = bArr[11].GetUint();
- b.extrefsymoff = bArr[12].GetUint();
- b.nextrefsyms = bArr[13].GetUint();
- b.indirectsymoff = bArr[14].GetUint();
- b.nindirectsyms = bArr[15].GetUint();
- b.extreloff = bArr[16].GetUint();
- b.nextrel = bArr[17].GetUint();
- b.locreloff = bArr[18].GetUint();
- b.nlocrel = bArr[19].GetUint();
- }
-
- void Serialize(const std::string& name, dyld_info_command b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.cmd, m_activeContext.allocator);
- bArr.PushBack(b.cmdsize, m_activeContext.allocator);
- bArr.PushBack(b.rebase_off, m_activeContext.allocator);
- bArr.PushBack(b.rebase_size, m_activeContext.allocator);
- bArr.PushBack(b.bind_off, m_activeContext.allocator);
- bArr.PushBack(b.bind_size, m_activeContext.allocator);
- bArr.PushBack(b.weak_bind_off, m_activeContext.allocator);
- bArr.PushBack(b.weak_bind_size, m_activeContext.allocator);
- bArr.PushBack(b.lazy_bind_off, m_activeContext.allocator);
- bArr.PushBack(b.lazy_bind_size, m_activeContext.allocator);
- bArr.PushBack(b.export_off, m_activeContext.allocator);
- bArr.PushBack(b.export_size, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, dyld_info_command& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.cmd = bArr[0].GetUint();
- b.cmdsize = bArr[1].GetUint();
- b.rebase_off = bArr[2].GetUint();
- b.rebase_size = bArr[3].GetUint();
- b.bind_off = bArr[4].GetUint();
- b.bind_size = bArr[5].GetUint();
- b.weak_bind_off = bArr[6].GetUint();
- b.weak_bind_size = bArr[7].GetUint();
- b.lazy_bind_off = bArr[8].GetUint();
- b.lazy_bind_size = bArr[9].GetUint();
- b.export_off = bArr[10].GetUint();
- b.export_size = bArr[11].GetUint();
- }
-
- void Serialize(const std::string& name, routines_command_64 b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.cmd, m_activeContext.allocator);
- bArr.PushBack(b.cmdsize, m_activeContext.allocator);
- bArr.PushBack(b.init_address, m_activeContext.allocator);
- bArr.PushBack(b.init_module, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, routines_command_64& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.cmd = bArr[0].GetUint();
- b.cmdsize = bArr[1].GetUint();
- b.init_address = bArr[2].GetUint();
- b.init_module = bArr[3].GetUint();
- }
-
- void Serialize(const std::string& name, function_starts_command b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.cmd, m_activeContext.allocator);
- bArr.PushBack(b.cmdsize, m_activeContext.allocator);
- bArr.PushBack(b.funcoff, m_activeContext.allocator);
- bArr.PushBack(b.funcsize, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, function_starts_command& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.cmd = bArr[0].GetUint();
- b.cmdsize = bArr[1].GetUint();
- b.funcoff = bArr[2].GetUint();
- b.funcsize = bArr[3].GetUint();
- }
-
- void Serialize(const std::string& name, std::vector<section_64> b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& s : b)
- {
- rapidjson::Value sArr(rapidjson::kArrayType);
- std::string sectNameStr;
- char sectName[16];
- memcpy(sectName, s.sectname, 16);
- sectName[15] = 0;
- sectNameStr = std::string(sectName);
- sArr.PushBack(rapidjson::Value(sectNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator);
- std::string segNameStr;
- char segName[16];
- memcpy(segName, s.segname, 16);
- segName[15] = 0;
- segNameStr = std::string(segName);
- sArr.PushBack(rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator);
- sArr.PushBack(s.addr, m_activeContext.allocator);
- sArr.PushBack(s.size, m_activeContext.allocator);
- sArr.PushBack(s.offset, m_activeContext.allocator);
- sArr.PushBack(s.align, m_activeContext.allocator);
- sArr.PushBack(s.reloff, m_activeContext.allocator);
- sArr.PushBack(s.nreloc, m_activeContext.allocator);
- sArr.PushBack(s.flags, m_activeContext.allocator);
- sArr.PushBack(s.reserved1, m_activeContext.allocator);
- sArr.PushBack(s.reserved2, m_activeContext.allocator);
- sArr.PushBack(s.reserved3, m_activeContext.allocator);
- bArr.PushBack(sArr, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
- void Deserialize(const std::string& name, std::vector<section_64>& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- for (auto& s : bArr)
- {
- section_64 sec;
- auto s2 = s.GetArray();
- std::string sectNameStr = s2[0].GetString();
- memcpy(sec.sectname, sectNameStr.c_str(), sectNameStr.size());
- std::string segNameStr = s2[1].GetString();
- memcpy(sec.segname, segNameStr.c_str(), segNameStr.size());
- sec.addr = s2[2].GetUint64();
- sec.size = s2[3].GetUint64();
- sec.offset = s2[4].GetUint();
- sec.align = s2[5].GetUint();
- sec.reloff = s2[6].GetUint();
- sec.nreloc = s2[7].GetUint();
- sec.flags = s2[8].GetUint();
- sec.reserved1 = s2[9].GetUint();
- sec.reserved2 = s2[10].GetUint();
- sec.reserved3 = s2[11].GetUint();
- b.push_back(sec);
- }
- }
-
- void Serialize(const std::string& name, linkedit_data_command b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.cmd, m_activeContext.allocator);
- bArr.PushBack(b.cmdsize, m_activeContext.allocator);
- bArr.PushBack(b.dataoff, m_activeContext.allocator);
- bArr.PushBack(b.datasize, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, linkedit_data_command& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.cmd = bArr[0].GetUint();
- b.cmdsize = bArr[1].GetUint();
- b.dataoff = bArr[2].GetUint();
- b.datasize = bArr[3].GetUint();
- }
-
- void Serialize(const std::string& name, segment_command_64 b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- std::string segNameStr;
- char segName[16];
- memcpy(segName, b.segname, 16);
- segName[15] = 0;
- segNameStr = std::string(segName);
- bArr.PushBack(rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator);
- bArr.PushBack(b.vmaddr, m_activeContext.allocator);
- bArr.PushBack(b.vmsize, m_activeContext.allocator);
- bArr.PushBack(b.fileoff, m_activeContext.allocator);
- bArr.PushBack(b.filesize, m_activeContext.allocator);
- bArr.PushBack(b.maxprot, m_activeContext.allocator);
- bArr.PushBack(b.initprot, m_activeContext.allocator);
- bArr.PushBack(b.nsects, m_activeContext.allocator);
- bArr.PushBack(b.flags, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, segment_command_64& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- std::string segNameStr = bArr[0].GetString();
- memcpy(b.segname, segNameStr.c_str(), segNameStr.size());
- b.vmaddr = bArr[1].GetUint64();
- b.vmsize = bArr[2].GetUint64();
- b.fileoff = bArr[3].GetUint64();
- b.filesize = bArr[4].GetUint64();
- b.maxprot = bArr[5].GetUint();
- b.initprot = bArr[6].GetUint();
- b.nsects = bArr[7].GetUint();
- b.flags = bArr[8].GetUint();
- }
-
- void Serialize(const std::string& name, std::vector<segment_command_64> b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& s : b)
- {
- rapidjson::Value sArr(rapidjson::kArrayType);
- std::string segNameStr;
- char segName[16];
- memcpy(segName, s.segname, 16);
- segName[15] = 0;
- segNameStr = std::string(segName);
- sArr.PushBack(rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator);
- sArr.PushBack(s.vmaddr, m_activeContext.allocator);
- sArr.PushBack(s.vmsize, m_activeContext.allocator);
- sArr.PushBack(s.fileoff, m_activeContext.allocator);
- sArr.PushBack(s.filesize, m_activeContext.allocator);
- sArr.PushBack(s.maxprot, m_activeContext.allocator);
- sArr.PushBack(s.initprot, m_activeContext.allocator);
- sArr.PushBack(s.nsects, m_activeContext.allocator);
- sArr.PushBack(s.flags, m_activeContext.allocator);
- bArr.PushBack(sArr, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, std::vector<segment_command_64>& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- for (auto& s : bArr)
- {
- segment_command_64 sec;
- auto s2 = s.GetArray();
- std::string segNameStr = s2[0].GetString();
- memcpy(sec.segname, segNameStr.c_str(), segNameStr.size());
- sec.vmaddr = s2[1].GetUint64();
- sec.vmsize = s2[2].GetUint64();
- sec.fileoff = s2[3].GetUint64();
- sec.filesize = s2[4].GetUint64();
- sec.maxprot = s2[5].GetUint();
- sec.initprot = s2[6].GetUint();
- sec.nsects = s2[7].GetUint();
- sec.flags = s2[8].GetUint();
- b.push_back(sec);
- }
- }
-
- void Serialize(const std::string& name, build_version_command b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- bArr.PushBack(b.cmd, m_activeContext.allocator);
- bArr.PushBack(b.cmdsize, m_activeContext.allocator);
- bArr.PushBack(b.platform, m_activeContext.allocator);
- bArr.PushBack(b.minos, m_activeContext.allocator);
- bArr.PushBack(b.sdk, m_activeContext.allocator);
- bArr.PushBack(b.ntools, m_activeContext.allocator);
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, build_version_command& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- b.cmd = bArr[0].GetUint();
- b.cmdsize = bArr[1].GetUint();
- b.platform = bArr[2].GetUint();
- b.minos = bArr[3].GetUint();
- b.sdk = bArr[4].GetUint();
- b.ntools = bArr[5].GetUint();
- }
-
- void Serialize(const std::string& name, std::vector<build_tool_version> b)
- {
- S();
- rapidjson::Value key(name.c_str(), m_activeContext.allocator);
- rapidjson::Value bArr(rapidjson::kArrayType);
- for (auto& s : b)
- {
- rapidjson::Value sArr(rapidjson::kArrayType);
- sArr.PushBack(s.tool, m_activeContext.allocator);
- sArr.PushBack(s.version, m_activeContext.allocator);
- bArr.PushBack(sArr, m_activeContext.allocator);
- }
- m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator);
- }
-
- void Deserialize(const std::string& name, std::vector<build_tool_version>& b)
- {
- auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray();
- for (auto& s : bArr)
- {
- build_tool_version sec;
- auto s2 = s.GetArray();
- sec.tool = s2[0].GetUint();
- sec.version = s2[1].GetUint();
- b.push_back(sec);
- }
- }
-
- void Store() override {
+ void Store(SharedCacheCore::SerializationContext& context) const {
MSS(textBase);
MSS(loadCommandOffset);
MSS_SUBCLASS(ident);
@@ -614,7 +236,8 @@ namespace SharedCacheAPI {
MSS(functionStartsPresent);
MSS(relocatable);
}
- void Load() override {
+
+ void Load(SharedCacheCore::DeserializationContext& context) {
MSL(textBase);
MSL(loadCommandOffset);
MSL_SUBCLASS(ident);