Instruction pin listing
This commit is contained in:
parent
59eb91dcdf
commit
7d1b68d8ed
@ -1,8 +1,10 @@
|
||||
#include <iostream>
|
||||
#include <final.h>
|
||||
#include <stage0.h>
|
||||
#include <stage1.h>
|
||||
|
||||
#include <safe-input.h>
|
||||
#include <pinpoint_config.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 .)
|
||||
|
||||
@ -4,7 +4,11 @@
|
||||
|
||||
static std::list<DataPin> pins;
|
||||
|
||||
const std::list<DataPin>& dpins() {
|
||||
void DataPin::reset() {
|
||||
pins.clear();
|
||||
}
|
||||
|
||||
const std::list<DataPin>& DataPin::all() {
|
||||
return pins;
|
||||
}
|
||||
|
||||
|
||||
8
pinpoint/stage0/on_start_unit.cpp
Normal file
8
pinpoint/stage0/on_start_unit.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stage0.h>
|
||||
#include <stage1.h>
|
||||
|
||||
void on_start_unit(void* plugin_data, void* user_data) {
|
||||
TargetType::reset();
|
||||
DataPin::reset();
|
||||
S1InstructionPin::reset();
|
||||
}
|
||||
@ -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<UID, TargetType>& 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<Component> components;
|
||||
};
|
||||
|
||||
const std::list<DataPin>& dpins();
|
||||
static void reset();
|
||||
static const std::list<DataPin>& 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);
|
||||
|
||||
@ -216,6 +216,11 @@ const std::unordered_map<UID, TargetType>& TargetType::all() {
|
||||
return targets;
|
||||
}
|
||||
|
||||
void TargetType::reset() {
|
||||
targets.clear();
|
||||
next_uid = 0;
|
||||
}
|
||||
|
||||
static bool foreach_record_field(tree t, std::function<bool(const TargetType::Field&)> callback) {
|
||||
if (!t || TREE_CODE(t) != RECORD_TYPE)
|
||||
return false;
|
||||
|
||||
@ -4,8 +4,17 @@
|
||||
#include <pinpoint_error.h>
|
||||
#include <pinpoint_config.h>
|
||||
|
||||
static UID next_separator_uid = 0;
|
||||
static std::unordered_map<UID, S1Separator> separators;
|
||||
static UID next_pin_uid = 0;
|
||||
static std::unordered_map<UID, S1InstructionPin> pins;
|
||||
|
||||
const std::unordered_map<UID, S1InstructionPin>& 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;
|
||||
|
||||
@ -3,13 +3,16 @@
|
||||
#include <stage0.h>
|
||||
#include <safe-gimple.h>
|
||||
|
||||
struct S1Separator {
|
||||
struct S1InstructionPin {
|
||||
enum ARCH {
|
||||
NONE, X86_64
|
||||
} arch;
|
||||
|
||||
UID target;
|
||||
std::size_t offset;
|
||||
|
||||
static const std::unordered_map<UID, S1InstructionPin>& all();
|
||||
static void reset();
|
||||
};
|
||||
|
||||
struct asm_offset_pass : gimple_opt_pass {
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user