ReactOS 0.4.16-dev-329-g9223134
main.cpp File Reference
#include <gcc-plugin.h>
#include <plugin-version.h>
#include <function.h>
#include <tree.h>
#include <c-family/c-pragma.h>
#include <c-family/c-common.h>
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <vector>
#include <cstdio>
Include dependency graph for main.cpp:

Go to the source code of this file.

Classes

struct  seh_handler
 
struct  seh_function
 

Macros

#define trace(...)
 
#define is_alpha(c)   (((c)>64 && (c)<91) || ((c)>96 && (c)<123))
 
#define VISIBLE   __attribute__((__visibility__("default")))
 
#define UNUSED   __attribute__((__unused__))
 

Functions

static struct seh_functionget_seh_function ()
 
static void handle_seh_pragma (cpp_reader *UNUSED parser)
 
static void finish_seh_function (void *event_data, void *UNUSED user_data)
 
static void register_seh_pragmas (void *UNUSED event_data, void *UNUSED user_data)
 
VISIBLE int plugin_init (struct plugin_name_args *info, struct plugin_gcc_version *version)
 

Variables

int VISIBLE plugin_is_GPL_compatible = 1
 
constexpr size_t k_header_statement_max_size = 20000
 
static std::unordered_map< struct function *, struct seh_function * > func_seh_map = {}
 

Macro Definition Documentation

◆ is_alpha

#define is_alpha (   c)    (((c)>64 && (c)<91) || ((c)>96 && (c)<123))

Definition at line 28 of file main.cpp.

◆ trace

#define trace (   ...)

Definition at line 25 of file main.cpp.

◆ UNUSED

#define UNUSED   __attribute__((__unused__))

Definition at line 36 of file main.cpp.

◆ VISIBLE

#define VISIBLE   __attribute__((__visibility__("default")))

Definition at line 33 of file main.cpp.

Function Documentation

◆ finish_seh_function()

static void finish_seh_function ( void event_data,
void *UNUSED  user_data 
)
static

Definition at line 150 of file main.cpp.

151{
152 tree fndef = (tree)event_data;
153 struct function* fun = DECL_STRUCT_FUNCTION(fndef);
154
155 auto search = func_seh_map.find(fun);
156 if (search == func_seh_map.end())
157 return;
158
159 /* Get our SEH details and remove us from the map */
160 seh_function* seh_fun = search->second;
161 func_seh_map.erase(search);
162
163 if (DECL_FUNCTION_PERSONALITY(fndef) != nullptr)
164 {
165 error("Function %s has a personality. Are you mixing SEH with C++ exceptions ?",
166 IDENTIFIER_POINTER(fndef));
167 return;
168 }
169
170 /* Update asm statement */
171 std::stringstream asm_str;
172 asm_str << ".seh_handler __C_specific_handler";
173 if (seh_fun->unwind)
174 asm_str << ", @unwind";
175 if (seh_fun->except)
176 asm_str << ", @except";
177 asm_str << "\n";
178 asm_str << "\t.seh_handlerdata\n";
179 asm_str << "\t.long " << seh_fun->count << "\n";
180
181 for (auto& handler : seh_fun->handlers)
182 {
183 asm_str << "\n\t.rva " << "__seh2$$begin_try__" << handler.line; /* Begin of tried code */
184 asm_str << "\n\t.rva " << "__seh2$$end_try__" << handler.line; /* End of tried code */
185 asm_str << "\n\t.rva " << "__seh2$$filter__" << handler.line; /* Filter function */
186 if (handler.is_except)
187 asm_str << "\n\t.rva " << "__seh2$$begin_except__" << handler.line; /* Called on except */
188 else
189 asm_str << "\n\t.long 0"; /* No unwind handler */
190 }
191 asm_str << "\n\t.seh_code\n";
192
193 strncpy(const_cast<char*>(TREE_STRING_POINTER(seh_fun->asm_header_text)),
194 asm_str.str().c_str(),
195 TREE_STRING_LENGTH(seh_fun->asm_header_text));
196
197 trace(stderr, "ASM: %s\n", asm_str.str().c_str());
198
199 delete seh_fun;
200}
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
struct _tree tree
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
#define stderr
Definition: stdio.h:100
#define error(str)
Definition: mkdosfs.c:1605
static short search(int val, const short *table, int size)
Definition: msg711.c:255
#define trace(...)
Definition: main.cpp:25
static std::unordered_map< struct function *, struct seh_function * > func_seh_map
Definition: main.cpp:78
size_t count
Definition: main.cpp:56
tree asm_header_text
Definition: main.cpp:54
std::vector< seh_handler > handlers
Definition: main.cpp:57
bool unwind
Definition: main.cpp:52
bool except
Definition: main.cpp:53

