diff --git a/pinpoint/CMakeLists.txt b/pinpoint/CMakeLists.txt index 47ba4a1..3ff5228 100644 --- a/pinpoint/CMakeLists.txt +++ b/pinpoint/CMakeLists.txt @@ -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) diff --git a/pinpoint/pinpoint.cpp b/pinpoint/pinpoint.cpp index 7ad1fe9..565bf3c 100644 --- a/pinpoint/pinpoint.cpp +++ b/pinpoint/pinpoint.cpp @@ -3,6 +3,8 @@ #include #include +#include + 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; } diff --git a/pinpoint/pinpoint_config.h b/pinpoint/pinpoint_config.h new file mode 100644 index 0000000..7c9521c --- /dev/null +++ b/pinpoint/pinpoint_config.h @@ -0,0 +1,3 @@ +#pragma once + +#define SPSLR_ATTRIBUTE "spslr" diff --git a/pinpoint/safegcc/safe-langhooks.h b/pinpoint/safegcc/safe-langhooks.h new file mode 100644 index 0000000..3fbea6c --- /dev/null +++ b/pinpoint/safegcc/safe-langhooks.h @@ -0,0 +1,8 @@ +#include + +#ifndef SAFEGCC_LANGHOOKS_H +#define SAFEGCC_LANGHOOKS_H + +#include + +#endif diff --git a/pinpoint/safegcc/safe-plugin-version.h b/pinpoint/safegcc/safe-plugin-version.h index d816648..e43a168 100644 --- a/pinpoint/safegcc/safe-plugin-version.h +++ b/pinpoint/safegcc/safe-plugin-version.h @@ -1,3 +1,5 @@ +#include + #ifndef SAFEGCC_PLUGIN_VERSION_H #define SAFEGCC_PLUGIN_VERSION_H diff --git a/pinpoint/safegcc/safe-tree.h b/pinpoint/safegcc/safe-tree.h new file mode 100644 index 0000000..0017178 --- /dev/null +++ b/pinpoint/safegcc/safe-tree.h @@ -0,0 +1,8 @@ +#include + +#ifndef SAFEGCC_TREE_H +#define SAFEGCC_TREE_H + +#include + +#endif diff --git a/pinpoint/stage0/CMakeLists.txt b/pinpoint/stage0/CMakeLists.txt new file mode 100644 index 0000000..12f8aa7 --- /dev/null +++ b/pinpoint/stage0/CMakeLists.txt @@ -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 .) diff --git a/pinpoint/stage0/on_finish_type.cpp b/pinpoint/stage0/on_finish_type.cpp new file mode 100644 index 0000000..73154a6 --- /dev/null +++ b/pinpoint/stage0/on_finish_type.cpp @@ -0,0 +1,6 @@ +#include + +void on_finish_type(void* plugin_data, void* user_data) { + +} + diff --git a/pinpoint/stage0/on_preserve_component_ref.cpp b/pinpoint/stage0/on_preserve_component_ref.cpp new file mode 100644 index 0000000..4efb4e5 --- /dev/null +++ b/pinpoint/stage0/on_preserve_component_ref.cpp @@ -0,0 +1,6 @@ +#include + +void on_preserve_component_ref(void* plugin_data, void* user_data) { + +} + diff --git a/pinpoint/stage0/on_register_attributes.cpp b/pinpoint/stage0/on_register_attributes.cpp new file mode 100644 index 0000000..d651f3c --- /dev/null +++ b/pinpoint/stage0/on_register_attributes.cpp @@ -0,0 +1,18 @@ +#include +#include + +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); +} + diff --git a/pinpoint/stage0/stage0.h b/pinpoint/stage0/stage0.h new file mode 100644 index 0000000..8c30a1f --- /dev/null +++ b/pinpoint/stage0/stage0.h @@ -0,0 +1,52 @@ +#pragma once +#include +#include +#include + +#include + +using UID = std::size_t; +constexpr UID UID_INVALID = std::numeric_limits::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 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); diff --git a/pinpoint/stage0/target.cpp b/pinpoint/stage0/target.cpp new file mode 100644 index 0000000..bc8aaba --- /dev/null +++ b/pinpoint/stage0/target.cpp @@ -0,0 +1,74 @@ +#include +#include + +#include + +static UID next_uid = 0; +static std::unordered_map 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 ⌖ + } + + return nullptr; +} + +const TargetType* TargetType::find(UID uid) { + auto it = targets.find(uid); + if (it == targets.end()) + return nullptr; + + return &it->second; +} + diff --git a/subject/main.c b/subject/main.c index 620bb2a..1f3e2d7 100644 --- a/subject/main.c +++ b/subject/main.c @@ -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) {