Made subject multi-CU
This commit is contained in:
parent
d7b07df8b7
commit
ecfeed59ee
@ -1,29 +1,26 @@
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
<o>.spslr.targets:
|
||||
target <uid> <size> <field count>
|
||||
<sourcefile>.spslr:
|
||||
|
||||
SPSLR_FINALIZE_HEADER <CU filename> <CU uid symbol>
|
||||
target <hash> <local uid> <size> <field count>
|
||||
f <offset> <size> <flags>
|
||||
f <offset> <size> <flags>
|
||||
...
|
||||
|
||||
<o>.spslr.ipins:
|
||||
(prefix __spslr_pin)
|
||||
0 <target uid> <field offset>
|
||||
1 <target uid> <field offset>
|
||||
2 <target uid> <field offset>
|
||||
ipin <label> <target uid> <field offset>
|
||||
ipin <label> <target uid> <field offset>
|
||||
ipin <label> <target uid> <field offset>
|
||||
...
|
||||
dpin <symbol> <offset> <level> <target uid>
|
||||
dpin <symbol> <offset> <level> <target uid>
|
||||
...
|
||||
|
||||
<o>.spslr.dpins:
|
||||
myVar1 2 <strip true/false>
|
||||
<offset> <lvl> <target uid>
|
||||
<offset> <lvl> <target uid>
|
||||
myVar2 1 <strip true/false>
|
||||
<offset> <lvl> <target uid>
|
||||
...
|
||||
|
||||
Datapins are randomized in order of their level, from bottom of nest to top
|
||||
Datapin strip flag is set if it would not have been preserved in symtab without pinpoint plugin
|
||||
|
||||
Datapins for same var/symbol are randomized in order of their level, from bottom of nest to top
|
||||
The CU uid symbol helps differentiating between e.g. "file.c" and "sub/file.c" (symbtab has no idea)
|
||||
Between CUs, types with the same hash are considered to be the same type
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ int plugin_init(struct plugin_name_args* plugin_info, struct plugin_gcc_version*
|
||||
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);
|
||||
register_callback(plugin_info->base_name, PLUGIN_FINISH_DECL, on_finish_decl, NULL);
|
||||
|
||||
struct register_pass_info separate_offset_pass_info;
|
||||
separate_offset_pass_info.pass = new separate_offset_pass(nullptr);
|
||||
|
||||
9
pinpoint/safegcc/safe-input.h
Normal file
9
pinpoint/safegcc/safe-input.h
Normal file
@ -0,0 +1,9 @@
|
||||
#include <safe-gcc-plugin.h>
|
||||
|
||||
#ifndef SAFEGCC_INPUT_H
|
||||
#define SAFEGCC_INPUT_H
|
||||
|
||||
#include <input.h>
|
||||
#include <libiberty.h>
|
||||
|
||||
#endif
|
||||
@ -1,3 +1,3 @@
|
||||
target_sources(spslr_pinpoint PRIVATE on_register_attributes.cpp on_finish_type.cpp on_preserve_component_ref.cpp
|
||||
target.cpp separator.cpp separate_offset_pass.cpp)
|
||||
on_finish_decl.cpp target.cpp separator.cpp separate_offset_pass.cpp)
|
||||
target_include_directories(spslr_pinpoint PRIVATE .)
|
||||
|
||||
93
pinpoint/stage0/on_finish_decl.cpp
Normal file
93
pinpoint/stage0/on_finish_decl.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include <iostream> // TODO
|
||||
#include <stage0.h>
|
||||
|
||||
#include <pinpoint_error.h>
|
||||
#include <safe-input.h>
|
||||
|
||||
static std::list<DataPin> pins;
|
||||
|
||||
const std::list<DataPin>& dpins() {
|
||||
return pins;
|
||||
}
|
||||
|
||||
/*
|
||||
struct DataPin {
|
||||
struct Component {
|
||||
std::size_t offset;
|
||||
std::size_t level;
|
||||
UID target;
|
||||
};
|
||||
|
||||
std::string symbol;
|
||||
std::list<Component> components;
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
bool type_matches(tree t, hash_set<tree> *target_types)
|
||||
{
|
||||
if (!t) return false;
|
||||
t = TYPE_MAIN_VARIANT(t);
|
||||
|
||||
if (target_types->contains(t))
|
||||
return true;
|
||||
|
||||
if (TREE_CODE(t) == RECORD_TYPE || TREE_CODE(t) == UNION_TYPE)
|
||||
{
|
||||
for (tree field = TYPE_FIELDS(t); field; field = TREE_CHAIN(field))
|
||||
{
|
||||
if (TREE_CODE(field) == FIELD_DECL)
|
||||
{
|
||||
tree ftype = TREE_TYPE(field);
|
||||
if (type_matches(ftype, target_types))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
static bool compile_datapin(tree type, DataPin& pin) {
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
static void on_static_var(tree var) {
|
||||
tree type = TREE_TYPE(var);
|
||||
if (!type)
|
||||
return;
|
||||
|
||||
DataPin pin;
|
||||
if (!compile_datapin(type, pin))
|
||||
return;
|
||||
|
||||
DECL_PRESERVE_P(var) = 1;
|
||||
DECL_VISIBILITY(var) = VISIBILITY_DEFAULT;
|
||||
DECL_VISIBILITY_SPECIFIED(var) = 1;
|
||||
|
||||
tree symbol_tree = DECL_ASSEMBLER_NAME(var);
|
||||
const char* symbol;
|
||||
if (!symbol_tree || !(symbol = IDENTIFIER_POINTER(symbol_tree)))
|
||||
pinpoint_fatal("on_static_var failed to get symbol of static variable");
|
||||
|
||||
pin.symbol = std::string{ symbol };
|
||||
|
||||
pins.emplace_back(std::move(pin));
|
||||
|
||||
// TODO
|
||||
std::cout << "Pinned: \"" << symbol << "\" (" << lbasename(main_input_filename) << ")" << std::endl;
|
||||
}
|
||||
|
||||
void on_finish_decl(void* plugin_data, void* user_data) {
|
||||
tree decl = (tree)plugin_data;
|
||||
|
||||
if (TREE_CODE(decl) != VAR_DECL)
|
||||
return;
|
||||
|
||||
if (!TREE_STATIC(decl) || DECL_EXTERNAL(decl))
|
||||
return;
|
||||
|
||||
on_static_var(decl);
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <limits>
|
||||
|
||||
#include <safe-tree.h>
|
||||
@ -64,9 +65,23 @@ tree make_stage0_ast_separator(UID target, std::size_t offset);
|
||||
gimple* make_stage0_gimple_separator(tree lhs, UID target, std::size_t offset);
|
||||
bool is_stage0_separator(gimple* stmt, UID& target, std::size_t& offset);
|
||||
|
||||
struct DataPin {
|
||||
struct Component {
|
||||
std::size_t offset;
|
||||
std::size_t level;
|
||||
UID target;
|
||||
};
|
||||
|
||||
std::string symbol;
|
||||
std::list<Component> components;
|
||||
};
|
||||
|
||||
const std::list<DataPin>& dpins();
|
||||
|
||||
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);
|
||||
void on_finish_decl(void* plugin_data, void* user_data);
|
||||
|
||||
struct separate_offset_pass : gimple_opt_pass {
|
||||
separate_offset_pass(gcc::context* ctxt);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
add_executable(subject main.c)
|
||||
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)
|
||||
|
||||
@ -1,54 +1,9 @@
|
||||
// test_task_struct.c
|
||||
#include <stdio.h>
|
||||
#include <stddef.h> // for offsetof
|
||||
#include "task_struct.h"
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof(((type*)0)->member)* __mptr = (ptr); \
|
||||
(type*)((char*)__mptr - offsetof(type, member)); })
|
||||
int second_pid();
|
||||
int third_pid();
|
||||
|
||||
// Minimal doubly linked list
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
|
||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
static inline void __list_add(struct list_head *new,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head, head->next);
|
||||
}
|
||||
|
||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head->prev, head);
|
||||
}
|
||||
|
||||
#define list_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
|
||||
#define list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
// A small struct like the Linux kernel's task_struct
|
||||
struct task_struct {
|
||||
int pid;
|
||||
const char *comm;
|
||||
struct list_head tasks; // linkage for global task list
|
||||
} __attribute__((spslr));
|
||||
struct task_struct global = { .pid = 42, .comm = "main_global" };
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@ -77,6 +32,6 @@ int main(void)
|
||||
|
||||
size_t myOffset = ((size_t)&((struct task_struct*)0)->tasks); // BROKEN, relevancy for kernel unknown
|
||||
|
||||
return 0;
|
||||
return second_pid() * third_pid();
|
||||
}
|
||||
|
||||
|
||||
7
subject/second.c
Normal file
7
subject/second.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "task_struct.h"
|
||||
|
||||
static struct task_struct global = { .pid = 43, .comm = "third_global" };
|
||||
|
||||
int third_pid() {
|
||||
return global.pid;
|
||||
}
|
||||
7
subject/sub/second.c
Normal file
7
subject/sub/second.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "task_struct.h"
|
||||
|
||||
static struct task_struct global = { .pid = 0, .comm = "second_global" };
|
||||
|
||||
int second_pid() {
|
||||
return global.pid;
|
||||
}
|
||||
49
subject/task_struct.h
Normal file
49
subject/task_struct.h
Normal file
@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof(((type*)0)->member)* __mptr = (ptr); \
|
||||
(type*)((char*)__mptr - offsetof(type, member)); })
|
||||
|
||||
// Minimal doubly linked list
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
|
||||
static inline void INIT_LIST_HEAD(struct list_head *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head, head->next);
|
||||
}
|
||||
|
||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head->prev, head);
|
||||
}
|
||||
|
||||
#define list_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
|
||||
#define list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
// A small struct like the Linux kernel's task_struct
|
||||
struct task_struct {
|
||||
int pid;
|
||||
const char *comm;
|
||||
struct list_head tasks; // linkage for global task list
|
||||
} __attribute__((spslr));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user