#include "accumulation.h" #include #include #include namespace fs = std::filesystem; static std::size_t next_global_target_uid = 0; std::unordered_map targets; std::unordered_map units; // Two different types with exactly same field structure will not cause problems if simply randomized together static bool global_target_field_cmp(const TARGET& a, const TARGET& b) { if (a.fields.size() != b.fields.size()) return false; auto ita = a.fields.begin(); auto itb = b.fields.begin(); for (; ita != a.fields.end() && itb != b.fields.end(); ++ita, ++itb) { const FIELD& fa = ita->second; const FIELD& fb = itb->second; if (fa.offset != fb.offset) return false; if (fa.size != fb.size) return false; if (fa.alignment != fb.alignment) return false; if (fa.flags != fb.flags) return false; } return true; } static bool global_target_cmp(const TARGET& a, const TARGET& b) { // Note -> Later, use hash of type (generated by pinpoint plugin) if (a.name != b.name) return false; if (a.size != b.size || !global_target_field_cmp(a, b)) { std::cerr << "WARNING: Got different definitions of \"" << a.name << "\" -> detached randomization" << std::endl; return false; } return true; } static std::size_t accumulate_global_target(TARGET&& target) { for (const auto& [guid, gtarget] : targets) { if (global_target_cmp(gtarget, target)) return guid; } std::size_t guid = next_global_target_uid++; targets.emplace(guid, std::move(target)); return guid; } /* .spslr: SPSLR target f f ... ipin