From 453ed0d431ceec371e15d64eecf47a0fcab6c3a9 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Wed, 13 Nov 2024 15:48:14 -0800 Subject: [PATCH 1/6] [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. --- view/sharedcache/api/MetadataSerializable.hpp | 500 ----------- view/sharedcache/api/sharedcache.cpp | 395 +++++++++ view/sharedcache/api/sharedcacheapi.h | 439 +--------- .../sharedcache/core/MetadataSerializable.hpp | 820 +++++++++--------- view/sharedcache/core/SharedCache.cpp | 404 +++++++++ view/sharedcache/core/SharedCache.h | 573 ++---------- 6 files changed, 1325 insertions(+), 1806 deletions(-) delete mode 100644 view/sharedcache/api/MetadataSerializable.hpp diff --git a/view/sharedcache/api/MetadataSerializable.hpp b/view/sharedcache/api/MetadataSerializable.hpp deleted file mode 100644 index dd3951ea7f..0000000000 --- a/view/sharedcache/api/MetadataSerializable.hpp +++ /dev/null @@ -1,500 +0,0 @@ -// -// Created by kat on 5/31/23. -// - -/* - * Welcome to, this file. - * - * This is a metadata serialization helper. - * - * Have you ever wished turning a complex datastructure into a Metadata object was as easy in C++ as it is in python? - * Do you like macros and templates? - * - * Great news. - * - * Implement these on your `public MetadataSerializable` subclass: - * ``` - void Store() override { - MSS(m_someVariable); - MSS(m_someOtherVariable); - } - void Load() override { - MSL(m_someVariable); - MSL(m_someOtherVariable); - } - ``` - * Then, you can turn your object into a Metadata object with `AsMetadata()`, and load it back with - `LoadFromMetadata()`. - * - * Serialized fields will be automatically repopulated. - * - * Other ser/deser formats (rapidjson objects, strings) also exist. You can use these to achieve nesting, but probably - avoid that. - * */ - -#include "binaryninjaapi.h" -#include "rapidjson/document.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/prettywriter.h" - -#ifndef SHAREDCACHE_METADATASERIALIZABLE_HPP -#define SHAREDCACHE_METADATASERIALIZABLE_HPP - -#define MSS(name) store(#name, name) -#define MSS_CAST(name, type) store(#name, (type) name) -#define MSS_SUBCLASS(name) Serialize(#name, name) -#define MSL(name) name = load(#name, name) -#define MSL_CAST(name, storedType, type) name = (type)load(#name, (storedType) name) -#define MSL_SUBCLASS(name) Deserialize(#name, name) - -using namespace BinaryNinja; - -class MetadataSerializable -{ -protected: - struct SerialContext - { - rapidjson::Document doc; - rapidjson::Document::AllocatorType allocator; - }; - struct DeserContext - { - rapidjson::Document doc; - }; - - DeserContext m_activeDeserContext; - SerialContext m_activeContext; - -public: - MetadataSerializable() - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); - } - - // copy constructor - MetadataSerializable(const MetadataSerializable& other) - { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); - } - - // copy assignment - MetadataSerializable& operator=(const MetadataSerializable& other) - { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); - return *this; - } - - virtual ~MetadataSerializable() - { - } - - void SetupSerContext(rapidjson::Document::AllocatorType* alloc = nullptr) - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); - } - void S() - { - // fixme factor out - } - void Serialize(std::string& name, bool b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, bool& b) { b = m_activeDeserContext.doc[name.c_str()].GetBool(); } - - void Serialize(std::string& name, uint8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint8_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); - } - - void Serialize(std::string& name, uint16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint16_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); - } - - void Serialize(std::string& name, uint32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint32_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); - } - - void Serialize(std::string& name, uint64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint64_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetUint64(); - } - - void Serialize(std::string& name, int8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int8_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } - - void Serialize(std::string& name, int16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int16_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } - - void Serialize(std::string& name, int32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int32_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt(); - } - - void Serialize(std::string& name, int64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int64_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } - - void Serialize(std::string& name, std::string b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value value(b.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, value, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::string& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetString(); - } - - void Serialize(std::string& name, std::map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); - } - - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value key(i.first.c_str(), m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(key, m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); - } - - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); - } - - // std::unordered_map> - void Serialize(std::string& name, std::unordered_map> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value classes(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value classArr(rapidjson::kArrayType); - rapidjson::Value classKey(i.first.c_str(), m_activeContext.allocator); - classArr.PushBack(classKey, m_activeContext.allocator); - rapidjson::Value membersArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value member(rapidjson::kArrayType); - member.PushBack(j.first, m_activeContext.allocator); - member.PushBack(j.second, m_activeContext.allocator); - membersArr.PushBack(member, m_activeContext.allocator); - } - classArr.PushBack(membersArr, m_activeContext.allocator); - classes.PushBack(classArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, classes, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map>& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::string key = i.GetArray()[0].GetString(); - std::unordered_map memArray; - for (auto& member : i.GetArray()[1].GetArray()) - { - memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); - } - b[key] = memArray; - } - } - - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); - } - - void Serialize(std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (const auto& s : b) - { - rapidjson::Value value(s.c_str(), m_activeContext.allocator); - bArr.PushBack(value, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b.emplace_back(i.GetString()); - } - - void Serialize(std::string& name, std::vector>> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second.first, m_activeContext.allocator); - segV.PushBack(i.second.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector>>& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair> 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 Serialize(std::string& name, std::vector> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector>& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair j; - j.first = i.GetArray()[0].GetUint64(); - j.second = i.GetArray()[1].GetBool(); - b.push_back(j); - } - } - - void Serialize(std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - bArr.PushBack(i, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b.push_back(i.GetUint64()); - } - } - - // std::unordered_map - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value key(i.first.c_str(), m_activeContext.allocator); - p.PushBack(key, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); - } - } - - template - void store(std::string x, T y) - { - Serialize(x, y); - } - - template - T load(std::string x, T y) - { - T val; - Deserialize(x, val); - return val; - } - - rapidjson::Document& GetDoc() - { - S(); - Store(); - return m_activeContext.doc; - } - -public: - virtual void Store() = 0; - virtual void Load() = 0; - - std::string AsString() - { - rapidjson::StringBuffer strbuf; - rapidjson::PrettyWriter writer(strbuf); - GetDoc().Accept(writer); - - std::string s = strbuf.GetString(); - return s; - } - rapidjson::Document& AsDocument() { return GetDoc(); } - void LoadFromString(const std::string& s) - { - m_activeDeserContext.doc.Parse(s.c_str()); - Load(); - } - void LoadFromValue(rapidjson::Value& s) - { - m_activeDeserContext.doc.CopyFrom(s, m_activeDeserContext.doc.GetAllocator()); - Load(); - } - Ref AsMetadata() { return new Metadata(AsString()); } - bool LoadFromMetadata(const Ref& meta) - { - if (!meta->IsString()) - return false; - LoadFromString(meta->GetString()); - return true; - } -}; - -#endif // SHAREDCACHE_METADATASERIALIZABLE_HPP diff --git a/view/sharedcache/api/sharedcache.cpp b/view/sharedcache/api/sharedcache.cpp index 5ca7c480eb..45ca6377f6 100644 --- a/view/sharedcache/api/sharedcache.cpp +++ b/view/sharedcache/api/sharedcache.cpp @@ -221,4 +221,399 @@ 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& 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& 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& 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& 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& 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& 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 19f021e7c4..a9a67a29f4 100644 --- a/view/sharedcache/api/sharedcacheapi.h +++ b/view/sharedcache/api/sharedcacheapi.h @@ -1,13 +1,39 @@ #pragma once #include -#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& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& 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& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& 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& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& b); + template 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 { 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 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& 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 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& 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 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& 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); diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp index c49a9e8c47..1b7a03d0df 100644 --- a/view/sharedcache/core/MetadataSerializable.hpp +++ b/view/sharedcache/core/MetadataSerializable.hpp @@ -12,15 +12,17 @@ * * Great news. * - * Implement these on your `public MetadataSerializable` subclass: + * Implement these on your `public MetadataSerializable` subclass: * ``` - void Store() override { - MSS(m_someVariable); - MSS(m_someOtherVariable); - } - void Load() override { - MSL(m_someVariable); - MSL(m_someOtherVariable); + class MyClass : public MetadataSerializable { + void Store(SerializationContext& context) const { + MSS(m_someVariable); + MSS(m_someOtherVariable); + } + void Load(DeserializationContext& context) { + MSL(m_someVariable); + MSL(m_someOtherVariable); + } } ``` * Then, you can turn your object into a Metadata object with `AsMetadata()`, and load it back with @@ -37,501 +39,481 @@ #include "rapidjson/stringbuffer.h" #include "rapidjson/prettywriter.h" -#ifndef SHAREDCACHE_METADATASERIALIZABLE_HPP -#define SHAREDCACHE_METADATASERIALIZABLE_HPP +#ifndef SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP +#define SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP + +namespace SharedCacheCore { -#define MSS(name) store(#name, name) -#define MSS_CAST(name, type) store(#name, (type) name) -#define MSS_SUBCLASS(name) Serialize(#name, name) -#define MSL(name) name = load(#name, name) -#define MSL_CAST(name, storedType, type) name = (type)load(#name, (storedType) name) -#define MSL_SUBCLASS(name) Deserialize(#name, name) +#define MSS(name) context.store(#name, name) +#define MSS_CAST(name, type) context.store(#name, (type) name) +#define MSS_SUBCLASS(name) Serialize(context, #name, name) +#define MSL(name) name = context.load(#name) +#define MSL_CAST(name, storedType, type) name = (type)context.load(#name) +#define MSL_SUBCLASS(name) Deserialize(context, #name, name) using namespace BinaryNinja; -class MetadataSerializable -{ -protected: - struct SerialContext - { - rapidjson::Document doc; - rapidjson::Document::AllocatorType allocator; - }; - struct DeserContext - { - rapidjson::Document doc; - }; +struct DeserializationContext; - DeserContext m_activeDeserContext; - SerialContext m_activeContext; +struct SerializationContext { + rapidjson::Document doc; + rapidjson::Document::AllocatorType allocator; -public: - MetadataSerializable() - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); + SerializationContext() { + doc.SetObject(); + allocator = doc.GetAllocator(); } - // copy constructor - MetadataSerializable(const MetadataSerializable& other) + template + void store(std::string_view x, const T& y) { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); + Serialize(*this, x, y); } +}; - // copy assignment - MetadataSerializable& operator=(const MetadataSerializable& other) - { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); - return *this; - } +struct DeserializationContext { + rapidjson::Document doc; - virtual ~MetadataSerializable() + template + T load(std::string_view x) { + T value; + Deserialize(*this, x, value); + return value; } +}; - void SetupSerContext(rapidjson::Document::AllocatorType* alloc = nullptr) - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); - } - void S() - { - // fixme factor out - } - void Serialize(std::string& name, bool b) +template +class MetadataSerializable +{ +public: + std::string AsString() const { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, bool& b) { b = m_activeDeserContext.doc[name.c_str()].GetBool(); } + rapidjson::StringBuffer strbuf; + rapidjson::PrettyWriter writer(strbuf); + AsDocument().Accept(writer); - void Serialize(std::string& name, uint8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint8_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); + return strbuf.GetString(); } - void Serialize(std::string& name, uint16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint16_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); + rapidjson::Document AsDocument() const { + SerializationContext context; + AsDerived().Store(context); + return std::move(context.doc); } - void Serialize(std::string& name, uint32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint32_t& b) + void LoadFromString(const std::string& s) { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); + DeserializationContext context; + context.doc.Parse(s.c_str()); + AsDerived().Load(context); } - void Serialize(std::string& name, uint64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint64_t& b) + void LoadFromValue(rapidjson::Value& s) { - b = m_activeDeserContext.doc[name.c_str()].GetUint64(); + DeserializationContext context; + context.doc.CopyFrom(s, context.doc.GetAllocator()); + AsDerived().Load(context); } - void Serialize(std::string& name, int8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int8_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } + Ref AsMetadata() { return new Metadata(AsString()); } - void Serialize(std::string& name, int16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int16_t& b) + bool LoadFromMetadata(const Ref& meta) { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); + if (!meta->IsString()) + return false; + LoadFromString(meta->GetString()); + return true; } - void Serialize(std::string& name, int32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int32_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt(); - } +private: + const Derived& AsDerived() const { return static_cast(*this); } + Derived& AsDerived() { return static_cast(*this); } +}; - void Serialize(std::string& name, int64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int64_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } +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); +} - void Serialize(std::string& name, std::string b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value value(b.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, value, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::string& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetString(); - } +inline void Deserialize(DeserializationContext& context, std::string_view name, bool& b) { + b = context.doc[name.data()].GetBool(); +} - void Serialize(std::string& name, std::map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); - } +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); +} - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } +inline void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b) +{ + b = static_cast(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(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(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); +} - void Serialize(std::string& name, std::unordered_map b) +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& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value _key(i.first.c_str(), m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(_key, m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + 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); } - void Deserialize(std::string& name, std::unordered_map& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::map& b) +{ + 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& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); + 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); +} - void Serialize(std::string& name, std::unordered_map b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + 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); } - void Deserialize(std::string& name, std::unordered_map& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + 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& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); + 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); +} - // std::unordered_map> - void Serialize(std::string& name, std::unordered_map> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value classes(rapidjson::kArrayType); - for (auto& i : b) +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); +} + +// std::unordered_map> +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map>& 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 classArr(rapidjson::kArrayType); - rapidjson::Value classKey(i.first.c_str(), m_activeContext.allocator); - classArr.PushBack(classKey, m_activeContext.allocator); - rapidjson::Value membersArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value member(rapidjson::kArrayType); - member.PushBack(j.first, m_activeContext.allocator); - member.PushBack(j.second, m_activeContext.allocator); - membersArr.PushBack(member, m_activeContext.allocator); - } - classArr.PushBack(membersArr, m_activeContext.allocator); - classes.PushBack(classArr, m_activeContext.allocator); + rapidjson::Value member(rapidjson::kArrayType); + member.PushBack(j.first, context.allocator); + member.PushBack(j.second, context.allocator); + membersArr.PushBack(member, context.allocator); } - m_activeContext.doc.AddMember(key, classes, m_activeContext.allocator); + classArr.PushBack(membersArr, context.allocator); + classes.PushBack(classArr, context.allocator); } - void Deserialize(std::string& name, std::unordered_map>& b) + context.doc.AddMember(key, classes, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) + std::string key = i.GetArray()[0].GetString(); + std::unordered_map memArray; + for (auto& member : i.GetArray()[1].GetArray()) { - std::string key = i.GetArray()[0].GetString(); - std::unordered_map memArray; - for (auto& member : i.GetArray()[1].GetArray()) - { - memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); - } - b[key] = memArray; + memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); } + b[key] = memArray; } +} - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); - } +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); +} - void Serialize(std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (const auto& s : b) - { - rapidjson::Value value(s.c_str(), m_activeContext.allocator); - bArr.PushBack(value, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector& b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (const auto& s : b) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b.emplace_back(i.GetString()); + rapidjson::Value value(s.c_str(), context.allocator); + bArr.PushBack(value, context.allocator); } + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b.emplace_back(i.GetString()); +} - void Serialize(std::string& name, std::vector>> b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>>& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second.first, m_activeContext.allocator); - segV.PushBack(i.second.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + 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); } - void Deserialize(std::string& name, std::vector>>& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair> 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); - } + std::pair> 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 Serialize(std::string& name, std::vector> b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + rapidjson::Value segV(rapidjson::kArrayType); + segV.PushBack(i.first, context.allocator); + segV.PushBack(i.second, context.allocator); + bArr.PushBack(segV, context.allocator); } - void Deserialize(std::string& name, std::vector>& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair j; - j.first = i.GetArray()[0].GetUint64(); - j.second = i.GetArray()[1].GetBool(); - b.push_back(j); - } + std::pair j; + j.first = i.GetArray()[0].GetUint64(); + j.second = i.GetArray()[1].GetBool(); + b.push_back(j); } +} - void Serialize(std::string& name, std::vector b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - bArr.PushBack(i, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + bArr.PushBack(i, context.allocator); } - void Deserialize(std::string& name, std::vector& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b.push_back(i.GetUint64()); - } + b.push_back(i.GetUint64()); } +} - // std::unordered_map - void Serialize(std::string& name, std::unordered_map b) +// std::unordered_map +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value _key(i.first.c_str(), m_activeContext.allocator); - p.PushBack(_key, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + 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); } - void Deserialize(std::string& name, std::unordered_map& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); - } + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); } - // std::vector>>> - void Serialize(std::string& name, std::vector>>> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) +} + +// std::vector>>> +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& 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 segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value segArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value segPair(rapidjson::kArrayType); - segPair.PushBack(j.first, m_activeContext.allocator); - rapidjson::Value segStr(j.second.c_str(), m_activeContext.allocator); - segPair.PushBack(segStr, m_activeContext.allocator); - segArr.PushBack(segPair, m_activeContext.allocator); - } - segV.PushBack(segArr, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); + 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); } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + segV.PushBack(segArr, context.allocator); + bArr.PushBack(segV, context.allocator); } - void Deserialize(std::string& name, std::vector>>>& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) + std::pair>> j; + j.first = i.GetArray()[0].GetUint64(); + for (auto& k : i.GetArray()[1].GetArray()) { - std::pair>> 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); + j.second.push_back({k.GetArray()[0].GetUint64(), k.GetArray()[1].GetString()}); } + b.push_back(j); } +} - template - void store(std::string x, T y) - { - Serialize(x, y); - } - - template - T load(std::string x, T y) - { - T val; - Deserialize(x, val); - return val; - } - - rapidjson::Document& GetDoc() - { - S(); - Store(); - return m_activeContext.doc; - } - -public: - virtual void Store() = 0; - virtual void Load() = 0; - - std::string AsString() - { - rapidjson::StringBuffer strbuf; - rapidjson::PrettyWriter writer(strbuf); - GetDoc().Accept(writer); - - std::string s = strbuf.GetString(); - return s; - } - rapidjson::Document& AsDocument() { return GetDoc(); } - void LoadFromString(const std::string& s) - { - m_activeDeserContext.doc.Parse(s.c_str()); - Load(); - } - void LoadFromValue(rapidjson::Value& s) - { - m_activeDeserContext.doc.CopyFrom(s, m_activeDeserContext.doc.GetAllocator()); - Load(); - } - Ref AsMetadata() { return new Metadata(AsString()); } - bool LoadFromMetadata(const Ref& meta) - { - if (!meta->IsString()) - return false; - LoadFromString(meta->GetString()); - return true; - } -}; +} // namespace SharedCacheCore #endif // SHAREDCACHE_METADATASERIALIZABLE_HPP diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index a7c7ffb016..16056827a6 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -3320,3 +3320,407 @@ void InitDSCViewType() g_dscViewType = &type; g_dscRawViewType = &rawType; } + +namespace SharedCacheCore { + +void Serialize(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(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(); +} + +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(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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(DeserializationContext& context, std::string_view name, std::vector& 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(sec); + } +} + +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); +} + +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, 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& 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(DeserializationContext& context, std::string_view name, std::vector& 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(sec); + } +} + +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& 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(DeserializationContext& context, std::string_view name, std::vector& 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/SharedCache.h b/view/sharedcache/core/SharedCache.h index 81c0262039..934cd093f6 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -16,6 +16,31 @@ 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& b); + void Deserialize(DeserializationContext&, std::string_view name, std::vector& 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& b); + void Deserialize(DeserializationContext&, std::string_view name, std::vector& 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& b); + void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); + enum DSCViewState { DSCViewStateUnloaded, @@ -26,7 +51,7 @@ namespace SharedCacheCore { const std::string SharedCacheMetadataTag = "SHAREDCACHE-SharedCacheData"; - struct MemoryRegion : public MetadataSerializable + struct MemoryRegion : public MetadataSerializable { std::string prettyName; uint64_t start; @@ -36,7 +61,7 @@ namespace SharedCacheCore { bool headerInitialized = false; BNSegmentFlag flags; - void Store() override + void Store(SerializationContext& context) const { MSS(prettyName); MSS(start); @@ -46,7 +71,7 @@ namespace SharedCacheCore { MSS_CAST(flags, uint64_t); } - void Load() override + void Load(DeserializationContext& context) { MSL(prettyName); MSL(start); @@ -57,30 +82,30 @@ namespace SharedCacheCore { } }; - struct CacheImage : public MetadataSerializable + struct CacheImage : public MetadataSerializable { std::string installName; uint64_t headerLocation; std::vector regions; - void Store() override + void Store(SerializationContext& context) const { MSS(installName); MSS(headerLocation); - rapidjson::Value key("regions", m_activeContext.allocator); + rapidjson::Value key("regions", context.allocator); rapidjson::Value bArr(rapidjson::kArrayType); for (auto& region : regions) { - bArr.PushBack(rapidjson::Value(region.AsString().c_str(), m_activeContext.allocator), m_activeContext.allocator); + bArr.PushBack(rapidjson::Value(region.AsString().c_str(), context.allocator), context.allocator); } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + context.doc.AddMember(key, bArr, context.allocator); } - void Load() override + void Load(DeserializationContext& context) { MSL(installName); MSL(headerLocation); - auto bArr = m_activeDeserContext.doc["regions"].GetArray(); + auto bArr = context.doc["regions"].GetArray(); regions.clear(); for (auto& region : bArr) { @@ -91,19 +116,19 @@ namespace SharedCacheCore { } }; - struct BackingCache : public MetadataSerializable + struct BackingCache : public MetadataSerializable { std::string path; bool isPrimary = false; std::vector>> mappings; - void Store() override + void Store(SerializationContext& context) const { MSS(path); MSS(isPrimary); MSS(mappings); } - void Load() override + void Load(DeserializationContext& context) { MSL(path); MSL(isPrimary); @@ -357,7 +382,7 @@ namespace SharedCacheCore { #endif using namespace BinaryNinja; - struct SharedCacheMachOHeader : public MetadataSerializable + struct SharedCacheMachOHeader : public MetadataSerializable { uint64_t textBase = 0; uint64_t loadCommandOffset = 0; @@ -402,419 +427,8 @@ namespace SharedCacheCore { 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].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(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 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& 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(); - 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); - } - } - - 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(); - 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(const std::string& name, std::vector 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& 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(); - 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); - } - } - - 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 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& 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(SerializationContext& context) const { MSS(textBase); MSS(loadCommandOffset); @@ -851,7 +465,7 @@ namespace SharedCacheCore { MSS(functionStartsPresent); MSS(relocatable); } - void Load() override + void Load(DeserializationContext& context) { MSL(textBase); MSL(loadCommandOffset); @@ -906,7 +520,7 @@ namespace SharedCacheCore { static std::atomic sharedCacheReferences = 0; - class SharedCache : public MetadataSerializable + class SharedCache : public MetadataSerializable { IMPLEMENT_SHAREDCACHE_API_OBJECT(BNSharedCache); @@ -938,20 +552,20 @@ namespace SharedCacheCore { iOS16CacheFormat, }; - void Store() override + void Store(SerializationContext& context) const { - m_activeContext.doc.AddMember("metadataVersion", METADATA_VERSION, m_activeContext.allocator); + 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) + for (auto& [k, v] : m_headers) { - headers.PushBack(v.AsDocument(), m_activeContext.allocator); + headers.PushBack(v.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("headers", headers, m_activeContext.allocator); + context.doc.AddMember("headers", headers, context.allocator); // std::vector>>>> m_exportInfos // std::vector>>>> exportInfos; rapidjson::Document exportInfos(rapidjson::kArrayType); @@ -963,61 +577,62 @@ namespace SharedCacheCore { for (const auto& pair2 : pair1.second) { rapidjson::Value subSubObj(rapidjson::kObjectType); - subSubObj.AddMember("key", pair2.first, m_activeContext.allocator); - subSubObj.AddMember("val1", pair2.second.first, m_activeContext.allocator); - subSubObj.AddMember("val2", pair2.second.second, m_activeContext.allocator); - subArr.PushBack(subSubObj, m_activeContext.allocator); + 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, m_activeContext.allocator); - subObj.AddMember("value", subArr, m_activeContext.allocator); + subObj.AddMember("key", pair1.first, context.allocator); + subObj.AddMember("value", subArr, context.allocator); - exportInfos.PushBack(subObj, m_activeContext.allocator); + exportInfos.PushBack(subObj, context.allocator); } - m_activeContext.doc.AddMember("exportInfos", exportInfos, m_activeContext.allocator); + context.doc.AddMember("exportInfos", exportInfos, context.allocator); rapidjson::Value backingCaches(rapidjson::kArrayType); - for (auto bc : m_backingCaches) + for (auto& bc : m_backingCaches) { - backingCaches.PushBack(bc.AsDocument(), m_activeContext.allocator); + backingCaches.PushBack(bc.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("backingCaches", backingCaches, m_activeContext.allocator); + context.doc.AddMember("backingCaches", backingCaches, context.allocator); rapidjson::Value stubIslands(rapidjson::kArrayType); - for (auto si : m_stubIslandRegions) + for (auto& si : m_stubIslandRegions) { - stubIslands.PushBack(si.AsDocument(), m_activeContext.allocator); + stubIslands.PushBack(si.AsDocument(), context.allocator); } rapidjson::Value images(rapidjson::kArrayType); - for (auto img : m_images) + for (auto& img : m_images) { - images.PushBack(img.AsDocument(), m_activeContext.allocator); + images.PushBack(img.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("images", images, m_activeContext.allocator); + context.doc.AddMember("images", images, context.allocator); rapidjson::Value regionsMappedIntoMemory(rapidjson::kArrayType); - for (auto r : m_regionsMappedIntoMemory) + for (auto& r : m_regionsMappedIntoMemory) { - regionsMappedIntoMemory.PushBack(r.AsDocument(), m_activeContext.allocator); + regionsMappedIntoMemory.PushBack(r.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("regionsMappedIntoMemory", regionsMappedIntoMemory, m_activeContext.allocator); - m_activeContext.doc.AddMember("stubIslands", stubIslands, m_activeContext.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) + for (auto& si : m_dyldDataRegions) { - dyldDataSections.PushBack(si.AsDocument(), m_activeContext.allocator); + dyldDataSections.PushBack(si.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("dyldDataSections", dyldDataSections, m_activeContext.allocator); + context.doc.AddMember("dyldDataSections", dyldDataSections, context.allocator); rapidjson::Value nonImageRegions(rapidjson::kArrayType); - for (auto si : m_nonImageRegions) + for (auto& si : m_nonImageRegions) { - nonImageRegions.PushBack(si.AsDocument(), m_activeContext.allocator); + nonImageRegions.PushBack(si.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("nonImageRegions", nonImageRegions, m_activeContext.allocator); + context.doc.AddMember("nonImageRegions", nonImageRegions, context.allocator); } - void Load() override + + void Load(DeserializationContext& context) { - if (m_activeDeserContext.doc.HasMember("metadataVersion")) + if (context.doc.HasMember("metadataVersion")) { - if (m_activeDeserContext.doc["metadataVersion"].GetUint() != METADATA_VERSION) + if (context.doc["metadataVersion"].GetUint() != METADATA_VERSION) { m_logger->LogError("Shared Cache metadata version mismatch"); return; @@ -1031,7 +646,7 @@ namespace SharedCacheCore { m_viewState = MSL_CAST(m_viewState, uint8_t, DSCViewState); m_cacheFormat = MSL_CAST(m_cacheFormat, uint8_t, SharedCacheFormat); m_headers.clear(); - for (auto& startAndHeader : m_activeDeserContext.doc["headers"].GetArray()) + for (auto& startAndHeader : context.doc["headers"].GetArray()) { SharedCacheMachOHeader header; header.LoadFromValue(startAndHeader); @@ -1040,7 +655,7 @@ namespace SharedCacheCore { MSL(m_imageStarts); MSL(m_baseFilePath); m_exportInfos.clear(); - for (const auto& obj1 : m_activeDeserContext.doc["exportInfos"].GetArray()) + for (const auto& obj1 : context.doc["exportInfos"].GetArray()) { std::vector>> innerVec; for (const auto& obj2 : obj1["value"].GetArray()) @@ -1052,7 +667,7 @@ namespace SharedCacheCore { m_exportInfos[obj1["key"].GetUint64()] = innerVec; } m_symbolInfos.clear(); - for (auto& symbolInfo : m_activeDeserContext.doc["symbolInfos"].GetArray()) + for (auto& symbolInfo : context.doc["symbolInfos"].GetArray()) { std::vector>> symbolInfoVec; for (auto& symbolInfoPair : symbolInfo.GetArray()) @@ -1060,49 +675,49 @@ namespace SharedCacheCore { symbolInfoVec.push_back({symbolInfoPair[0].GetUint64(), {(BNSymbolType)symbolInfoPair[1].GetUint(), symbolInfoPair[2].GetString()}}); } - m_symbolInfos[symbolInfo[0].GetUint64()] = symbolInfoVec; + m_symbolInfos[symbolInfo[0].GetUint64()] = std::move(symbolInfoVec); } m_backingCaches.clear(); - for (auto& bcV : m_activeDeserContext.doc["backingCaches"].GetArray()) + for (auto& bcV : context.doc["backingCaches"].GetArray()) { BackingCache bc; bc.LoadFromValue(bcV); - m_backingCaches.push_back(bc); + m_backingCaches.push_back(std::move(bc)); } m_images.clear(); - for (auto& imgV : m_activeDeserContext.doc["images"].GetArray()) + for (auto& imgV : context.doc["images"].GetArray()) { CacheImage img; img.LoadFromValue(imgV); - m_images.push_back(img); + m_images.push_back(std::move(img)); } m_regionsMappedIntoMemory.clear(); - for (auto& rV : m_activeDeserContext.doc["regionsMappedIntoMemory"].GetArray()) + for (auto& rV : context.doc["regionsMappedIntoMemory"].GetArray()) { MemoryRegion r; r.LoadFromValue(rV); - m_regionsMappedIntoMemory.push_back(r); + m_regionsMappedIntoMemory.push_back(std::move(r)); } m_stubIslandRegions.clear(); - for (auto& siV : m_activeDeserContext.doc["stubIslands"].GetArray()) + for (auto& siV : context.doc["stubIslands"].GetArray()) { MemoryRegion si; si.LoadFromValue(siV); - m_stubIslandRegions.push_back(si); + m_stubIslandRegions.push_back(std::move(si)); } m_dyldDataRegions.clear(); - for (auto& siV : m_activeDeserContext.doc["dyldDataSections"].GetArray()) + for (auto& siV : context.doc["dyldDataSections"].GetArray()) { MemoryRegion si; si.LoadFromValue(siV); - m_dyldDataRegions.push_back(si); + m_dyldDataRegions.push_back(std::move(si)); } m_nonImageRegions.clear(); - for (auto& siV : m_activeDeserContext.doc["nonImageRegions"].GetArray()) + for (auto& siV : context.doc["nonImageRegions"].GetArray()) { MemoryRegion si; si.LoadFromValue(siV); - m_nonImageRegions.push_back(si); + m_nonImageRegions.push_back(std::move(si)); } m_metadataValid = true; @@ -1186,7 +801,7 @@ namespace SharedCacheCore { DSCViewState State() const { return m_viewState; } explicit SharedCache(BinaryNinja::Ref rawView); - ~SharedCache() override; + virtual ~SharedCache(); std::optional LoadHeaderForAddress( std::shared_ptr vm, uint64_t address, std::string installName); From 36a66387c549c63aa65ad9d4424a6dcb94a0795e Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Wed, 13 Nov 2024 18:43:04 -0800 Subject: [PATCH 2/6] Move implementation of SharedCache::Load / SharedCache::Store into the .cpp file --- view/sharedcache/core/SharedCache.cpp | 175 +++++++++++++++++++++++++- view/sharedcache/core/SharedCache.h | 172 +------------------------ 2 files changed, 176 insertions(+), 171 deletions(-) diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 16056827a6..414d13ad48 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -3323,6 +3323,179 @@ void InitDSCViewType() namespace SharedCacheCore { +void SharedCache::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>>>> + // m_exportInfos std::vector>>>> 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 SharedCache::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>> innerVec; + for (const auto& obj2 : obj1["value"].GetArray()) + { + std::pair 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>> 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 Serialize(SerializationContext& context, std::string_view name, const mach_header_64& b) { rapidjson::Value key(name.data(), context.allocator); @@ -3723,4 +3896,4 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve } } -} // namespace SharedCacheCore +} // namespace SharedCacheCore diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index 934cd093f6..8906160c60 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -552,176 +552,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>>>> m_exportInfos - // std::vector>>>> 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>> innerVec; - for (const auto& obj2 : obj1["value"].GetArray()) - { - std::pair 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>> 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 m_logger; From 1422f508a50a978e40fef765fe965b1f1ebd89fb Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Fri, 15 Nov 2024 08:31:02 -0800 Subject: [PATCH 3/6] [SharedCache] Move Serialize / Deserialize definitions into .cpp file This ensures only one definition ends up in the final binary and makes compilation a little faster. --- .../sharedcache/core/MetadataSerializable.cpp | 392 ++++++++++++++++ .../sharedcache/core/MetadataSerializable.hpp | 426 ++---------------- 2 files changed, 436 insertions(+), 382 deletions(-) create mode 100644 view/sharedcache/core/MetadataSerializable.cpp diff --git a/view/sharedcache/core/MetadataSerializable.cpp b/view/sharedcache/core/MetadataSerializable.cpp new file mode 100644 index 0000000000..8b7fac431a --- /dev/null +++ b/view/sharedcache/core/MetadataSerializable.cpp @@ -0,0 +1,392 @@ +#include "MetadataSerializable.hpp" + +namespace SharedCacheCore { + +using namespace BinaryNinja; + +struct DeserializationContext; + +void Serialize(SerializationContext& context, std::string_view name, bool b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, bool& b) { + b = context.doc[name.data()].GetBool(); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b) +{ + b = static_cast(context.doc[name.data()].GetUint64()); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b) +{ + b = static_cast(context.doc[name.data()].GetUint64()); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b) +{ + b = static_cast(context.doc[name.data()].GetUint64()); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b) +{ + b = context.doc[name.data()].GetUint64(); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b) +{ + b = context.doc[name.data()].GetInt(); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, int64_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::string& b) +{ + b = context.doc[name.data()].GetString(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::map& 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); + 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); +} + +// std::unordered_map> +void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map>& 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::string key = i.GetArray()[0].GetString(); + std::unordered_map 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& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b.emplace_back(i.GetString()); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector>>& 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); + segV.PushBack(i.second.first, context.allocator); + segV.PushBack(i.second.second, context.allocator); + bArr.PushBack(segV, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::pair> 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 Serialize(SerializationContext& context, std::string_view name, const std::vector>& 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); + segV.PushBack(i.second, context.allocator); + bArr.PushBack(segV, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::pair j; + j.first = i.GetArray()[0].GetUint64(); + j.second = i.GetArray()[1].GetBool(); + b.push_back(j); + } +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + b.push_back(i.GetUint64()); + } +} + +// std::unordered_map +void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); + } +} + +// std::vector>>> +void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& 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); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + { + std::pair>> 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); + } +} + +} // namespace SharedCacheCore diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp index 1b7a03d0df..3c3541c474 100644 --- a/view/sharedcache/core/MetadataSerializable.hpp +++ b/view/sharedcache/core/MetadataSerializable.hpp @@ -38,6 +38,7 @@ #include "rapidjson/document.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/prettywriter.h" +#include "../api/sharedcachecore.h" #ifndef SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP #define SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP @@ -131,388 +132,49 @@ class MetadataSerializable Derived& AsDerived() { return static_cast(*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(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(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(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& 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& b) -{ - 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& 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 Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); - 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); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) -{ - 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& 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& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); -} - -// std::unordered_map> -inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map>& 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>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - std::string key = i.GetArray()[0].GetString(); - std::unordered_map 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& 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& 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); -} - -inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - b.emplace_back(i.GetString()); -} - -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>>& 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); - segV.PushBack(i.second.first, context.allocator); - segV.PushBack(i.second.second, 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>>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - std::pair> 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); - } -} - -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>& 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); - segV.PushBack(i.second, 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>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - std::pair 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& 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& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - b.push_back(i.GetUint64()); - } -} - -// std::unordered_map -inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); - } -} - -// std::vector>>> -inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& 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>>>& b) -{ - for (auto& i : context.doc[name.data()].GetArray()) - { - std::pair>> 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); - } -} +// These are not part of the FFI API, but are exported so that sharedcacheui can use them. +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, bool b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, bool& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, uint8_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, uint16_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, uint32_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, uint64_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, int8_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, int16_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, int32_t b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, 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 name, std::string_view b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::string& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::map& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::map& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector>>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector>& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>>& b); } // namespace SharedCacheCore From 9d7282080da9b9cd683d0a2fe669a47303eb70e1 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Fri, 15 Nov 2024 08:35:58 -0800 Subject: [PATCH 4/6] Move duplicated Serialize / Deserialize functions from api / core into MetadataSerializable --- view/sharedcache/api/sharedcache.cpp | 394 ----------------- view/sharedcache/api/sharedcacheapi.h | 26 -- .../sharedcache/core/MetadataSerializable.cpp | 401 ++++++++++++++++++ .../sharedcache/core/MetadataSerializable.hpp | 26 ++ view/sharedcache/core/SharedCache.cpp | 400 ----------------- view/sharedcache/core/SharedCache.h | 25 -- 6 files changed, 427 insertions(+), 845 deletions(-) diff --git a/view/sharedcache/api/sharedcache.cpp b/view/sharedcache/api/sharedcache.cpp index 45ca6377f6..71d190da21 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& 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& 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& 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& 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& 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& 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 a9a67a29f4..7b049bc423 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& b); - void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& 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& b); - void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& 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& b); - void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& b); - template class SCRefCountObject { void AddRefInternal() { m_refs.fetch_add(1); } diff --git a/view/sharedcache/core/MetadataSerializable.cpp b/view/sharedcache/core/MetadataSerializable.cpp index 8b7fac431a..1e17279ba5 100644 --- a/view/sharedcache/core/MetadataSerializable.cpp +++ b/view/sharedcache/core/MetadataSerializable.cpp @@ -389,4 +389,405 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve } } +void Serialize(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(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(); +} + +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(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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(DeserializationContext& context, std::string_view name, std::vector& 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(sec); + } +} + +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); +} + +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, 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& 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(DeserializationContext& context, std::string_view name, std::vector& 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(sec); + } +} + +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& 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(DeserializationContext& context, std::string_view name, std::vector& 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 3c3541c474..fa27353495 100644 --- a/view/sharedcache/core/MetadataSerializable.hpp +++ b/view/sharedcache/core/MetadataSerializable.hpp @@ -39,6 +39,7 @@ #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 @@ -175,6 +176,31 @@ SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_vi SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>>& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, 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&, std::string_view name, const symtab_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, symtab_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, const dysymtab_command& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, dysymtab_command& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, 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&, std::string_view name, 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&, std::string_view name, 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&, std::string_view name, const std::vector& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, 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&, std::string_view name, const segment_command_64& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, segment_command_64& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, const std::vector& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, 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&, std::string_view name, const std::vector& b); +SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); + } // namespace SharedCacheCore diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 414d13ad48..97cc796863 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -3496,404 +3496,4 @@ void SharedCache::Load(DeserializationContext& context) m_metadataValid = true; } -void Serialize(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(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(); -} - -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(); -} - -void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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(DeserializationContext& context, std::string_view name, std::vector& 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(sec); - } -} - -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); -} - -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, 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& 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(DeserializationContext& context, std::string_view name, std::vector& 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(sec); - } -} - -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& 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(DeserializationContext& context, std::string_view name, std::vector& 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/SharedCache.h b/view/sharedcache/core/SharedCache.h index 8906160c60..0c871c3e21 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& b); - void Deserialize(DeserializationContext&, std::string_view name, std::vector& 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& b); - void Deserialize(DeserializationContext&, std::string_view name, std::vector& 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& b); - void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); - enum DSCViewState { DSCViewStateUnloaded, From 7c77bfe4a30ecfcae6e7f8d45f3935a875b8a1a0 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Fri, 15 Nov 2024 08:49:18 -0800 Subject: [PATCH 5/6] Switch to SAX-style JSON writing API Building up an in-memory representation of the JSON document is expensive in both CPU and memory. Instead of doing that we can directly write the appropriate types. --- .../sharedcache/core/MetadataSerializable.cpp | 596 +++++------------- .../sharedcache/core/MetadataSerializable.hpp | 147 +++-- view/sharedcache/core/SharedCache.cpp | 85 +-- view/sharedcache/core/SharedCache.h | 8 +- 4 files changed, 302 insertions(+), 534 deletions(-) diff --git a/view/sharedcache/core/MetadataSerializable.cpp b/view/sharedcache/core/MetadataSerializable.cpp index 1e17279ba5..0fa712b17a 100644 --- a/view/sharedcache/core/MetadataSerializable.cpp +++ b/view/sharedcache/core/MetadataSerializable.cpp @@ -2,90 +2,83 @@ namespace SharedCacheCore { -using namespace BinaryNinja; +void Serialize(SerializationContext& context, std::string_view str) { + context.writer.String(str.data(), str.length()); +} -struct DeserializationContext; +void Serialize(SerializationContext& context, const char* value) { + Serialize(context, std::string_view(value)); +} -void Serialize(SerializationContext& context, std::string_view name, bool b) +void Serialize(SerializationContext& context, bool b) { - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); + context.writer.Bool(b); } -void Deserialize(DeserializationContext& context, std::string_view name, bool& b) { - b = context.doc[name.data()].GetBool(); +void Serialize(SerializationContext& context, int8_t value) { + context.writer.Int(value); } -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); +void Serialize(SerializationContext& context, uint8_t value) { + context.writer.Uint(value); } -void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b) -{ - b = static_cast(context.doc[name.data()].GetUint64()); +void Serialize(SerializationContext& context, int16_t value) { + context.writer.Int(value); } -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); +void Serialize(SerializationContext& context, uint16_t value) { + context.writer.Uint(value); } -void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b) -{ - b = static_cast(context.doc[name.data()].GetUint64()); +void Serialize(SerializationContext& context, int32_t value) { + context.writer.Int(value); } -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); +void Serialize(SerializationContext& context, uint32_t value) { + context.writer.Uint(value); } -void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b) -{ - b = static_cast(context.doc[name.data()].GetUint64()); +void Serialize(SerializationContext& context, int64_t value) { + context.writer.Int64(value); } -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); +void Serialize(SerializationContext& context, uint64_t value) { + context.writer.Uint64(value); } -void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b) +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 = context.doc[name.data()].GetUint64(); + b = static_cast(context.doc[name.data()].GetUint64()); } -void Serialize(SerializationContext& context, std::string_view name, int8_t b) +void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b) { - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); + b = static_cast(context.doc[name.data()].GetUint64()); } -void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b) +void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b) { - b = context.doc[name.data()].GetInt64(); + b = static_cast(context.doc[name.data()].GetUint64()); } -void Serialize(SerializationContext& context, std::string_view name, int16_t b) +void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b) { - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); + b = context.doc[name.data()].GetUint64(); } -void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b) +void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b) { b = context.doc[name.data()].GetInt64(); } -void Serialize(SerializationContext& context, std::string_view name, int32_t b) +void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b) { - rapidjson::Value key(name.data(), context.allocator); - context.doc.AddMember(key, b, context.allocator); + b = context.doc[name.data()].GetInt64(); } void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b) @@ -93,131 +86,34 @@ void Deserialize(DeserializationContext& context, std::string_view name, int32_t b = context.doc[name.data()].GetInt(); } -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); -} - void Deserialize(DeserializationContext& context, std::string_view name, int64_t& b) { b = context.doc[name.data()].GetInt64(); } -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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::string& b) { b = context.doc[name.data()].GetString(); } -void Serialize(SerializationContext& context, std::string_view name, const std::map& 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::map& b) { for (auto& i : context.doc[name.data()].GetArray()) b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); } -void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); -} - -void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); - 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) { for (auto& i : context.doc[name.data()].GetArray()) b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); } -void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) { for (auto& i : context.doc[name.data()].GetArray()) b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); } -// std::unordered_map> -void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map>& 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map>& b) { for (auto& i : context.doc[name.data()].GetArray()) @@ -238,37 +134,20 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::un b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); } -void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) { for (auto& i : context.doc[name.data()].GetArray()) b.emplace_back(i.GetString()); } -void Serialize(SerializationContext& context, std::string_view name, const std::vector>>& b) +// Note: This flattens the pair into [first, second.first, second.second] with no nested arrays. +void Serialize(SerializationContext& context, const std::pair>& value) { - 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); - segV.PushBack(i.second.first, context.allocator); - segV.PushBack(i.second.second, context.allocator); - bArr.PushBack(segV, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); + 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>>& b) @@ -283,20 +162,6 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve } } -void Serialize(SerializationContext& context, std::string_view name, const std::vector>& 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); - segV.PushBack(i.second, context.allocator); - bArr.PushBack(segV, context.allocator); - } - context.doc.AddMember(key, bArr, context.allocator); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::vector>& b) { for (auto& i : context.doc[name.data()].GetArray()) @@ -308,17 +173,6 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve } } -void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) { for (auto& i : context.doc[name.data()].GetArray()) @@ -327,22 +181,6 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve } } -// std::unordered_map -void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) { for (auto& i : context.doc[name.data()].GetArray()) @@ -351,30 +189,6 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::un } } -// std::vector>>> -void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& 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); -} - void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>>& b) { for (auto& i : context.doc[name.data()].GetArray()) @@ -389,19 +203,17 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve } } -void Serialize(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 Serialize(SerializationContext& context, const mach_header_64& value) { + context.writer.StartArray(); + Serialize(context, value.magic); + Serialize(context, value.cputype); + Serialize(context, 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) @@ -417,17 +229,16 @@ void Deserialize(DeserializationContext& context, std::string_view name, mach_he b.reserved = bArr[7].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const symtab_command& b) +void Serialize(SerializationContext& context, const symtab_command& value) { - 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); + 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) @@ -441,31 +252,30 @@ void Deserialize(DeserializationContext& context, std::string_view name, symtab_ 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 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) @@ -493,23 +303,22 @@ void Deserialize(DeserializationContext& context, std::string_view name, dysymta b.nlocrel = bArr[19].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const dyld_info_command& b) +void Serialize(SerializationContext& context, const dyld_info_command& value) { - 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); + 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) @@ -529,15 +338,14 @@ void Deserialize(DeserializationContext& context, std::string_view name, dyld_in b.export_size = bArr[11].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const routines_command_64& b) +void Serialize(SerializationContext& context, const routines_command_64& value) { - 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); + 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) @@ -549,15 +357,14 @@ void Deserialize(DeserializationContext& context, std::string_view name, routine b.init_module = bArr[3].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const function_starts_command& b) +void Serialize(SerializationContext& context, const function_starts_command& value) { - 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); + 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) @@ -569,40 +376,26 @@ void Deserialize(DeserializationContext& context, std::string_view name, functio b.funcsize = bArr[3].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +void Serialize(SerializationContext& context, const section_64& value) { - 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); + 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& b) @@ -628,19 +421,18 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve sec.reserved1 = s2[9].GetUint(); sec.reserved2 = s2[10].GetUint(); sec.reserved3 = s2[11].GetUint(); - b.push_back(sec); + b.push_back(std::move(sec)); } } -void Serialize(SerializationContext& context, std::string_view name, const linkedit_data_command& b) +void Serialize(SerializationContext& context, const linkedit_data_command& value) { - 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); + 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) @@ -652,25 +444,20 @@ void Deserialize(DeserializationContext& context, std::string_view name, linkedi b.datasize = bArr[3].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const segment_command_64& b) +void Serialize(SerializationContext& context, const segment_command_64& value) { - 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); + 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) @@ -689,33 +476,6 @@ void Deserialize(DeserializationContext& context, std::string_view name, segment b.flags = bArr[8].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const std::vector& 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(DeserializationContext& context, std::string_view name, std::vector& b) { auto bArr = context.doc[name.data()].GetArray(); @@ -734,21 +494,20 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve sec.initprot = s2[6].GetUint(); sec.nsects = s2[7].GetUint(); sec.flags = s2[8].GetUint(); - b.push_back(sec); + b.push_back(std::move(sec)); } } -void Serialize(SerializationContext& context, std::string_view name, const build_version_command& b) +void Serialize(SerializationContext& context, const build_version_command& value) { - 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); + 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) @@ -762,18 +521,12 @@ void Deserialize(DeserializationContext& context, std::string_view name, build_v b.ntools = bArr[5].GetUint(); } -void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +void Serialize(SerializationContext& context, const build_tool_version& value) { - 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); + context.writer.StartArray(); + Serialize(context, value.tool); + Serialize(context, value.version); + context.writer.EndArray(); } void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) @@ -789,5 +542,4 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve } } - } // namespace SharedCacheCore diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp index fa27353495..5a39f5f67b 100644 --- a/view/sharedcache/core/MetadataSerializable.hpp +++ b/view/sharedcache/core/MetadataSerializable.hpp @@ -58,12 +58,10 @@ using namespace BinaryNinja; struct DeserializationContext; struct SerializationContext { - rapidjson::Document doc; - rapidjson::Document::AllocatorType allocator; + rapidjson::StringBuffer buffer; + rapidjson::PrettyWriter writer; - SerializationContext() { - doc.SetObject(); - allocator = doc.GetAllocator(); + SerializationContext() : buffer(), writer(buffer) { } template @@ -91,17 +89,10 @@ class MetadataSerializable public: std::string AsString() const { - rapidjson::StringBuffer strbuf; - rapidjson::PrettyWriter 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) @@ -118,7 +109,9 @@ class MetadataSerializable AsDerived().Load(context); } - Ref AsMetadata() { return new Metadata(AsString()); } + Ref AsMetadata() { + return new Metadata(AsString()); + } bool LoadFromMetadata(const Ref& meta) { @@ -128,80 +121,132 @@ class MetadataSerializable return true; } + void Store(SerializationContext& context) const { + context.writer.StartObject(); + AsDerived().Store(context); + context.writer.EndObject(); + } + private: const Derived& AsDerived() const { return static_cast(*this); } Derived& AsDerived() { return static_cast(*this); } }; -// These are not part of the FFI API, but are exported so that sharedcacheui can use them. -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, bool b); +// The functions below are not part of the FFI API, but are exported so they can be shared with sharedcacheui. + +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view str); + +template +inline void Serialize(SerializationContext& context, const MetadataSerializable& value) +{ + value.Store(context); +} + +template +inline void Serialize(SerializationContext& context, std::string_view name, const T& value) +{ + Serialize(context, name); + Serialize(context, value); +} + +template +void Serialize(SerializationContext& context, const std::pair& value) +{ + context.writer.StartArray(); + Serialize(context, value.first); + Serialize(context, value.second); + context.writer.EndArray(); +} + +template +void Serialize(SerializationContext& context, const std::map& value) +{ + context.writer.StartArray(); + for (auto& pair : value) + { + Serialize(context, pair); + } + context.writer.EndArray(); +} + +template +void Serialize(SerializationContext& context, const std::unordered_map& value) +{ + context.writer.StartArray(); + for (auto& pair : value) + { + Serialize(context, pair); + } + context.writer.EndArray(); +} + +template +void Serialize(SerializationContext& context, const std::vector& values) +{ + context.writer.StartArray(); + for (const auto& value : values) + { + Serialize(context, value); + } + context.writer.EndArray(); +} + +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, std::string_view name, uint8_t 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, std::string_view name, uint16_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, std::string_view name, uint32_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, std::string_view name, uint64_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, std::string_view name, int8_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, std::string_view name, int16_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, std::string_view name, int32_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, std::string_view name, int64_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 name, std::string_view b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::string& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::map& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::map& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map>& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map>& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector>>& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector>& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector>& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>>& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, const mach_header_64& 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&, std::string_view name, const symtab_command& 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&, std::string_view name, const dysymtab_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&, std::string_view name, const dyld_info_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&, std::string_view name, const routines_command_64& 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&, std::string_view name, const function_starts_command& 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&, std::string_view name, const std::vector& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const section_64& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, const linkedit_data_command& 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&, std::string_view name, const segment_command_64& 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 Serialize(SerializationContext&, std::string_view name, const std::vector& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); -SHAREDCACHE_FFI_API void Serialize(SerializationContext&, std::string_view name, const build_version_command& 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&, std::string_view name, const std::vector& b); +SHAREDCACHE_FFI_API void Serialize(SerializationContext&, const build_tool_version& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); - } // namespace SharedCacheCore #endif // SHAREDCACHE_METADATASERIALIZABLE_HPP diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 97cc796863..652365985a 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -3325,79 +3325,50 @@ namespace SharedCacheCore { void SharedCache::Store(SerializationContext& context) const { - context.doc.AddMember("metadataVersion", METADATA_VERSION, context.allocator); + Serialize(context, "metadataVersion", METADATA_VERSION); MSS(m_viewState); MSS_CAST(m_cacheFormat, uint8_t); MSS(m_imageStarts); MSS(m_baseFilePath); - rapidjson::Value headers(rapidjson::kArrayType); + + Serialize(context, "headers"); + context.writer.StartArray(); for (auto& [k, v] : m_headers) { - headers.PushBack(v.AsDocument(), context.allocator); + context.writer.StartObject(); + v.Store(context); + context.writer.EndObject(); } - context.doc.AddMember("headers", headers, context.allocator); - // std::vector>>>> - // m_exportInfos std::vector>>>> exportInfos; - rapidjson::Document exportInfos(rapidjson::kArrayType); + context.writer.EndArray(); + Serialize(context, "exportInfos"); + context.writer.StartArray(); for (const auto& pair1 : m_exportInfos) { - rapidjson::Value subObj(rapidjson::kObjectType); - rapidjson::Value subArr(rapidjson::kArrayType); + context.writer.StartObject(); + Serialize(context, "key", pair1.first); + Serialize(context, "value"); + context.writer.StartArray(); 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); + context.writer.StartObject(); + Serialize(context, "key", pair2.first); + Serialize(context, "val1", pair2.second.first); + Serialize(context, "val2", pair2.second.second); + context.writer.EndObject(); } - - subObj.AddMember("key", pair1.first, context.allocator); - subObj.AddMember("value", subArr, context.allocator); - - exportInfos.PushBack(subObj, context.allocator); + context.writer.EndArray(); + context.writer.EndObject(); } - context.doc.AddMember("exportInfos", exportInfos, context.allocator); + context.writer.EndArray(); - 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); + 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 SharedCache::Load(DeserializationContext& context) diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index 0c871c3e21..4444f8473a 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -67,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) From 9060301b2269fbebcea1696248b705a4eafb4563 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Wed, 20 Nov 2024 18:00:19 -0800 Subject: [PATCH 6/6] Serialization fixes after switch to SAX-style JSON writing API 1. Continue to serialize the `cputype` / `cpusubtype` fields of `mach_header_64` as unsigned, despite them being signed. This preserves compatibility with the existing metadata version. 2. Add the `Serialize` declaration for the special `std::pair>` overload to the header. This ensures it will be favored over the generic `std::pair` template function and preserves the serialization used with the existing metadata version. --- view/sharedcache/core/MetadataSerializable.cpp | 7 +++++-- view/sharedcache/core/MetadataSerializable.hpp | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/view/sharedcache/core/MetadataSerializable.cpp b/view/sharedcache/core/MetadataSerializable.cpp index 0fa712b17a..ad8959f262 100644 --- a/view/sharedcache/core/MetadataSerializable.cpp +++ b/view/sharedcache/core/MetadataSerializable.cpp @@ -206,8 +206,11 @@ void Deserialize(DeserializationContext& context, std::string_view name, std::ve void Serialize(SerializationContext& context, const mach_header_64& value) { context.writer.StartArray(); Serialize(context, value.magic); - Serialize(context, value.cputype); - Serialize(context, value.cpusubtype); + // 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(value.cputype)); + Serialize(context, static_cast(value.cpusubtype)); Serialize(context, value.filetype); Serialize(context, value.ncmds); Serialize(context, value.sizeofcmds); diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp index 5a39f5f67b..7b44ccbdbf 100644 --- a/view/sharedcache/core/MetadataSerializable.hpp +++ b/view/sharedcache/core/MetadataSerializable.hpp @@ -211,6 +211,7 @@ SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::strin 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>& 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& b); SHAREDCACHE_FFI_API void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b);