diff options
| author | Author: Mark Rowe <mrowe@bdash.net.nz> | 2024-12-04 08:59:16 -0500 |
|---|---|---|
| committer | kat <kat@vector35.com> | 2024-12-10 10:39:14 -0500 |
| commit | a2e5d06195c6ec725fa311220ea7037abbb9ce69 (patch) | |
| tree | 1acb237c429f60aa29c509c1452f6aa9f6432dbf /view/sharedcache | |
| parent | ce88a94adc42807f1cda3b97a7fa8f16320d48a8 (diff) | |
[SharedCache] Switch to SAX-based writer API for JSON serialization
Diffstat (limited to 'view/sharedcache')
| -rw-r--r-- | view/sharedcache/api/sharedcache.cpp | 394 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcacheapi.h | 26 | ||||
| -rw-r--r-- | view/sharedcache/core/MetadataSerializable.cpp | 548 | ||||
| -rw-r--r-- | view/sharedcache/core/MetadataSerializable.hpp | 478 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.cpp | 500 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.h | 205 |
6 files changed, 782 insertions, 1369 deletions
diff --git a/view/sharedcache/api/sharedcache.cpp b/view/sharedcache/api/sharedcache.cpp index 45ca6377..71d190da 100644 --- a/view/sharedcache/api/sharedcache.cpp +++ b/view/sharedcache/api/sharedcache.cpp @@ -222,398 +222,4 @@ namespace SharedCacheAPI { BNDSCFindSymbolAtAddressAndApplyToAddress(m_object, symbolLocation, targetLocation, triggerReanalysis); } - -void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const mach_header_64& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.magic, context.allocator); - bArr.PushBack(b.cputype, context.allocator); - bArr.PushBack(b.cpusubtype, context.allocator); - bArr.PushBack(b.filetype, context.allocator); - bArr.PushBack(b.ncmds, context.allocator); - bArr.PushBack(b.sizeofcmds, context.allocator); - bArr.PushBack(b.flags, context.allocator); - bArr.PushBack(b.reserved, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, mach_header_64& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const symtab_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.symoff, context.allocator); - bArr.PushBack(b.nsyms, context.allocator); - bArr.PushBack(b.stroff, context.allocator); - bArr.PushBack(b.strsize, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, symtab_command& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const dysymtab_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.ilocalsym, context.allocator); - bArr.PushBack(b.nlocalsym, context.allocator); - bArr.PushBack(b.iextdefsym, context.allocator); - bArr.PushBack(b.nextdefsym, context.allocator); - bArr.PushBack(b.iundefsym, context.allocator); - bArr.PushBack(b.nundefsym, context.allocator); - bArr.PushBack(b.tocoff, context.allocator); - bArr.PushBack(b.ntoc, context.allocator); - bArr.PushBack(b.modtaboff, context.allocator); - bArr.PushBack(b.nmodtab, context.allocator); - bArr.PushBack(b.extrefsymoff, context.allocator); - bArr.PushBack(b.nextrefsyms, context.allocator); - bArr.PushBack(b.indirectsymoff, context.allocator); - bArr.PushBack(b.nindirectsyms, context.allocator); - bArr.PushBack(b.extreloff, context.allocator); - bArr.PushBack(b.nextrel, context.allocator); - bArr.PushBack(b.locreloff, context.allocator); - bArr.PushBack(b.nlocrel, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, dysymtab_command& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const dyld_info_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.rebase_off, context.allocator); - bArr.PushBack(b.rebase_size, context.allocator); - bArr.PushBack(b.bind_off, context.allocator); - bArr.PushBack(b.bind_size, context.allocator); - bArr.PushBack(b.weak_bind_off, context.allocator); - bArr.PushBack(b.weak_bind_size, context.allocator); - bArr.PushBack(b.lazy_bind_off, context.allocator); - bArr.PushBack(b.lazy_bind_size, context.allocator); - bArr.PushBack(b.export_off, context.allocator); - bArr.PushBack(b.export_size, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, dyld_info_command& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const routines_command_64& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.init_address, context.allocator); - bArr.PushBack(b.init_module, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, routines_command_64& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const function_starts_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.funcoff, context.allocator); - bArr.PushBack(b.funcsize, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, function_starts_command& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.funcoff = bArr[2].GetUint(); - b.funcsize = bArr[3].GetUint(); -} - -void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const std::vector<section_64>& b) -{ - rapidjson::Value key(name.data(), context.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(), context.allocator), context.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(), context.allocator), context.allocator); - sArr.PushBack(s.addr, context.allocator); - sArr.PushBack(s.size, context.allocator); - sArr.PushBack(s.offset, context.allocator); - sArr.PushBack(s.align, context.allocator); - sArr.PushBack(s.reloff, context.allocator); - sArr.PushBack(s.nreloc, context.allocator); - sArr.PushBack(s.flags, context.allocator); - sArr.PushBack(s.reserved1, context.allocator); - sArr.PushBack(s.reserved2, context.allocator); - sArr.PushBack(s.reserved3, context.allocator); - bArr.PushBack(sArr, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, std::vector<section_64>& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const linkedit_data_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.dataoff, context.allocator); - bArr.PushBack(b.datasize, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, linkedit_data_command& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.dataoff = bArr[2].GetUint(); - b.datasize = bArr[3].GetUint(); -} - -void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const segment_command_64& b) -{ - rapidjson::Value key(name.data(), context.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(), context.allocator), context.allocator); - bArr.PushBack(b.vmaddr, context.allocator); - bArr.PushBack(b.vmsize, context.allocator); - bArr.PushBack(b.fileoff, context.allocator); - bArr.PushBack(b.filesize, context.allocator); - bArr.PushBack(b.maxprot, context.allocator); - bArr.PushBack(b.initprot, context.allocator); - bArr.PushBack(b.nsects, context.allocator); - bArr.PushBack(b.flags, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, segment_command_64& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const std::vector<segment_command_64>& b) -{ - rapidjson::Value key(name.data(), context.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(), context.allocator), context.allocator); - sArr.PushBack(s.vmaddr, context.allocator); - sArr.PushBack(s.vmsize, context.allocator); - sArr.PushBack(s.fileoff, context.allocator); - sArr.PushBack(s.filesize, context.allocator); - sArr.PushBack(s.maxprot, context.allocator); - sArr.PushBack(s.initprot, context.allocator); - sArr.PushBack(s.nsects, context.allocator); - sArr.PushBack(s.flags, context.allocator); - bArr.PushBack(sArr, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, std::vector<segment_command_64>& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const build_version_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.platform, context.allocator); - bArr.PushBack(b.minos, context.allocator); - bArr.PushBack(b.sdk, context.allocator); - bArr.PushBack(b.ntools, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, build_version_command& b) -{ - auto bArr = context.doc[name.data()].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(SharedCacheCore::SerializationContext& context, std::string_view name, const std::vector<build_tool_version>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) - { - rapidjson::Value sArr(rapidjson::kArrayType); - sArr.PushBack(s.tool, context.allocator); - sArr.PushBack(s.version, context.allocator); - bArr.PushBack(sArr, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, std::vector<build_tool_version>& b) -{ - auto bArr = context.doc[name.data()].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); - } -} - } // namespace SharedCacheAPI diff --git a/view/sharedcache/api/sharedcacheapi.h b/view/sharedcache/api/sharedcacheapi.h index a9a67a29..7b049bc4 100644 --- a/view/sharedcache/api/sharedcacheapi.h +++ b/view/sharedcache/api/sharedcacheapi.h @@ -8,32 +8,6 @@ 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); } diff --git a/view/sharedcache/core/MetadataSerializable.cpp b/view/sharedcache/core/MetadataSerializable.cpp new file mode 100644 index 00000000..ad8959f2 --- /dev/null +++ b/view/sharedcache/core/MetadataSerializable.cpp @@ -0,0 +1,548 @@ +#include "MetadataSerializable.hpp" + +namespace SharedCacheCore { + +void Serialize(SerializationContext& context, std::string_view str) { + context.writer.String(str.data(), str.length()); +} + +void Serialize(SerializationContext& context, const char* value) { + Serialize(context, std::string_view(value)); +} + +void Serialize(SerializationContext& context, bool b) +{ + context.writer.Bool(b); +} + +void Serialize(SerializationContext& context, int8_t value) { + context.writer.Int(value); +} + +void Serialize(SerializationContext& context, uint8_t value) { + context.writer.Uint(value); +} + +void Serialize(SerializationContext& context, int16_t value) { + context.writer.Int(value); +} + +void Serialize(SerializationContext& context, uint16_t value) { + context.writer.Uint(value); +} + +void Serialize(SerializationContext& context, int32_t value) { + context.writer.Int(value); +} + +void Serialize(SerializationContext& context, uint32_t value) { + context.writer.Uint(value); +} + +void Serialize(SerializationContext& context, int64_t value) { + context.writer.Int64(value); +} + +void Serialize(SerializationContext& context, uint64_t value) { + context.writer.Uint64(value); +} + +void Deserialize(DeserializationContext& context, std::string_view name, bool& b) { + b = context.doc[name.data()].GetBool(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b) +{ + b = static_cast<uint8_t>(context.doc[name.data()].GetUint64()); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b) +{ + b = static_cast<uint16_t>(context.doc[name.data()].GetUint64()); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b) +{ + b = static_cast<uint32_t>(context.doc[name.data()].GetUint64()); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b) +{ + b = context.doc[name.data()].GetUint64(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b) +{ + b = context.doc[name.data()].GetInt(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int64_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::string& b) +{ + b = context.doc[name.data()].GetString(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::map<uint64_t, std::string>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, std::string>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, uint64_t>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::string key = i.GetArray()[0].GetString(); + std::unordered_map<uint64_t, uint64_t> memArray; + for (auto& member : i.GetArray()[1].GetArray()) + { + memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); + } + b[key] = memArray; + } +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::string>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::string>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b.emplace_back(i.GetString()); +} + +// Note: This flattens the pair into [first, second.first, second.second] with no nested arrays. +void Serialize(SerializationContext& context, const std::pair<uint64_t, std::pair<uint64_t, uint64_t>>& value) +{ + context.writer.StartArray(); + Serialize(context, value.first); + Serialize(context, value.second.first); + Serialize(context, value.second.second); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::pair<uint64_t, std::pair<uint64_t, uint64_t>> j; + j.first = i.GetArray()[0].GetUint64(); + j.second.first = i.GetArray()[1].GetUint64(); + j.second.second = i.GetArray()[2].GetUint64(); + b.push_back(j); + } +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, bool>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::pair<uint64_t, bool> j; + j.first = i.GetArray()[0].GetUint64(); + j.second = i.GetArray()[1].GetBool(); + b.push_back(j); + } +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector<uint64_t>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + b.push_back(i.GetUint64()); + } +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, uint64_t>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); + } +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>> j; + j.first = i.GetArray()[0].GetUint64(); + for (auto& k : i.GetArray()[1].GetArray()) + { + j.second.push_back({k.GetArray()[0].GetUint64(), k.GetArray()[1].GetString()}); + } + b.push_back(j); + } +} + +void Serialize(SerializationContext& context, const mach_header_64& value) { + context.writer.StartArray(); + Serialize(context, value.magic); + // cputype and cpusubtype are signed but were serialized as unsigned in + // v4.2 (metadata version 2). We continue serializing them as unsigned + // so we don't need to bump the metadata version. + Serialize(context, static_cast<uint32_t>(value.cputype)); + Serialize(context, static_cast<uint32_t>(value.cpusubtype)); + Serialize(context, value.filetype); + Serialize(context, value.ncmds); + Serialize(context, value.sizeofcmds); + Serialize(context, value.flags); + Serialize(context, value.reserved); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, mach_header_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.magic = bArr[0].GetUint(); + b.cputype = bArr[1].GetUint(); + b.cpusubtype = bArr[2].GetUint(); + b.filetype = bArr[3].GetUint(); + b.ncmds = bArr[4].GetUint(); + b.sizeofcmds = bArr[5].GetUint(); + b.flags = bArr[6].GetUint(); + b.reserved = bArr[7].GetUint(); +} + +void Serialize(SerializationContext& context, const symtab_command& value) +{ + context.writer.StartArray(); + Serialize(context, value.cmd); + Serialize(context, value.cmdsize); + Serialize(context, value.symoff); + Serialize(context, value.nsyms); + Serialize(context, value.stroff); + Serialize(context, value.strsize); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, symtab_command& b) +{ + auto bArr = context.doc[name.data()].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(SerializationContext& context, const dysymtab_command& value) +{ + context.writer.StartArray(); + Serialize(context, value.cmd); + Serialize(context, value.cmdsize); + Serialize(context, value.ilocalsym); + Serialize(context, value.nlocalsym); + Serialize(context, value.iextdefsym); + Serialize(context, value.nextdefsym); + Serialize(context, value.iundefsym); + Serialize(context, value.nundefsym); + Serialize(context, value.tocoff); + Serialize(context, value.ntoc); + Serialize(context, value.modtaboff); + Serialize(context, value.nmodtab); + Serialize(context, value.extrefsymoff); + Serialize(context, value.nextrefsyms); + Serialize(context, value.indirectsymoff); + Serialize(context, value.nindirectsyms); + Serialize(context, value.extreloff); + Serialize(context, value.nextrel); + Serialize(context, value.locreloff); + Serialize(context, value.nlocrel); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, dysymtab_command& b) +{ + auto bArr = context.doc[name.data()].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(SerializationContext& context, const dyld_info_command& value) +{ + context.writer.StartArray(); + Serialize(context, value.cmd); + Serialize(context, value.cmdsize); + Serialize(context, value.rebase_off); + Serialize(context, value.rebase_size); + Serialize(context, value.bind_off); + Serialize(context, value.bind_size); + Serialize(context, value.weak_bind_off); + Serialize(context, value.weak_bind_size); + Serialize(context, value.lazy_bind_off); + Serialize(context, value.lazy_bind_size); + Serialize(context, value.export_off); + Serialize(context, value.export_size); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, dyld_info_command& b) +{ + auto bArr = context.doc[name.data()].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(SerializationContext& context, const routines_command_64& value) +{ + context.writer.StartArray(); + Serialize(context, value.cmd); + Serialize(context, value.cmdsize); + Serialize(context, value.init_address); + Serialize(context, value.init_module); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, routines_command_64& b) +{ + auto bArr = context.doc[name.data()].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(SerializationContext& context, const function_starts_command& value) +{ + context.writer.StartArray(); + Serialize(context, value.cmd); + Serialize(context, value.cmdsize); + Serialize(context, value.funcoff); + Serialize(context, value.funcsize); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, function_starts_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.funcoff = bArr[2].GetUint(); + b.funcsize = bArr[3].GetUint(); +} + +void Serialize(SerializationContext& context, const section_64& value) +{ + context.writer.StartArray(); + + std::string_view sectname(value.sectname, 16); + std::string_view segname(value.segname, 16); + + Serialize(context, sectname.substr(0, sectname.find('\0'))); + Serialize(context, segname.substr(0, segname.find('\0'))); + Serialize(context, value.addr); + Serialize(context, value.size); + Serialize(context, value.offset); + Serialize(context, value.align); + Serialize(context, value.reloff); + Serialize(context, value.nreloc); + Serialize(context, value.flags); + Serialize(context, value.reserved1); + Serialize(context, value.reserved2); + Serialize(context, value.reserved3); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector<section_64>& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + section_64 sec; + auto s2 = s.GetArray(); + std::string sectNameStr = s2[0].GetString(); + memset(sec.sectname, 0, 16); + memcpy(sec.sectname, sectNameStr.c_str(), sectNameStr.size()); + std::string segNameStr = s2[1].GetString(); + memset(sec.segname, 0, 16); + 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(std::move(sec)); + } +} + +void Serialize(SerializationContext& context, const linkedit_data_command& value) +{ + context.writer.StartArray(); + Serialize(context, value.cmd); + Serialize(context, value.cmdsize); + Serialize(context, value.dataoff); + Serialize(context, value.datasize); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, linkedit_data_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.dataoff = bArr[2].GetUint(); + b.datasize = bArr[3].GetUint(); +} + +void Serialize(SerializationContext& context, const segment_command_64& value) +{ + context.writer.StartArray(); + std::string_view segname(value.segname, 16); + Serialize(context, segname.substr(0, segname.find('\0'))); + Serialize(context, value.vmaddr); + Serialize(context, value.vmsize); + Serialize(context, value.fileoff); + Serialize(context, value.filesize); + Serialize(context, value.maxprot); + Serialize(context, value.initprot); + Serialize(context, value.nsects); + Serialize(context, value.flags); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, segment_command_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + std::string segNameStr = bArr[0].GetString(); + memset(b.segname, 0, 16); + 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 Deserialize(DeserializationContext& context, std::string_view name, std::vector<segment_command_64>& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + segment_command_64 sec; + auto s2 = s.GetArray(); + std::string segNameStr = s2[0].GetString(); + memset(sec.segname, 0, 16); + 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(std::move(sec)); + } +} + +void Serialize(SerializationContext& context, const build_version_command& value) +{ + context.writer.StartArray(); + Serialize(context, value.cmd); + Serialize(context, value.cmdsize); + Serialize(context, value.platform); + Serialize(context, value.minos); + Serialize(context, value.sdk); + Serialize(context, value.ntools); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, build_version_command& b) +{ + auto bArr = context.doc[name.data()].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(SerializationContext& context, const build_tool_version& value) +{ + context.writer.StartArray(); + Serialize(context, value.tool); + Serialize(context, value.version); + context.writer.EndArray(); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector<build_tool_version>& b) +{ + auto bArr = context.doc[name.data()].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); + } +} + +} // namespace SharedCacheCore diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp index 1b7a03d0..7b44ccbd 100644 --- a/view/sharedcache/core/MetadataSerializable.hpp +++ b/view/sharedcache/core/MetadataSerializable.hpp @@ -38,6 +38,8 @@ #include "rapidjson/document.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/prettywriter.h" +#include "../api/sharedcachecore.h" +#include "view/macho/machoview.h" #ifndef SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP #define SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP @@ -56,12 +58,10 @@ using namespace BinaryNinja; struct DeserializationContext; struct SerializationContext { - rapidjson::Document doc; - rapidjson::Document::AllocatorType allocator; + rapidjson::StringBuffer buffer; + rapidjson::PrettyWriter<rapidjson::StringBuffer> writer; - SerializationContext() { - doc.SetObject(); - allocator = doc.GetAllocator(); + SerializationContext() : buffer(), writer(buffer) { } template <typename T> @@ -89,17 +89,10 @@ class MetadataSerializable public: std::string AsString() const { - rapidjson::StringBuffer strbuf; - rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf); - AsDocument().Accept(writer); - - return strbuf.GetString(); - } - - rapidjson::Document AsDocument() const { SerializationContext context; - AsDerived().Store(context); - return std::move(context.doc); + Store(context); + + return context.buffer.GetString(); } void LoadFromString(const std::string& s) @@ -116,7 +109,9 @@ public: AsDerived().Load(context); } - Ref<Metadata> AsMetadata() { return new Metadata(AsString()); } + Ref<Metadata> AsMetadata() { + return new Metadata(AsString()); + } bool LoadFromMetadata(const Ref<Metadata>& meta) { @@ -126,393 +121,132 @@ public: return true; } + void Store(SerializationContext& context) const { + context.writer.StartObject(); + AsDerived().Store(context); + context.writer.EndObject(); + } + private: const Derived& AsDerived() const { return static_cast<const Derived&>(*this); } Derived& AsDerived() { return static_cast<Derived&>(*this); } }; -inline void Serialize(SerializationContext& context, std::string_view name, bool b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, bool& b) { - b = context.doc[name.data()].GetBool(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, uint8_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b) -{ - b = static_cast<uint8_t>(context.doc[name.data()].GetUint64()); -} - -inline void Serialize(SerializationContext& context, std::string_view name, uint16_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b) -{ - b = static_cast<uint16_t>(context.doc[name.data()].GetUint64()); -} - -inline void Serialize(SerializationContext& context, std::string_view name, uint32_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b) -{ - b = static_cast<uint32_t>(context.doc[name.data()].GetUint64()); -} - -inline void Serialize(SerializationContext& context, std::string_view name, uint64_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b) -{ - b = context.doc[name.data()].GetUint64(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, int8_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b) -{ - b = context.doc[name.data()].GetInt64(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, int16_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b) -{ - b = context.doc[name.data()].GetInt64(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, int32_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b) -{ - b = context.doc[name.data()].GetInt(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, int64_t b) -{ - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, int64_t& b) -{ - b = context.doc[name.data()].GetInt64(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, std::string_view b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value value(b.data(), context.allocator); - context.doc.AddMember(key, value, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::string& b) -{ - b = context.doc[name.data()].GetString(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, const std::map<uint64_t, std::string>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, context.allocator); - rapidjson::Value value(i.second.c_str(), context.allocator); - p.PushBack(value, context.allocator); - bArr.PushBack(p, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::map<uint64_t, std::string>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); -} +// The functions below are not part of the FFI API, but are exported so they can be shared with sharedcacheui. -inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<uint64_t, std::string>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, context.allocator); - rapidjson::Value value(i.second.c_str(), context.allocator); - p.PushBack(value, context.allocator); - bArr.PushBack(p, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view str); -inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<std::string, std::string>& b) +template <typename T> +inline void Serialize(SerializationContext& context, const MetadataSerializable<T>& value) { - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value _key(i.first.c_str(), context.allocator); - rapidjson::Value value(i.second.c_str(), context.allocator); - p.PushBack(_key, context.allocator); - p.PushBack(value, context.allocator); - bArr.PushBack(p, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); + value.Store(context); } -inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, std::string>& b) +template <typename T> +inline void Serialize(SerializationContext& context, std::string_view name, const T& value) { - for (auto& i : context.doc[name.data()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<uint64_t, uint64_t>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, context.allocator); - p.PushBack(i.second, context.allocator); - bArr.PushBack(p, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, uint64_t>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); -} - -// std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>> -inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value classes(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value classArr(rapidjson::kArrayType); - rapidjson::Value classKey(i.first.c_str(), context.allocator); - classArr.PushBack(classKey, context.allocator); - rapidjson::Value membersArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value member(rapidjson::kArrayType); - member.PushBack(j.first, context.allocator); - member.PushBack(j.second, context.allocator); - membersArr.PushBack(member, context.allocator); - } - classArr.PushBack(membersArr, context.allocator); - classes.PushBack(classArr, context.allocator); - } - context.doc.AddMember(key, classes, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - std::string key = i.GetArray()[0].GetString(); - std::unordered_map<uint64_t, uint64_t> memArray; - for (auto& member : i.GetArray()[1].GetArray()) - { - memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); - } - b[key] = memArray; - } -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::string>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); -} - -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::string>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (const auto& s : b) - { - rapidjson::Value value(s.c_str(), context.allocator); - bArr.PushBack(value, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); + Serialize(context, name); + Serialize(context, value); } -inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::string>& b) +template <typename First, typename Second> +void Serialize(SerializationContext& context, const std::pair<First, Second>& value) { - for (auto& i : context.doc[name.data()].GetArray()) - b.emplace_back(i.GetString()); + context.writer.StartArray(); + Serialize(context, value.first); + Serialize(context, value.second); + context.writer.EndArray(); } -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>& b) +template <typename K, typename V> +void Serialize(SerializationContext& context, const std::map<K, V>& value) { - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) + context.writer.StartArray(); + for (auto& pair : value) { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, context.allocator); - segV.PushBack(i.second.first, context.allocator); - segV.PushBack(i.second.second, context.allocator); - bArr.PushBack(segV, context.allocator); + Serialize(context, pair); } - context.doc.AddMember(key, bArr, context.allocator); + context.writer.EndArray(); } -inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>& b) +template <typename K, typename V> +void Serialize(SerializationContext& context, const std::unordered_map<K, V>& value) { - for (auto& i : context.doc[name.data()].GetArray()) + context.writer.StartArray(); + for (auto& pair : value) { - std::pair<uint64_t, std::pair<uint64_t, uint64_t>> j; - j.first = i.GetArray()[0].GetUint64(); - j.second.first = i.GetArray()[1].GetUint64(); - j.second.second = i.GetArray()[2].GetUint64(); - b.push_back(j); + Serialize(context, pair); } + context.writer.EndArray(); } -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::pair<uint64_t, bool>>& b) +template <typename T> +void Serialize(SerializationContext& context, const std::vector<T>& values) { - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) + context.writer.StartArray(); + for (const auto& value : values) { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, context.allocator); - segV.PushBack(i.second, context.allocator); - bArr.PushBack(segV, context.allocator); + Serialize(context, value); } - context.doc.AddMember(key, bArr, context.allocator); + context.writer.EndArray(); } -inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, bool>>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - std::pair<uint64_t, bool> j; - j.first = i.GetArray()[0].GetUint64(); - j.second = i.GetArray()[1].GetBool(); - b.push_back(j); - } -} - -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<uint64_t>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - bArr.PushBack(i, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<uint64_t>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - b.push_back(i.GetUint64()); - } -} - -// std::unordered_map<std::string, uint64_t> -inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map<std::string, uint64_t>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value _key(i.first.c_str(), context.allocator); - p.PushBack(_key, context.allocator); - p.PushBack(i.second, context.allocator); - bArr.PushBack(p, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, uint64_t>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); - } -} - -// std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>> -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, context.allocator); - rapidjson::Value segArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value segPair(rapidjson::kArrayType); - segPair.PushBack(j.first, context.allocator); - rapidjson::Value segStr(j.second.c_str(), context.allocator); - segPair.PushBack(segStr, context.allocator); - segArr.PushBack(segPair, context.allocator); - } - segV.PushBack(segArr, context.allocator); - bArr.PushBack(segV, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>> j; - j.first = i.GetArray()[0].GetUint64(); - for (auto& k : i.GetArray()[1].GetArray()) - { - j.second.push_back({k.GetArray()[0].GetUint64(), k.GetArray()[1].GetString()}); - } - b.push_back(j); - } -} +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, const char*); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, bool b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, bool& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, uint8_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, uint16_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, uint32_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, uint64_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, int8_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, int16_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, int32_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, int64_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, int64_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, const std::pair<uint64_t, std::pair<uint64_t, uint64_t>>& value); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::string& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::map<uint64_t, std::string>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, std::string>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<uint64_t, uint64_t>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::unordered_map<uint64_t, uint64_t>>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, std::string>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::string>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::pair<uint64_t, uint64_t>>>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, bool>>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector<uint64_t>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map<std::string, uint64_t>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::string>>>>& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const mach_header_64& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, mach_header_64& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const symtab_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, symtab_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const dysymtab_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, dysymtab_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const dyld_info_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, dyld_info_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const routines_command_64& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, routines_command_64& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const function_starts_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, function_starts_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const section_64& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector<section_64>& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const linkedit_data_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, linkedit_data_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const segment_command_64& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, segment_command_64& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector<segment_command_64>& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const build_version_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, build_version_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const build_tool_version& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector<build_tool_version>& b); } // namespace SharedCacheCore diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 16056827..65236598 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -3323,404 +3323,148 @@ void InitDSCViewType() namespace SharedCacheCore { -void Serialize(SerializationContext& context, std::string_view name, const mach_header_64& b) +void SharedCache::Store(SerializationContext& context) const { - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.magic, context.allocator); - bArr.PushBack(b.cputype, context.allocator); - bArr.PushBack(b.cpusubtype, context.allocator); - bArr.PushBack(b.filetype, context.allocator); - bArr.PushBack(b.ncmds, context.allocator); - bArr.PushBack(b.sizeofcmds, context.allocator); - bArr.PushBack(b.flags, context.allocator); - bArr.PushBack(b.reserved, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, mach_header_64& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - b.magic = bArr[0].GetUint(); - b.cputype = bArr[1].GetUint(); - b.cpusubtype = bArr[2].GetUint(); - b.filetype = bArr[3].GetUint(); - b.ncmds = bArr[4].GetUint(); - b.sizeofcmds = bArr[5].GetUint(); - b.flags = bArr[6].GetUint(); - b.reserved = bArr[7].GetUint(); -} - -void Serialize(SerializationContext& context, std::string_view name, const symtab_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.symoff, context.allocator); - bArr.PushBack(b.nsyms, context.allocator); - bArr.PushBack(b.stroff, context.allocator); - bArr.PushBack(b.strsize, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, symtab_command& b) -{ - auto bArr = context.doc[name.data()].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(SerializationContext& context, std::string_view name, const dysymtab_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.ilocalsym, context.allocator); - bArr.PushBack(b.nlocalsym, context.allocator); - bArr.PushBack(b.iextdefsym, context.allocator); - bArr.PushBack(b.nextdefsym, context.allocator); - bArr.PushBack(b.iundefsym, context.allocator); - bArr.PushBack(b.nundefsym, context.allocator); - bArr.PushBack(b.tocoff, context.allocator); - bArr.PushBack(b.ntoc, context.allocator); - bArr.PushBack(b.modtaboff, context.allocator); - bArr.PushBack(b.nmodtab, context.allocator); - bArr.PushBack(b.extrefsymoff, context.allocator); - bArr.PushBack(b.nextrefsyms, context.allocator); - bArr.PushBack(b.indirectsymoff, context.allocator); - bArr.PushBack(b.nindirectsyms, context.allocator); - bArr.PushBack(b.extreloff, context.allocator); - bArr.PushBack(b.nextrel, context.allocator); - bArr.PushBack(b.locreloff, context.allocator); - bArr.PushBack(b.nlocrel, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, dysymtab_command& b) -{ - auto bArr = context.doc[name.data()].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(SerializationContext& context, std::string_view name, const dyld_info_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.rebase_off, context.allocator); - bArr.PushBack(b.rebase_size, context.allocator); - bArr.PushBack(b.bind_off, context.allocator); - bArr.PushBack(b.bind_size, context.allocator); - bArr.PushBack(b.weak_bind_off, context.allocator); - bArr.PushBack(b.weak_bind_size, context.allocator); - bArr.PushBack(b.lazy_bind_off, context.allocator); - bArr.PushBack(b.lazy_bind_size, context.allocator); - bArr.PushBack(b.export_off, context.allocator); - bArr.PushBack(b.export_size, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, dyld_info_command& b) -{ - auto bArr = context.doc[name.data()].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(); -} + Serialize(context, "metadataVersion", METADATA_VERSION); -void Serialize(SerializationContext& context, std::string_view name, const routines_command_64& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.init_address, context.allocator); - bArr.PushBack(b.init_module, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, routines_command_64& b) -{ - auto bArr = context.doc[name.data()].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(SerializationContext& context, std::string_view name, const function_starts_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.funcoff, context.allocator); - bArr.PushBack(b.funcsize, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, function_starts_command& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.funcoff = bArr[2].GetUint(); - b.funcsize = bArr[3].GetUint(); -} + MSS(m_viewState); + MSS_CAST(m_cacheFormat, uint8_t); + MSS(m_imageStarts); + MSS(m_baseFilePath); -void Serialize(SerializationContext& context, std::string_view name, const std::vector<section_64>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) + Serialize(context, "headers"); + context.writer.StartArray(); + for (auto& [k, v] : m_headers) { - 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(), context.allocator), context.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(), context.allocator), context.allocator); - sArr.PushBack(s.addr, context.allocator); - sArr.PushBack(s.size, context.allocator); - sArr.PushBack(s.offset, context.allocator); - sArr.PushBack(s.align, context.allocator); - sArr.PushBack(s.reloff, context.allocator); - sArr.PushBack(s.nreloc, context.allocator); - sArr.PushBack(s.flags, context.allocator); - sArr.PushBack(s.reserved1, context.allocator); - sArr.PushBack(s.reserved2, context.allocator); - sArr.PushBack(s.reserved3, context.allocator); - bArr.PushBack(sArr, context.allocator); + context.writer.StartObject(); + v.Store(context); + context.writer.EndObject(); } - context.doc.AddMember(key, bArr, context.allocator); -} + context.writer.EndArray(); -void Deserialize(DeserializationContext& context, std::string_view name, std::vector<section_64>& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - for (auto& s : bArr) + Serialize(context, "exportInfos"); + context.writer.StartArray(); + for (const auto& pair1 : m_exportInfos) { - section_64 sec; - auto s2 = s.GetArray(); - std::string sectNameStr = s2[0].GetString(); - memset(sec.sectname, 0, 16); - memcpy(sec.sectname, sectNameStr.c_str(), sectNameStr.size()); - std::string segNameStr = s2[1].GetString(); - memset(sec.segname, 0, 16); - 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); + context.writer.StartObject(); + Serialize(context, "key", pair1.first); + Serialize(context, "value"); + context.writer.StartArray(); + for (const auto& pair2 : pair1.second) + { + context.writer.StartObject(); + Serialize(context, "key", pair2.first); + Serialize(context, "val1", pair2.second.first); + Serialize(context, "val2", pair2.second.second); + context.writer.EndObject(); + } + context.writer.EndArray(); + context.writer.EndObject(); } -} + context.writer.EndArray(); -void Serialize(SerializationContext& context, std::string_view name, const linkedit_data_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.dataoff, context.allocator); - bArr.PushBack(b.datasize, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); + Serialize(context, "backingCaches", m_backingCaches); + Serialize(context, "stubIslands", m_stubIslandRegions); + Serialize(context, "images", m_images); + Serialize(context, "regionsMappedIntoMemory", m_regionsMappedIntoMemory); + Serialize(context, "dyldDataSections", m_dyldDataRegions); + Serialize(context, "nonImageRegions", m_nonImageRegions); } -void Deserialize(DeserializationContext& context, std::string_view name, linkedit_data_command& b) +void SharedCache::Load(DeserializationContext& context) { - auto bArr = context.doc[name.data()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.dataoff = bArr[2].GetUint(); - b.datasize = bArr[3].GetUint(); -} - -void Serialize(SerializationContext& context, std::string_view name, const segment_command_64& b) -{ - rapidjson::Value key(name.data(), context.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(), context.allocator), context.allocator); - bArr.PushBack(b.vmaddr, context.allocator); - bArr.PushBack(b.vmsize, context.allocator); - bArr.PushBack(b.fileoff, context.allocator); - bArr.PushBack(b.filesize, context.allocator); - bArr.PushBack(b.maxprot, context.allocator); - bArr.PushBack(b.initprot, context.allocator); - bArr.PushBack(b.nsects, context.allocator); - bArr.PushBack(b.flags, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, segment_command_64& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - std::string segNameStr = bArr[0].GetString(); - memset(b.segname, 0, 16); - 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(SerializationContext& context, std::string_view name, const std::vector<segment_command_64>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) + if (context.doc.HasMember("metadataVersion")) { - 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(), context.allocator), context.allocator); - sArr.PushBack(s.vmaddr, context.allocator); - sArr.PushBack(s.vmsize, context.allocator); - sArr.PushBack(s.fileoff, context.allocator); - sArr.PushBack(s.filesize, context.allocator); - sArr.PushBack(s.maxprot, context.allocator); - sArr.PushBack(s.initprot, context.allocator); - sArr.PushBack(s.nsects, context.allocator); - sArr.PushBack(s.flags, context.allocator); - bArr.PushBack(sArr, context.allocator); + if (context.doc["metadataVersion"].GetUint() != METADATA_VERSION) + { + m_logger->LogError("Shared Cache metadata version mismatch"); + return; + } } - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, std::vector<segment_command_64>& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - for (auto& s : bArr) + else { - segment_command_64 sec; - auto s2 = s.GetArray(); - std::string segNameStr = s2[0].GetString(); - memset(sec.segname, 0, 16); - 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); + m_logger->LogError("Shared Cache metadata version missing"); + return; } -} - -void Serialize(SerializationContext& context, std::string_view name, const build_version_command& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, context.allocator); - bArr.PushBack(b.cmdsize, context.allocator); - bArr.PushBack(b.platform, context.allocator); - bArr.PushBack(b.minos, context.allocator); - bArr.PushBack(b.sdk, context.allocator); - bArr.PushBack(b.ntools, context.allocator); - context.doc.AddMember(key, bArr, context.allocator); -} - -void Deserialize(DeserializationContext& context, std::string_view name, build_version_command& b) -{ - auto bArr = context.doc[name.data()].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(SerializationContext& context, std::string_view name, const std::vector<build_tool_version>& b) -{ - rapidjson::Value key(name.data(), context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) + m_viewState = MSL_CAST(m_viewState, uint8_t, DSCViewState); + m_cacheFormat = MSL_CAST(m_cacheFormat, uint8_t, SharedCacheFormat); + m_headers.clear(); + for (auto& startAndHeader : context.doc["headers"].GetArray()) { - rapidjson::Value sArr(rapidjson::kArrayType); - sArr.PushBack(s.tool, context.allocator); - sArr.PushBack(s.version, context.allocator); - bArr.PushBack(sArr, context.allocator); + SharedCacheMachOHeader header; + header.LoadFromValue(startAndHeader); + m_headers[header.textBase] = header; } - context.doc.AddMember(key, bArr, context.allocator); -} + MSL(m_imageStarts); + MSL(m_baseFilePath); + m_exportInfos.clear(); + for (const auto& obj1 : context.doc["exportInfos"].GetArray()) + { + std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> innerVec; + for (const auto& obj2 : obj1["value"].GetArray()) + { + std::pair<BNSymbolType, std::string> innerPair = { + (BNSymbolType)obj2["val1"].GetUint64(), obj2["val2"].GetString()}; + innerVec.push_back({obj2["key"].GetUint64(), innerPair}); + } -void Deserialize(DeserializationContext& context, std::string_view name, std::vector<build_tool_version>& b) -{ - auto bArr = context.doc[name.data()].GetArray(); - for (auto& s : bArr) + m_exportInfos[obj1["key"].GetUint64()] = innerVec; + } + m_symbolInfos.clear(); + for (auto& symbolInfo : context.doc["symbolInfos"].GetArray()) { - build_tool_version sec; - auto s2 = s.GetArray(); - sec.tool = s2[0].GetUint(); - sec.version = s2[1].GetUint(); - b.push_back(sec); + std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> symbolInfoVec; + for (auto& symbolInfoPair : symbolInfo.GetArray()) + { + symbolInfoVec.push_back({symbolInfoPair[0].GetUint64(), + {(BNSymbolType)symbolInfoPair[1].GetUint(), symbolInfoPair[2].GetString()}}); + } + m_symbolInfos[symbolInfo[0].GetUint64()] = std::move(symbolInfoVec); } + m_backingCaches.clear(); + for (auto& bcV : context.doc["backingCaches"].GetArray()) + { + BackingCache bc; + bc.LoadFromValue(bcV); + m_backingCaches.push_back(std::move(bc)); + } + m_images.clear(); + for (auto& imgV : context.doc["images"].GetArray()) + { + CacheImage img; + img.LoadFromValue(imgV); + m_images.push_back(std::move(img)); + } + m_regionsMappedIntoMemory.clear(); + for (auto& rV : context.doc["regionsMappedIntoMemory"].GetArray()) + { + MemoryRegion r; + r.LoadFromValue(rV); + m_regionsMappedIntoMemory.push_back(std::move(r)); + } + m_stubIslandRegions.clear(); + for (auto& siV : context.doc["stubIslands"].GetArray()) + { + MemoryRegion si; + si.LoadFromValue(siV); + m_stubIslandRegions.push_back(std::move(si)); + } + m_dyldDataRegions.clear(); + for (auto& siV : context.doc["dyldDataSections"].GetArray()) + { + MemoryRegion si; + si.LoadFromValue(siV); + m_dyldDataRegions.push_back(std::move(si)); + } + m_nonImageRegions.clear(); + for (auto& siV : context.doc["nonImageRegions"].GetArray()) + { + MemoryRegion si; + si.LoadFromValue(siV); + m_nonImageRegions.push_back(std::move(si)); + } + + m_metadataValid = true; } -} // namespace SharedCacheCore +} // namespace SharedCacheCore diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index 934cd093..4444f847 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -16,31 +16,6 @@ DECLARE_SHAREDCACHE_API_OBJECT(BNSharedCache, SharedCache); namespace SharedCacheCore { - void Serialize(SerializationContext&, std::string_view name, const mach_header_64& b); - void Deserialize(DeserializationContext&, std::string_view name, mach_header_64& b); - void Serialize(SerializationContext&, std::string_view name, const symtab_command& b); - void Deserialize(DeserializationContext&, std::string_view name, symtab_command& b); - void Serialize(SerializationContext&, std::string_view name, const dysymtab_command& b); - void Deserialize(DeserializationContext&, std::string_view name, dysymtab_command& b); - void Serialize(SerializationContext&, std::string_view name, const dyld_info_command& b); - void Deserialize(DeserializationContext&, std::string_view name, dyld_info_command& b); - void Serialize(SerializationContext&, std::string_view name, const routines_command_64& b); - void Deserialize(DeserializationContext&, std::string_view name, routines_command_64& b); - void Serialize(SerializationContext&, std::string_view name, const function_starts_command& b); - void Deserialize(DeserializationContext&, std::string_view name, function_starts_command& b); - void Serialize(SerializationContext&, std::string_view name, const std::vector<section_64>& b); - void Deserialize(DeserializationContext&, std::string_view name, std::vector<section_64>& b); - void Serialize(SerializationContext&, std::string_view name, const linkedit_data_command& b); - void Deserialize(DeserializationContext&, std::string_view name, linkedit_data_command& b); - void Serialize(SerializationContext&, std::string_view name, const segment_command_64& b); - void Deserialize(DeserializationContext&, std::string_view name, segment_command_64& b); - void Serialize(SerializationContext&, std::string_view name, const std::vector<segment_command_64>& b); - void Deserialize(DeserializationContext&, std::string_view name, std::vector<segment_command_64>& b); - void Serialize(SerializationContext&, std::string_view name, const build_version_command& b); - void Deserialize(DeserializationContext&, std::string_view name, build_version_command& b); - void Serialize(SerializationContext&, std::string_view name, const std::vector<build_tool_version>& b); - void Deserialize(DeserializationContext&, std::string_view name, std::vector<build_tool_version>& b); - enum DSCViewState { DSCViewStateUnloaded, @@ -92,13 +67,13 @@ namespace SharedCacheCore { { MSS(installName); MSS(headerLocation); - rapidjson::Value key("regions", context.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); + Serialize(context, "regions"); + context.writer.StartArray(); for (auto& region : regions) { - bArr.PushBack(rapidjson::Value(region.AsString().c_str(), context.allocator), context.allocator); + Serialize(context, region.AsString()); } - context.doc.AddMember(key, bArr, context.allocator); + context.writer.EndArray(); } void Load(DeserializationContext& context) @@ -552,176 +527,8 @@ namespace SharedCacheCore { iOS16CacheFormat, }; - void Store(SerializationContext& context) const - { - context.doc.AddMember("metadataVersion", METADATA_VERSION, context.allocator); - - MSS(m_viewState); - MSS_CAST(m_cacheFormat, uint8_t); - MSS(m_imageStarts); - MSS(m_baseFilePath); - rapidjson::Value headers(rapidjson::kArrayType); - for (auto& [k, v] : m_headers) - { - headers.PushBack(v.AsDocument(), context.allocator); - } - context.doc.AddMember("headers", headers, context.allocator); - // std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>>> m_exportInfos - // std::vector<std::pair<uint64_t, std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>>>> exportInfos; - rapidjson::Document exportInfos(rapidjson::kArrayType); - - for (const auto& pair1 : m_exportInfos) - { - rapidjson::Value subObj(rapidjson::kObjectType); - rapidjson::Value subArr(rapidjson::kArrayType); - for (const auto& pair2 : pair1.second) - { - rapidjson::Value subSubObj(rapidjson::kObjectType); - subSubObj.AddMember("key", pair2.first, context.allocator); - subSubObj.AddMember("val1", pair2.second.first, context.allocator); - subSubObj.AddMember("val2", pair2.second.second, context.allocator); - subArr.PushBack(subSubObj, context.allocator); - } - - subObj.AddMember("key", pair1.first, context.allocator); - subObj.AddMember("value", subArr, context.allocator); - - exportInfos.PushBack(subObj, context.allocator); - } - context.doc.AddMember("exportInfos", exportInfos, context.allocator); - - rapidjson::Value backingCaches(rapidjson::kArrayType); - for (auto& bc : m_backingCaches) - { - backingCaches.PushBack(bc.AsDocument(), context.allocator); - } - context.doc.AddMember("backingCaches", backingCaches, context.allocator); - rapidjson::Value stubIslands(rapidjson::kArrayType); - for (auto& si : m_stubIslandRegions) - { - stubIslands.PushBack(si.AsDocument(), context.allocator); - } - rapidjson::Value images(rapidjson::kArrayType); - for (auto& img : m_images) - { - images.PushBack(img.AsDocument(), context.allocator); - } - context.doc.AddMember("images", images, context.allocator); - rapidjson::Value regionsMappedIntoMemory(rapidjson::kArrayType); - for (auto& r : m_regionsMappedIntoMemory) - { - regionsMappedIntoMemory.PushBack(r.AsDocument(), context.allocator); - } - context.doc.AddMember("regionsMappedIntoMemory", regionsMappedIntoMemory, context.allocator); - context.doc.AddMember("stubIslands", stubIslands, context.allocator); - rapidjson::Value dyldDataSections(rapidjson::kArrayType); - for (auto& si : m_dyldDataRegions) - { - dyldDataSections.PushBack(si.AsDocument(), context.allocator); - } - context.doc.AddMember("dyldDataSections", dyldDataSections, context.allocator); - rapidjson::Value nonImageRegions(rapidjson::kArrayType); - for (auto& si : m_nonImageRegions) - { - nonImageRegions.PushBack(si.AsDocument(), context.allocator); - } - context.doc.AddMember("nonImageRegions", nonImageRegions, context.allocator); - } - - void Load(DeserializationContext& context) - { - if (context.doc.HasMember("metadataVersion")) - { - if (context.doc["metadataVersion"].GetUint() != METADATA_VERSION) - { - m_logger->LogError("Shared Cache metadata version mismatch"); - return; - } - } - else - { - m_logger->LogError("Shared Cache metadata version missing"); - return; - } - m_viewState = MSL_CAST(m_viewState, uint8_t, DSCViewState); - m_cacheFormat = MSL_CAST(m_cacheFormat, uint8_t, SharedCacheFormat); - m_headers.clear(); - for (auto& startAndHeader : context.doc["headers"].GetArray()) - { - SharedCacheMachOHeader header; - header.LoadFromValue(startAndHeader); - m_headers[header.textBase] = header; - } - MSL(m_imageStarts); - MSL(m_baseFilePath); - m_exportInfos.clear(); - for (const auto& obj1 : context.doc["exportInfos"].GetArray()) - { - std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> innerVec; - for (const auto& obj2 : obj1["value"].GetArray()) - { - std::pair<BNSymbolType, std::string> innerPair = { (BNSymbolType)obj2["val1"].GetUint64(), obj2["val2"].GetString() }; - innerVec.push_back({ obj2["key"].GetUint64(), innerPair }); - } - - m_exportInfos[obj1["key"].GetUint64()] = innerVec; - } - m_symbolInfos.clear(); - for (auto& symbolInfo : context.doc["symbolInfos"].GetArray()) - { - std::vector<std::pair<uint64_t, std::pair<BNSymbolType, std::string>>> symbolInfoVec; - for (auto& symbolInfoPair : symbolInfo.GetArray()) - { - symbolInfoVec.push_back({symbolInfoPair[0].GetUint64(), - {(BNSymbolType)symbolInfoPair[1].GetUint(), symbolInfoPair[2].GetString()}}); - } - m_symbolInfos[symbolInfo[0].GetUint64()] = std::move(symbolInfoVec); - } - m_backingCaches.clear(); - for (auto& bcV : context.doc["backingCaches"].GetArray()) - { - BackingCache bc; - bc.LoadFromValue(bcV); - m_backingCaches.push_back(std::move(bc)); - } - m_images.clear(); - for (auto& imgV : context.doc["images"].GetArray()) - { - CacheImage img; - img.LoadFromValue(imgV); - m_images.push_back(std::move(img)); - } - m_regionsMappedIntoMemory.clear(); - for (auto& rV : context.doc["regionsMappedIntoMemory"].GetArray()) - { - MemoryRegion r; - r.LoadFromValue(rV); - m_regionsMappedIntoMemory.push_back(std::move(r)); - } - m_stubIslandRegions.clear(); - for (auto& siV : context.doc["stubIslands"].GetArray()) - { - MemoryRegion si; - si.LoadFromValue(siV); - m_stubIslandRegions.push_back(std::move(si)); - } - m_dyldDataRegions.clear(); - for (auto& siV : context.doc["dyldDataSections"].GetArray()) - { - MemoryRegion si; - si.LoadFromValue(siV); - m_dyldDataRegions.push_back(std::move(si)); - } - m_nonImageRegions.clear(); - for (auto& siV : context.doc["nonImageRegions"].GetArray()) - { - MemoryRegion si; - si.LoadFromValue(siV); - m_nonImageRegions.push_back(std::move(si)); - } - - m_metadataValid = true; - } + void Store(SerializationContext& context) const; + void Load(DeserializationContext& context); private: Ref<Logger> m_logger; |
