#include #include #include #include #include #include #include int plugin_is_GPL_compatible; int plugin_init(struct plugin_name_args* plugin_info, struct plugin_gcc_version* version) { if (!plugin_default_version_check(version, &gcc_version)) { std::cerr << "spslr_pinpoint -> GCC version mismatch" << std::endl; return 1; } for (int i = 0; i < plugin_info->argc; ++i) { if (!strcmp(plugin_info->argv[i].key, "metadir")) set_meta_dir(plugin_info->argv[i].value); } if (!has_meta_dir()) { std::cerr << "spslr_pinpoint -> missing meta directory argument" << std::endl; return 1; } // 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); register_callback(plugin_info->base_name, PLUGIN_FINISH_DECL, on_finish_decl, NULL); struct register_pass_info separate_offset_pass_info; separate_offset_pass_info.pass = new separate_offset_pass(nullptr); separate_offset_pass_info.ref_pass_instance_number = 1; separate_offset_pass_info.reference_pass_name = "cfg"; separate_offset_pass_info.pos_op = PASS_POS_INSERT_AFTER; register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &separate_offset_pass_info); // Stage 1 -> stage 0 separators are replaced with inline assembly markers struct register_pass_info asm_offset_pass_info; asm_offset_pass_info.pass = new asm_offset_pass(nullptr); asm_offset_pass_info.ref_pass_instance_number = 1; asm_offset_pass_info.reference_pass_name = "separate_offset"; asm_offset_pass_info.pos_op = PASS_POS_INSERT_AFTER; register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &asm_offset_pass_info); // Stage 2 -> stage 1 markers are replaced with assembled offset-load instructions with labeled immediates struct register_pass_info rtl_pin_lower_pass_info; rtl_pin_lower_pass_info.pass = new rtl_pin_lower_pass(nullptr); rtl_pin_lower_pass_info.ref_pass_instance_number = 1; rtl_pin_lower_pass_info.reference_pass_name = "final"; rtl_pin_lower_pass_info.pos_op = PASS_POS_INSERT_BEFORE; register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &rtl_pin_lower_pass_info); // Final stage -> dump accumulated information register_callback(plugin_info->base_name, PLUGIN_FINISH_UNIT, on_finish_unit, NULL); return 0; }