From 6b716fbd56b4f4f5b50c1c2276d53ad9a4e00848 Mon Sep 17 00:00:00 2001 From: York Jasper Niebuhr Date: Sun, 26 Oct 2025 12:53:35 +0100 Subject: [PATCH] Target type size --- docs/writeup.txt | 10 ++++++++++ finalize/finalize.cpp | 5 +++-- pinpoint/final/on_finish_unit.cpp | 3 +++ pinpoint/stage0/stage0.h | 4 ++++ pinpoint/stage0/target.cpp | 28 ++++++++++++++++++++++++++-- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/docs/writeup.txt b/docs/writeup.txt index a6ca7d0..a1c79bc 100644 --- a/docs/writeup.txt +++ b/docs/writeup.txt @@ -34,3 +34,13 @@ Custom UNSPECs can not get through vregs or a few later passes -> architecture specific, dynamic operands though -> can not get optimized (O1+ does optimizations in RTL, mostly after vregs) -> could replace asm with normal "set" RTL close to final pass to remove architecture dependence + +Plugin is per compilation unit + -> static label counters start at 0 for each + -> labels are local symbols in symbtab + -> symtab entries like "df *ABS* 0000000000000000 main.c" indicate block begin for new file + -> "main.c" and "sub/main.c" both only specify "main.c" (no way to differentiate) + -> emit UID symbol per CU to match symbol block to unique label set + -> structs with same name can habe different definitions in different CUs (disallow this for now) + -> anonymous structs can not really be matched between CUs without type hash (disallow this for now) + -> later, use hash(type) to match structs between CUs to randomize as one diff --git a/finalize/finalize.cpp b/finalize/finalize.cpp index 5400f14..b02ab99 100644 --- a/finalize/finalize.cpp +++ b/finalize/finalize.cpp @@ -4,7 +4,7 @@ .spslr: SPSLR_FINALIZE_HEADER -target +target f f ... @@ -20,7 +20,8 @@ dpin Datapins for same var/symbol are randomized in order of their level, from bottom of nest to top The CU uid symbol helps differentiating between e.g. "file.c" and "sub/file.c" (symbtab has no idea) -Between CUs, types with the same hash are considered to be the same type +Between CUs, types with the same name HAVE TO HAVE the same layout -> randomized together +To begin with, anonymous types are not allowed for randomization (later solved with hash(type) instead of name)! */ diff --git a/pinpoint/final/on_finish_unit.cpp b/pinpoint/final/on_finish_unit.cpp index c87645b..8ef2502 100644 --- a/pinpoint/final/on_finish_unit.cpp +++ b/pinpoint/final/on_finish_unit.cpp @@ -15,6 +15,9 @@ void on_finish_unit(void* plugin_data, void* user_data) { std::cout << "Finishing unit \"" << lbasename(main_input_filename) << "\" ..." << std::endl; + for (const auto& [uid, target] : TargetType::all()) + std::cout << " Target " << uid << " -> \"" << target.name() << "\" (" << target.size() << ")" << std::endl; + for (const DataPin& dpin : dpins()) { std::cout << " Data pin at symbol \"" << dpin.symbol << "\":" << std::endl; for (const DataPin::Component& c : dpin.components) diff --git a/pinpoint/stage0/stage0.h b/pinpoint/stage0/stage0.h index e8da7a0..30e2a22 100644 --- a/pinpoint/stage0/stage0.h +++ b/pinpoint/stage0/stage0.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include #include @@ -27,6 +28,7 @@ private: UID m_uid; std::size_t m_flags; tree m_main_variant; + std::size_t m_size; // Fields are identified by their offsets std::map m_fields; @@ -44,12 +46,14 @@ public: std::string name() const; const Field* field(std::size_t off, bool exact = true) const; UID uid() const; + std::size_t size() const; static void add(tree t); static std::size_t count(); static const TargetType* find(tree t); // O(n) static const TargetType* find(UID uid); // O(1) static bool reference(tree ref, UID& target, std::size_t& offset); + static const std::unordered_map& all(); private: friend void on_finish_type(void*, void*); bool fetch_fields(bool redo = false); diff --git a/pinpoint/stage0/target.cpp b/pinpoint/stage0/target.cpp index 2940c69..3d1764c 100644 --- a/pinpoint/stage0/target.cpp +++ b/pinpoint/stage0/target.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -14,7 +13,7 @@ static tree get_record_main_variant(tree t) { return TYPE_MAIN_VARIANT(t); } -TargetType::TargetType(tree t) : m_uid{ UID_INVALID }, m_flags{ 0 } { +TargetType::TargetType(tree t) : m_uid{ UID_INVALID }, m_flags{ 0 }, m_size{ 0 } { if (!(m_main_variant = get_record_main_variant(t))) return; @@ -75,6 +74,13 @@ UID TargetType::uid() const { return m_uid; } +std::size_t TargetType::size() const { + if (!valid() || !(m_flags & FLAG_FIELDS)) + return 0; + + return m_size; +} + void TargetType::add(tree t) { if (find(t) != nullptr) return; @@ -206,6 +212,10 @@ bool TargetType::reference(tree ref, UID& target, std::size_t& offset) { return true; } +const std::unordered_map& TargetType::all() { + return targets; +} + static bool foreach_record_field(tree t, std::function callback) { if (!t || TREE_CODE(t) != RECORD_TYPE) return false; @@ -285,6 +295,20 @@ bool TargetType::fetch_fields(bool redo) { if (!foreach_record_field(m_main_variant, per_field_callback)) return false; + // Get struct size + + tree size_tree = TYPE_SIZE(m_main_variant); + if (!size_tree || TREE_CODE(size_tree) != INTEGER_CST) + return false; + + HOST_WIDE_INT size_bits = tree_to_uhwi(size_tree); + if (size_bits < 0 || size_bits % 8 != 0) + return false; + + m_size = static_cast(size_bits / 8); + + // Everything done + m_fields = std::move(tmp_fields); m_flags |= FLAG_FIELDS; return true;