Pinpoint plugin destination file determination
This commit is contained in:
parent
91a329122b
commit
5f28fd2b22
@ -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();
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
#include <final.h>
|
||||
#include <stage0.h>
|
||||
#include <stage1.h>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
#include <safe-input.h>
|
||||
#include <safe-output.h>
|
||||
@ -9,48 +11,107 @@
|
||||
#include <pinpoint_config.h>
|
||||
#include <pinpoint_error.h>
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -4,3 +4,4 @@
|
||||
#define SPSLR_PINPOINT_STAGE0_SEPARATOR "__spslr_offsetof"
|
||||
#define SPSLR_PINPOINT_STAGE1_PIN "__spslr_ipin_" /* suffixed with "<uid>" */
|
||||
#define SPSLR_PINPOINT_CU_UID_LABEL "__spslr_cu_" /* suffixed with "<uid>" */
|
||||
#define SPSLR_PINFILE_EXTENSION ".spslr"
|
||||
|
||||
@ -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=$<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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user