Finalizer association of symbols with pinpoint data

This commit is contained in:
York Jasper Niebuhr 2025-10-27 20:40:12 +01:00
parent a55009342f
commit a7382f9efe
5 changed files with 86 additions and 15 deletions

View File

@ -4,14 +4,28 @@
#include <unordered_map>
#include <map>
#include <list>
#include <optional>
#include <cstdint>
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> 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<COMPONENT> components;
std::optional<HIT> hit;
};
struct FIELD {

View File

@ -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
*/
}

View File

@ -1,20 +1,10 @@
#include "symbol_collection.h"
#include "accumulation.h"
#include <iostream>
#define SPSLR_PINPOINT_CU_UID_LABEL "__spslr_cu_" /* suffixed with "<uid>" */
/*
struct GlobalSymtab {
std::unordered_map<std::string, VADDR> symbols;
};
struct LocalSymtab {
std::string cu;
std::unordered_map<std::string, VADDR> symbols;
};
*/
using namespace LIEF::ELF;
GlobalSymtab global_syms;
@ -91,3 +81,50 @@ bool collect_symbols(const std::unique_ptr<LIEF::ELF::Binary>& 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;
}

View File

@ -19,4 +19,5 @@ extern GlobalSymtab global_syms;
extern std::unordered_map<std::string, LocalSymtab> local_syms;
bool collect_symbols(const std::unique_ptr<LIEF::ELF::Binary>& bin);
bool associate_symbols();

View File

@ -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;
}