From a7382f9efe1d6dbd81aad4f7c1eb6aa0f301b2b4 Mon Sep 17 00:00:00 2001 From: York Jasper Niebuhr Date: Mon, 27 Oct 2025 20:40:12 +0100 Subject: [PATCH] Finalizer association of symbols with pinpoint data --- finalize/accumulation.h | 16 ++++++++ finalize/finalize.cpp | 17 +++++++-- finalize/symbol_collection.cpp | 59 +++++++++++++++++++++++------ finalize/symbol_collection.h | 1 + pinpoint/stage1/asm_offset_pass.cpp | 8 ++++ 5 files changed, 86 insertions(+), 15 deletions(-) diff --git a/finalize/accumulation.h b/finalize/accumulation.h index f9a858e..4a347d3 100644 --- a/finalize/accumulation.h +++ b/finalize/accumulation.h @@ -4,14 +4,28 @@ #include #include #include +#include +#include struct IPIN { + struct HIT { + uint64_t vaddr; + uint32_t imm_offset; + uint32_t imm_size; + }; + std::string symbol; std::size_t local_target; std::size_t field_offset; + + std::optional hit; }; struct DPIN { + struct HIT { + uint64_t vaddr; + }; + struct COMPONENT { std::size_t offset; std::size_t level; @@ -20,6 +34,8 @@ struct DPIN { std::string symbol; std::list components; + + std::optional hit; }; struct FIELD { diff --git a/finalize/finalize.cpp b/finalize/finalize.cpp index 9636031..8274950 100644 --- a/finalize/finalize.cpp +++ b/finalize/finalize.cpp @@ -89,12 +89,21 @@ int main(int argc, char** argv) { return 1; } + if (!associate_symbols()) { + std::cerr << "Failed to associate symbols with accumulated data!" << std::endl; + return 1; + } + // TODO /* - 1. Find virtual address and file address for all pins - 2. Emit patcher program into final executable and set __spslr_program - -> make all patcher addresses relative to &__spslr_program - -> dpatch entries ordered by level (high levels/nest depths first) + 1. For each ipin, disassemble instruction and find immediate offset + 2. Find __spslr_program + 3. Serialize entire patcher program + -> all pin addresses relative to &__spslr_program + -> dpatch entry components ordered by level + 4. Add new section .spslr with patcher program + 5. Set __spslr_program to (&.spslr - &__spslr_program) + 6. Output final program */ } diff --git a/finalize/symbol_collection.cpp b/finalize/symbol_collection.cpp index 025b43d..f30a709 100644 --- a/finalize/symbol_collection.cpp +++ b/finalize/symbol_collection.cpp @@ -1,20 +1,10 @@ #include "symbol_collection.h" +#include "accumulation.h" #include #define SPSLR_PINPOINT_CU_UID_LABEL "__spslr_cu_" /* suffixed with "" */ -/* -struct GlobalSymtab { - std::unordered_map symbols; -}; - -struct LocalSymtab { - std::string cu; - std::unordered_map symbols; -}; -*/ - using namespace LIEF::ELF; GlobalSymtab global_syms; @@ -91,3 +81,50 @@ bool collect_symbols(const std::unique_ptr& bin) { return true; } +bool associate_symbols() { + // Fetch symbols for each accumulated CU + for (auto& [cu_uid, cu] : units) { + if (!local_syms.contains(cu_uid)) { + std::cerr << "Could not find symbols for unit UID " << cu_uid << std::endl; + return false; + } + + const LocalSymtab& lsyms = local_syms.at(cu_uid); + + for (auto& [ipin_sym, ipin] : cu.ipins) { + if (!lsyms.symbols.contains(ipin_sym)) { + std::cerr << "Unable to locate symbol \"" << ipin_sym << "\" in unit " << cu_uid << std::endl; + return false; + } + + ipin.hit.emplace(); + ipin.hit->vaddr = lsyms.symbols.at(ipin_sym); + ipin.hit->imm_offset = 0; + ipin.hit->imm_size = 0; + } + + for (auto& [dpin_sym, dpin] : cu.dpins) { + if (!lsyms.symbols.contains(dpin_sym)) { + std::cerr << "Unable to locate symbol \"" << dpin_sym << "\" in unit " << cu_uid << std::endl; + return false; + } + + dpin.hit.emplace(); + dpin.hit->vaddr = lsyms.symbols.at(dpin_sym); + } + } + + // Fetch global symbols for global dpins + for (auto& [dpin_sym, dpin] : global_dpins) { + if (!global_syms.symbols.contains(dpin_sym)) { + std::cerr << "Unable to locate global symbol \"" << dpin_sym << "\"" << std::endl; + return false; + } + + dpin.hit.emplace(); + dpin.hit->vaddr = global_syms.symbols.at(dpin_sym); + } + + return true; +} + diff --git a/finalize/symbol_collection.h b/finalize/symbol_collection.h index 4f73882..9c37703 100644 --- a/finalize/symbol_collection.h +++ b/finalize/symbol_collection.h @@ -19,4 +19,5 @@ extern GlobalSymtab global_syms; extern std::unordered_map local_syms; bool collect_symbols(const std::unique_ptr& bin); +bool associate_symbols(); diff --git a/pinpoint/stage1/asm_offset_pass.cpp b/pinpoint/stage1/asm_offset_pass.cpp index 3b529b4..5e97088 100644 --- a/pinpoint/stage1/asm_offset_pass.cpp +++ b/pinpoint/stage1/asm_offset_pass.cpp @@ -76,6 +76,14 @@ static gimple* make_stage1_pin(tree lhs, UID target, std::size_t offset) { if (!new_gasm) return nullptr; + /* + TODO + These asm statements should not actually be volatile. + Instead, a final pass has to detect which have been removed. + Only data about still present ipins should be given to finalizer! + */ + gimple_asm_set_volatile(new_gasm, true); + pins.emplace(uid, pin); return new_gasm; }