Referenced by plugin_init().

◆ get_seh_function()

static struct seh_function * get_seh_function ( )
static

Definition at line 82 of file main.cpp.

83{
84 auto search = func_seh_map.find(cfun);
85 if (search != func_seh_map.end())
86 return search->second;
87
88 auto seh_fun = new seh_function(cfun);
89 func_seh_map.insert({cfun, seh_fun});
90
91 return seh_fun;
92}

Referenced by handle_seh_pragma().

◆ handle_seh_pragma()

static void handle_seh_pragma ( cpp_reader *UNUSED  parser)
static

Definition at line 96 of file main.cpp.

97{
98 tree x, arg, line;
99 std::stringstream label_decl;
100 bool is_except;
101
102 if (!cfun)
103 {
104 error("%<#pragma REACTOS seh%> is not allowed outside functions");
105 return;
106 }
107
108 if ((pragma_lex(&x) != CPP_OPEN_PAREN) ||
109 (pragma_lex(&arg) != CPP_NAME) || // except or finally
110 (pragma_lex(&x) != CPP_COMMA) ||
111 (pragma_lex(&line) != CPP_NUMBER) || // Line number
112 (pragma_lex(&x) != CPP_CLOSE_PAREN) ||
113 (pragma_lex(&x) != CPP_EOF)
114 )
115 {
116 error("%<#pragma REACTOS seh%> needs two parameters%>");
117 return;
118 }
119
120 trace(stderr, "Pragma: %s, %u\n", IDENTIFIER_POINTER(arg), TREE_INT_CST_LOW(line));
121
122 const char* op = IDENTIFIER_POINTER(arg);
123
124 seh_function* seh_fun = get_seh_function();
125 if (strcmp(op, "__seh$$except") == 0)
126 {
127 is_except = true;
128 seh_fun->except = true;
129 }
130 else if (strcmp(op, "__seh$$finally") == 0)
131 {
132 is_except = false;
133 seh_fun->unwind = true;
134 }
135 else
136 {
137 error("Wrong argument for %<#pragma REACTOS seh%>. Expected \"except\" or \"finally\"");
138 return;
139 }
140 seh_fun->count++;
141
142 seh_fun->handlers.push_back({is_except, (unsigned int)TREE_INT_CST_LOW(line)});
143
144 /* Make sure we use a frame pointer. REACTOS' PSEH depends on this */
145 cfun->machine->accesses_prev_frame = 1;
146}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT op
Definition: effect.c:236
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static struct seh_function * get_seh_function()
Definition: main.cpp:82
Definition: parser.c:49
void * arg
Definition: msvc.h:10

Referenced by register_seh_pragmas().

◆ plugin_init()

VISIBLE int plugin_init ( struct plugin_name_args *  info,
struct plugin_gcc_version *  version 
)

Definition at line 212 of file main.cpp.

214{
215 if (!plugin_default_version_check (version, &gcc_version))
216 {
217 std::cerr << "This GCC plugin is for version " << GCCPLUGIN_VERSION_MAJOR << "." << GCCPLUGIN_VERSION_MINOR << "\n";
218 return 1;
219 }
220
221 register_callback(info->base_name, PLUGIN_PRAGMAS, register_seh_pragmas, NULL);
222 register_callback(info->base_name, PLUGIN_FINISH_PARSE_FUNCTION, finish_seh_function, NULL);
223
224 return 0;
225}
#define NULL
Definition: types.h:112
static const WCHAR version[]
Definition: asmname.c:66
static void register_seh_pragmas(void *UNUSED event_data, void *UNUSED user_data)
Definition: main.cpp:204
static void finish_seh_function(void *event_data, void *UNUSED user_data)
Definition: main.cpp:150

◆ register_seh_pragmas()

static void register_seh_pragmas ( void *UNUSED  event_data,
void *UNUSED  user_data 
)
static

Definition at line 204 of file main.cpp.

205{
206 c_register_pragma("REACTOS", "seh", handle_seh_pragma);
207}
static void handle_seh_pragma(cpp_reader *UNUSED parser)
Definition: main.cpp:96

Referenced by plugin_init().

Variable Documentation

◆ func_seh_map

std::unordered_map<struct function*, struct seh_function*> func_seh_map = {}
static

Definition at line 78 of file main.cpp.

Referenced by finish_seh_function(), and get_seh_function().

◆ k_header_statement_max_size

constexpr size_t k_header_statement_max_size = 20000
constexpr

Definition at line 42 of file main.cpp.

Referenced by seh_function::seh_function().

◆ plugin_is_GPL_compatible

int VISIBLE plugin_is_GPL_compatible = 1

Definition at line 40 of file main.cpp.