Pinpoint plugin destination file determination

This commit is contained in:
York Jasper Niebuhr 2025-10-26 16:56:03 +01:00
parent 91a329122b
commit 5f28fd2b22
5 changed files with 115 additions and 25 deletions

View File

@ -1,3 +1,12 @@
#pragma once #pragma once
void on_finish_unit(void* plugin_data, void* user_data); 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();

View File

@ -2,6 +2,8 @@
#include <final.h> #include <final.h>
#include <stage0.h> #include <stage0.h>
#include <stage1.h> #include <stage1.h>
#include <string>
#include <filesystem>
#include <safe-input.h> #include <safe-input.h>
#include <safe-output.h> #include <safe-output.h>
@ -9,48 +11,107 @@
#include <pinpoint_config.h> #include <pinpoint_config.h>
#include <pinpoint_error.h> #include <pinpoint_error.h>
unsigned char cu_uid_md5[16]; static bool src_dir_known = false, dst_dir_known = false;
char cu_uid_hex[33]; 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) 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); std::filesystem::path abs_current_src = std::filesystem::absolute(main_input_filename);
return cu_uid_md5; 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() { static std::filesystem::path spslr_output_file(const std::filesystem::path& infile) {
const unsigned char* digest = calculate_cu_uid_md5(); const char* dst_root = get_dst_dir();
if (!digest) if (!dst_root)
return nullptr; pinpoint_fatal("spslr_output_file is missing the destination root path");
for (int i = 0; i < 16; ++i) std::filesystem::path abs_root_dst = std::filesystem::absolute(dst_root);
sprintf(cu_uid_hex + 2*i, "%02x", digest[i]); return (abs_root_dst / infile).string() + SPSLR_PINFILE_EXTENSION;
cu_uid_hex[32] = '\0';
return cu_uid_hex;
} }
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]; 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); fprintf(asm_out_file, "%s:\n", label);
return true;
} }
void on_finish_unit(void* plugin_data, void* user_data) { void on_finish_unit(void* plugin_data, void* user_data) {
const char* cu_uid = calculate_cu_uid_hex(); std::filesystem::path infile = relative_src_path();
if (!cu_uid) std::filesystem::path outfile = spslr_output_file(infile);
pinpoint_fatal("on_finish_unit failed to calculate compilation unit UID");
if (!emit_cu_uid_label(cu_uid)) std::cout << "Finishing unit " << infile << " ..." << std::endl;
pinpoint_fatal("on_finish_unit failed to emit CU UID label"); 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; 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()) for (const auto& [uid, target] : TargetType::all())
std::cout << " Target " << uid << " -> \"" << target.name() << "\" (" << target.size() << ")" << std::endl; std::cout << " Target " << uid << " -> \"" << target.name() << "\" (" << target.size() << ")" << std::endl;

View File

@ -15,6 +15,23 @@ int plugin_init(struct plugin_name_args* plugin_info, struct plugin_gcc_version*
return 1; 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 // 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_START_UNIT, on_start_unit, NULL);

View File

@ -4,3 +4,4 @@
#define SPSLR_PINPOINT_STAGE0_SEPARATOR "__spslr_offsetof" #define SPSLR_PINPOINT_STAGE0_SEPARATOR "__spslr_offsetof"
#define SPSLR_PINPOINT_STAGE1_PIN "__spslr_ipin_" /* suffixed with "<uid>" */ #define SPSLR_PINPOINT_STAGE1_PIN "__spslr_ipin_" /* suffixed with "<uid>" */
#define SPSLR_PINPOINT_CU_UID_LABEL "__spslr_cu_" /* suffixed with "<uid>" */ #define SPSLR_PINPOINT_CU_UID_LABEL "__spslr_cu_" /* suffixed with "<uid>" */
#define SPSLR_PINFILE_EXTENSION ".spslr"

View File

@ -2,4 +2,6 @@ add_executable(subject main.c second.c sub/second.c)
target_include_directories(subject PRIVATE .) target_include_directories(subject PRIVATE .)
add_dependencies(subject spslr_pinpoint spslr_finalize spslr_selfpatch) add_dependencies(subject spslr_pinpoint spslr_finalize spslr_selfpatch)
target_link_libraries(subject PRIVATE spslr_selfpatch) target_link_libraries(subject PRIVATE spslr_selfpatch)
target_compile_options(subject PRIVATE -O1 -fplugin=$<TARGET_FILE:spslr_pinpoint> -fdump-tree-separate_offset -fdump-tree-asm_offset) target_compile_options(subject PRIVATE -O1 -fplugin=$<TARGET_FILE:spslr_pinpoint> -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)