Attribute registration for pinpoint plugin

This commit is contained in:
York Jasper Niebuhr 2025-10-24 16:38:04 +02:00
parent aa9fe3b8fc
commit 162a0785c9
13 changed files with 190 additions and 3 deletions

View File

@ -6,4 +6,6 @@ target_compile_options(spslr_pinpoint PRIVATE -fno-rtti -fno-exceptions)
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=plugin OUTPUT_VARIABLE GCC_PLUGIN_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "GCC plugin path: ${GCC_PLUGIN_PATH}")
target_include_directories(spslr_pinpoint PRIVATE ${GCC_PLUGIN_PATH}/include ${CMAKE_CURRENT_SOURCE_DIR}/safegcc)
target_include_directories(spslr_pinpoint PRIVATE ${GCC_PLUGIN_PATH}/include ${CMAKE_CURRENT_SOURCE_DIR}/safegcc ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(stage0)

View File

@ -3,6 +3,8 @@
#include <safe-gcc-plugin.h>
#include <safe-plugin-version.h>
#include <stage0.h>
int plugin_is_GPL_compatible;
int plugin_init(struct plugin_name_args* plugin_info, struct plugin_gcc_version* version) {
@ -11,6 +13,10 @@ int plugin_init(struct plugin_name_args* plugin_info, struct plugin_gcc_version*
return 1;
}
// TODO
// Stage 0 -> logic that happens before all usual passes
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);
return 0;
}

View File

@ -0,0 +1,3 @@
#pragma once
#define SPSLR_ATTRIBUTE "spslr"

View File

@ -0,0 +1,8 @@
#include <safe-gcc-plugin.h>
#ifndef SAFEGCC_LANGHOOKS_H
#define SAFEGCC_LANGHOOKS_H
#include <langhooks.h>
#endif

View File

@ -1,3 +1,5 @@
#include <safe-gcc-plugin.h>
#ifndef SAFEGCC_PLUGIN_VERSION_H
#define SAFEGCC_PLUGIN_VERSION_H

View File

@ -0,0 +1,8 @@
#include <safe-gcc-plugin.h>
#ifndef SAFEGCC_TREE_H
#define SAFEGCC_TREE_H
#include <tree.h>
#endif

View File

@ -0,0 +1,2 @@
target_sources(spslr_pinpoint PRIVATE on_register_attributes.cpp on_finish_type.cpp on_preserve_component_ref.cpp target.cpp)
target_include_directories(spslr_pinpoint PRIVATE .)

View File

@ -0,0 +1,6 @@
#include <stage0.h>
void on_finish_type(void* plugin_data, void* user_data) {
}

View File

@ -0,0 +1,6 @@
#include <stage0.h>
void on_preserve_component_ref(void* plugin_data, void* user_data) {
}

View File

@ -0,0 +1,18 @@
#include <stage0.h>
#include <pinpoint_config.h>
static tree log_new_target(tree* node, tree name, tree args, int flags, bool* no_add_attrs) {
if (node)
TargetType::add(*node);
return NULL_TREE;
}
static struct attribute_spec spslr_attribute = {
SPSLR_ATTRIBUTE, 0, 0, false, false, false, false, log_new_target, NULL
};
void on_register_attributes(void* plugin_data, void* user_data) {
register_attribute(&spslr_attribute);
}

52
pinpoint/stage0/stage0.h Normal file
View File

@ -0,0 +1,52 @@
#pragma once
#include <cstddef>
#include <map>
#include <limits>
#include <safe-tree.h>
using UID = std::size_t;
constexpr UID UID_INVALID = std::numeric_limits<UID>::max();
class TargetType {
public:
struct Field {
static constexpr std::size_t FLAG_DANGEROUS = 1;
std::size_t offset;
std::size_t size;
std::size_t flags;
};
private:
static constexpr std::size_t FLAG_MAIN_VARIANT = 1;
static constexpr std::size_t FLAG_FIELDS = 2;
UID m_uid;
std::size_t m_flags;
tree m_main_variant;
// Fields are identified by their offsets
std::map<std::size_t, Field> m_field;
public:
TargetType(const TargetType& other) = default;
TargetType& operator=(const TargetType& other) = default;
TargetType(TargetType&& other) = default;
TargetType& operator=(TargetType&& other) = default;
TargetType(tree t); // Does NOT fetch fields
~TargetType();
bool valid() const;
bool fields() const;
bool fetch_fields();
static void add(tree t);
static std::size_t count();
static const TargetType* find(tree t); // O(n)
static const TargetType* find(UID uid); // O(1)
};
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);

View File

@ -0,0 +1,74 @@
#include <stage0.h>
#include <unordered_map>
#include <safe-langhooks.h>
static UID next_uid = 0;
static std::unordered_map<UID, TargetType> targets;
static tree get_record_main_variant(tree t) {
if (!t || TREE_CODE(t) != RECORD_TYPE)
return NULL_TREE;
return TYPE_MAIN_VARIANT(t);
}
TargetType::TargetType(tree t) : m_uid{ UID_INVALID }, m_flags{ 0 } {
if (!(m_main_variant = get_record_main_variant(t)))
return;
m_flags |= FLAG_MAIN_VARIANT;
}
TargetType::~TargetType() {}
bool TargetType::valid() const {
return (m_flags & FLAG_MAIN_VARIANT) != 0;
}
bool TargetType::fields() const {
return (m_flags & FLAG_FIELDS) != 0;
}
bool TargetType::fetch_fields() {
// TODO
return false;
}
void TargetType::add(tree t) {
if (find(t) != nullptr)
return;
TargetType tmp { t };
if (!tmp.valid())
return;
tmp.m_uid = next_uid++;
targets.emplace(tmp.m_uid, tmp);
}
std::size_t TargetType::count() {
return targets.size();
}
const TargetType* TargetType::find(tree t) {
tree main_variant = get_record_main_variant(t);
if (!main_variant)
return nullptr;
for (const auto& [uid, target] : targets) {
if (lang_hooks.types_compatible_p(main_variant, target.m_main_variant))
return &target;
}
return nullptr;
}
const TargetType* TargetType::find(UID uid) {
auto it = targets.find(uid);
if (it == targets.end())
return nullptr;
return &it->second;
}

View File

@ -48,7 +48,7 @@ struct task_struct {
int pid;
const char *comm;
struct list_head tasks; // linkage for global task list
} __attribute__((slr));
} __attribute__((spslr));
int main(void)
{