diff --git a/pinpoint/final/on_finish_unit.cpp b/pinpoint/final/on_finish_unit.cpp index 7c5e603..f8ffad7 100644 --- a/pinpoint/final/on_finish_unit.cpp +++ b/pinpoint/final/on_finish_unit.cpp @@ -1,8 +1,10 @@ #include #include #include +#include #include +#include void on_finish_unit(void* plugin_data, void* user_data) { /* @@ -18,10 +20,15 @@ void on_finish_unit(void* plugin_data, void* user_data) { for (const auto& [uid, target] : TargetType::all()) std::cout << " Target " << uid << " -> \"" << target.name() << "\" (" << target.size() << ")" << std::endl; - for (const DataPin& dpin : dpins()) { + for (const DataPin& dpin : DataPin::all()) { std::cout << " " << (dpin.global ? "Global" : "Local") << " data pin at symbol \"" << dpin.symbol << "\":" << std::endl; for (const DataPin::Component& c : dpin.components) std::cout << " offset " << c.offset << " (level " << c.level << ") -> target " << c.target << std::endl; } + + for (const auto& [uid, ipin] : S1InstructionPin::all()) { + std::cout << " Instruction pin at symbol \"" << SPSLR_PINPOINT_STAGE1_SEPARATOR + << "_" << uid << "\" -> target " << ipin.target << ", offset " << ipin.offset << std::endl; + } } diff --git a/pinpoint/pinpoint.cpp b/pinpoint/pinpoint.cpp index 25072d1..b113f2d 100644 --- a/pinpoint/pinpoint.cpp +++ b/pinpoint/pinpoint.cpp @@ -17,6 +17,7 @@ int plugin_init(struct plugin_name_args* plugin_info, struct plugin_gcc_version* // Stage 0 -> separates relevant field offsets into function calls + register_callback(plugin_info->base_name, PLUGIN_START_UNIT, on_start_unit, NULL); register_callback(plugin_info->base_name, PLUGIN_ATTRIBUTES, on_register_attributes, NULL); register_callback(plugin_info->base_name, PLUGIN_FINISH_TYPE, on_finish_type, NULL); register_callback(plugin_info->base_name, PLUGIN_BUILD_COMPONENT_REF, on_preserve_component_ref, NULL); diff --git a/pinpoint/stage0/CMakeLists.txt b/pinpoint/stage0/CMakeLists.txt index 682969f..c838411 100644 --- a/pinpoint/stage0/CMakeLists.txt +++ b/pinpoint/stage0/CMakeLists.txt @@ -1,3 +1,3 @@ target_sources(spslr_pinpoint PRIVATE on_register_attributes.cpp on_finish_type.cpp on_preserve_component_ref.cpp - on_finish_decl.cpp target.cpp separator.cpp separate_offset_pass.cpp) + on_finish_decl.cpp on_start_unit.cpp target.cpp separator.cpp separate_offset_pass.cpp) target_include_directories(spslr_pinpoint PRIVATE .) diff --git a/pinpoint/stage0/on_finish_decl.cpp b/pinpoint/stage0/on_finish_decl.cpp index dd0ec8c..30c4b8e 100644 --- a/pinpoint/stage0/on_finish_decl.cpp +++ b/pinpoint/stage0/on_finish_decl.cpp @@ -4,7 +4,11 @@ static std::list pins; -const std::list& dpins() { +void DataPin::reset() { + pins.clear(); +} + +const std::list& DataPin::all() { return pins; } diff --git a/pinpoint/stage0/on_start_unit.cpp b/pinpoint/stage0/on_start_unit.cpp new file mode 100644 index 0000000..c94f8da --- /dev/null +++ b/pinpoint/stage0/on_start_unit.cpp @@ -0,0 +1,8 @@ +#include +#include + +void on_start_unit(void* plugin_data, void* user_data) { + TargetType::reset(); + DataPin::reset(); + S1InstructionPin::reset(); +} diff --git a/pinpoint/stage0/stage0.h b/pinpoint/stage0/stage0.h index 9ae9580..49caa36 100644 --- a/pinpoint/stage0/stage0.h +++ b/pinpoint/stage0/stage0.h @@ -54,6 +54,7 @@ public: 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(); + static void reset(); private: friend void on_finish_type(void*, void*); bool fetch_fields(bool redo = false); @@ -79,14 +80,16 @@ struct DataPin { std::string symbol; bool global; std::list components; -}; -const std::list& dpins(); + static void reset(); + static const std::list& all(); +}; void on_register_attributes(void* plugin_data, void* user_data); void on_finish_type(void* plugin_data, void* user_data); void on_preserve_component_ref(void* plugin_data, void* user_data); void on_finish_decl(void* plugin_data, void* user_data); +void on_start_unit(void* plugin_data, void* user_data); struct separate_offset_pass : gimple_opt_pass { separate_offset_pass(gcc::context* ctxt); diff --git a/pinpoint/stage0/target.cpp b/pinpoint/stage0/target.cpp index 3d1764c..3df8bd7 100644 --- a/pinpoint/stage0/target.cpp +++ b/pinpoint/stage0/target.cpp @@ -216,6 +216,11 @@ const std::unordered_map& TargetType::all() { return targets; } +void TargetType::reset() { + targets.clear(); + next_uid = 0; +} + static bool foreach_record_field(tree t, std::function callback) { if (!t || TREE_CODE(t) != RECORD_TYPE) return false; diff --git a/pinpoint/stage1/asm_offset_pass.cpp b/pinpoint/stage1/asm_offset_pass.cpp index 5e3835f..d790142 100644 --- a/pinpoint/stage1/asm_offset_pass.cpp +++ b/pinpoint/stage1/asm_offset_pass.cpp @@ -4,8 +4,17 @@ #include #include -static UID next_separator_uid = 0; -static std::unordered_map separators; +static UID next_pin_uid = 0; +static std::unordered_map pins; + +const std::unordered_map& S1InstructionPin::all() { + return pins; +} + +void S1InstructionPin::reset() { + pins.clear(); + next_pin_uid = 0; +} static char asm_str_buf[1024]; @@ -20,14 +29,14 @@ static const char* make_asm_x86_64(UID uid) { return asm_str_buf; } -static const char* make_asm(UID uid, S1Separator::ARCH& arch) { +static const char* make_asm(UID uid, S1InstructionPin::ARCH& arch) { #if defined(__x86_64__) || defined(__amd64__) - arch = S1Separator::X86_64; + arch = S1InstructionPin::X86_64; return make_asm_x86_64(uid); #else static_assert(false, "Architecture-independent RTL recovery pass is not yet implemented"); - arch = S1Separator::NONE; + arch = S1InstructionPin::NONE; return make_asm_noarch(uid); #endif } @@ -39,19 +48,19 @@ static tree make_asm_operand(const char* constraint_text, tree operand_tree) { return outer_list; } -static gimple* make_stage1_separator(tree lhs, UID target, std::size_t offset) { +static gimple* make_stage1_pin(tree lhs, UID target, std::size_t offset) { if (!lhs) return nullptr; - UID uid = next_separator_uid++; + UID uid = next_pin_uid++; - S1Separator separator; - separator.target = target; - separator.offset = offset; + S1InstructionPin pin; + pin.target = target; + pin.offset = offset; - const char* asm_str = make_asm(uid, separator.arch); + const char* asm_str = make_asm(uid, pin.arch); if (!asm_str) - pinpoint_fatal("make_stage1_separator failed to generate asm string"); + pinpoint_fatal("make_stage1_pin failed to generate asm string"); tree arg0 = build_int_cst(size_type_node, target); tree arg1 = build_int_cst(size_type_node, offset); @@ -67,11 +76,11 @@ static gimple* make_stage1_separator(tree lhs, UID target, std::size_t offset) { if (!new_gasm) return nullptr; - separators.emplace(uid, separator); + pins.emplace(uid, pin); return new_gasm; } -static void separator_update_ssa_def(function* fn, gimple* old_def, gimple* new_def) { +static void pin_update_ssa_def(function* fn, gimple* old_def, gimple* new_def) { if (!fn || !old_def) return; @@ -90,7 +99,7 @@ static void separator_update_ssa_def(function* fn, gimple* old_def, gimple* new_ } } -static void separator_assemble_maybe(function* fn, gimple_stmt_iterator* gsi) { +static void pin_assemble_maybe(function* fn, gimple_stmt_iterator* gsi) { if (!gsi) return; @@ -104,12 +113,12 @@ static void separator_assemble_maybe(function* fn, gimple_stmt_iterator* gsi) { if (!is_stage0_separator(stmt, target, offset)) return; - gimple* replacement = make_stage1_separator(gimple_call_lhs(stmt), target, offset); + gimple* replacement = make_stage1_pin(gimple_call_lhs(stmt), target, offset); if (!replacement) pinpoint_fatal(); gsi_replace(gsi, replacement, true); - separator_update_ssa_def(fn, stmt, replacement); + pin_update_ssa_def(fn, stmt, replacement); } static const pass_data asm_offset_pass_data = { @@ -130,7 +139,7 @@ unsigned int asm_offset_pass::execute(function* fn) { basic_block bb; FOR_EACH_BB_FN(bb, fn) { for (gimple_stmt_iterator gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) - separator_assemble_maybe(fn, &gsi); + pin_assemble_maybe(fn, &gsi); } return 0; diff --git a/pinpoint/stage1/stage1.h b/pinpoint/stage1/stage1.h index 211e484..0dc65a9 100644 --- a/pinpoint/stage1/stage1.h +++ b/pinpoint/stage1/stage1.h @@ -3,13 +3,16 @@ #include #include -struct S1Separator { +struct S1InstructionPin { enum ARCH { NONE, X86_64 } arch; UID target; std::size_t offset; + + static const std::unordered_map& all(); + static void reset(); }; struct asm_offset_pass : gimple_opt_pass { diff --git a/subject/main.c b/subject/main.c index 30729e3..737d062 100644 --- a/subject/main.c +++ b/subject/main.c @@ -3,7 +3,7 @@ int second_pid(); int third_pid(); -extern struct task_struct global = { .pid = 42, .comm = "main_global" }; +struct task_struct global = { .pid = 42, .comm = "main_global" }; int main(void) {