diff --git a/pinpoint/final/final.h b/pinpoint/final/final.h index 539e432..aaf370f 100644 --- a/pinpoint/final/final.h +++ b/pinpoint/final/final.h @@ -1,3 +1,12 @@ #pragma once void on_finish_unit(void* plugin_data, void* user_data); + +void set_src_dir(const char* dir); +void set_dst_dir(const char* dir); + +bool has_src_dir(); +bool has_dst_dir(); + +const char* get_src_dir(); +const char* get_dst_dir(); diff --git a/pinpoint/final/on_finish_unit.cpp b/pinpoint/final/on_finish_unit.cpp index 7d6c295..708b173 100644 --- a/pinpoint/final/on_finish_unit.cpp +++ b/pinpoint/final/on_finish_unit.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include @@ -9,48 +11,107 @@ #include #include -unsigned char cu_uid_md5[16]; -char cu_uid_hex[33]; +static bool src_dir_known = false, dst_dir_known = false; +static std::string src_dir, dst_dir; + +void set_src_dir(const char* dir) { + if (!dir) { + src_dir_known = false; + return; + } + + src_dir = std::string{ dir }; + src_dir_known = true; +} + +void set_dst_dir(const char* dir) { + if (!dir) { + dst_dir_known = false; + return; + } + + dst_dir = std::string{ dir }; + dst_dir_known = true; +} + +bool has_src_dir() { + return src_dir_known; +} + +bool has_dst_dir() { + return dst_dir_known; +} + +const char* get_src_dir() { + if (!src_dir_known) + return nullptr; + + return src_dir.c_str(); +} + +const char* get_dst_dir() { + if (!dst_dir_known) + return nullptr; + + return dst_dir.c_str(); +} + +static std::filesystem::path relative_src_path() { + const char* src_root = get_src_dir(); + if (!src_root) + pinpoint_fatal("relative_src_path is missing the source root path"); -static const unsigned char* calculate_cu_uid_md5() { if (!main_input_filename) - return nullptr; + pinpoint_fatal("relative_src_path is missing the current source file path"); - md5_buffer(main_input_filename, strlen(main_input_filename), cu_uid_md5); - return cu_uid_md5; + std::filesystem::path abs_current_src = std::filesystem::absolute(main_input_filename); + std::filesystem::path abs_root_src = std::filesystem::absolute(src_root); + return std::filesystem::relative(abs_current_src, abs_root_src); } -static const char* calculate_cu_uid_hex() { - const unsigned char* digest = calculate_cu_uid_md5(); - if (!digest) - return nullptr; +static std::filesystem::path spslr_output_file(const std::filesystem::path& infile) { + const char* dst_root = get_dst_dir(); + if (!dst_root) + pinpoint_fatal("spslr_output_file is missing the destination root path"); - for (int i = 0; i < 16; ++i) - sprintf(cu_uid_hex + 2*i, "%02x", digest[i]); - - cu_uid_hex[32] = '\0'; - return cu_uid_hex; + std::filesystem::path abs_root_dst = std::filesystem::absolute(dst_root); + return (abs_root_dst / infile).string() + SPSLR_PINFILE_EXTENSION; } -static bool emit_cu_uid_label(const char* uid) { +static std::string calculate_cu_uid(const std::filesystem::path& infile) { + unsigned char md5_digest[16]; + + const char* infile_cstr = infile.c_str(); + md5_buffer(infile_cstr, strlen(infile_cstr), md5_digest); + + char md5_digest_hex[33] = {}; + for (int i = 0; i < 16; i++) + sprintf(md5_digest_hex + i * 2, "%02x", md5_digest[i]); + + return std::string{ md5_digest_hex }; +} + +static void emit_cu_uid_label(const std::string& uid) { char label[128]; - snprintf(label, sizeof(label), SPSLR_PINPOINT_CU_UID_LABEL "%s", uid); + snprintf(label, sizeof(label), SPSLR_PINPOINT_CU_UID_LABEL "%s", uid.c_str()); fprintf(asm_out_file, "%s:\n", label); - return true; } void on_finish_unit(void* plugin_data, void* user_data) { - const char* cu_uid = calculate_cu_uid_hex(); - if (!cu_uid) - pinpoint_fatal("on_finish_unit failed to calculate compilation unit UID"); + std::filesystem::path infile = relative_src_path(); + std::filesystem::path outfile = spslr_output_file(infile); - if (!emit_cu_uid_label(cu_uid)) - pinpoint_fatal("on_finish_unit failed to emit CU UID label"); + std::cout << "Finishing unit " << infile << " ..." << std::endl; + std::cout << " Dumping SPSLR data accumulation to " << outfile << std::endl; - std::cout << "Finishing unit \"" << lbasename(main_input_filename) << "\" ..." << std::endl; + std::string cu_uid = calculate_cu_uid(infile); std::cout << " Unit UID is 0x" << cu_uid << std::endl; + emit_cu_uid_label(cu_uid); + + // TODO -> Dump to outfile + for (const auto& [uid, target] : TargetType::all()) std::cout << " Target " << uid << " -> \"" << target.name() << "\" (" << target.size() << ")" << std::endl; diff --git a/pinpoint/pinpoint.cpp b/pinpoint/pinpoint.cpp index b113f2d..e62bb14 100644 --- a/pinpoint/pinpoint.cpp +++ b/pinpoint/pinpoint.cpp @@ -15,6 +15,23 @@ int plugin_init(struct plugin_name_args* plugin_info, struct plugin_gcc_version* return 1; } + for (int i = 0; i < plugin_info->argc; ++i) { + if (!strcmp(plugin_info->argv[i].key, "srcdir")) + set_src_dir(plugin_info->argv[i].value); + else if (!strcmp(plugin_info->argv[i].key, "dstdir")) + set_dst_dir(plugin_info->argv[i].value); + } + + if (!has_src_dir()) { + std::cerr << "spslr_pinpoint -> missing source directory argument" << std::endl; + return 1; + } + + if (!has_dst_dir()) { + std::cerr << "spslr_pinpoint -> missing destination 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); diff --git a/pinpoint/pinpoint_config.h b/pinpoint/pinpoint_config.h index 8666d27..c58e44f 100644 --- a/pinpoint/pinpoint_config.h +++ b/pinpoint/pinpoint_config.h @@ -4,3 +4,4 @@ #define SPSLR_PINPOINT_STAGE0_SEPARATOR "__spslr_offsetof" #define SPSLR_PINPOINT_STAGE1_PIN "__spslr_ipin_" /* suffixed with "" */ #define SPSLR_PINPOINT_CU_UID_LABEL "__spslr_cu_" /* suffixed with "" */ +#define SPSLR_PINFILE_EXTENSION ".spslr" diff --git a/subject/CMakeLists.txt b/subject/CMakeLists.txt index 0e4b6d3..bf27cb7 100644 --- a/subject/CMakeLists.txt +++ b/subject/CMakeLists.txt @@ -2,4 +2,6 @@ add_executable(subject main.c second.c sub/second.c) target_include_directories(subject PRIVATE .) add_dependencies(subject spslr_pinpoint spslr_finalize spslr_selfpatch) target_link_libraries(subject PRIVATE spslr_selfpatch) -target_compile_options(subject PRIVATE -O1 -fplugin=$ -fdump-tree-separate_offset -fdump-tree-asm_offset) +target_compile_options(subject PRIVATE -O1 -fplugin=$ -fdump-tree-separate_offset -fdump-tree-asm_offset + -fplugin-arg-spslr_pinpoint-srcdir=${CMAKE_CURRENT_SOURCE_DIR} + -fplugin-arg-spslr_pinpoint-dstdir=${CMAKE_CURRENT_BINARY_DIR}/spslr)