ReactOS 0.4.16-dev-2574-g474348f
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 mark_seh_function_noinline (void)
 
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 172 of file main.cpp.

173{
174 tree fndef = (tree)event_data;
175 struct function* fun = DECL_STRUCT_FUNCTION(fndef);
176
177 auto search = func_seh_map.find(fun);
178 if (search == func_seh_map.end())
179 return;
180
181 /* Get our SEH details and remove us from the map */
182 seh_function* seh_fun = search->second;
183 func_seh_map.erase(search);
184
185 if (DECL_FUNCTION_PERSONALITY(fndef) != nullptr)
186 {
187 error("Function %s has a personality. Are you mixing SEH with C++ exceptions ?",
188 IDENTIFIER_POINTER(fndef));
189 return;
190 }
191
192 /* Update asm statement */
193 std::stringstream asm_str;
194 asm_str << ".seh_handler __C_specific_handler";
195 if (seh_fun->unwind)
196 asm_str << ", @unwind";
197 if (seh_fun->except)
198 asm_str << ", @except";
199 asm_str << "\n";
200 asm_str << "\t.seh_handlerdata\n";
201 asm_str << "\t.long " << seh_fun->count << "\n";
202
203 for (auto& handler : seh_fun->handlers)
204 {
205 asm_str << "\n\t.rva " << "__seh2$$begin_try__" << handler.line; /* Begin of tried code */
206 asm_str << "\n\t.rva " << "__seh2$$end_try__" << handler.line; /* End of tried code */
207 asm_str << "\n\t.rva " << "__seh2$$filter__" << handler.line; /* Filter function */
208 if (handler.is_except)
209 asm_str << "\n\t.rva " << "__seh2$$begin_except__" << handler.line; /* Called on except */
210 else
211 asm_str << "\n\t.long 0"; /* No unwind handler */
212 }
213 asm_str << "\n\t.seh_code\n";
214
215 strncpy(const_cast<char*>(TREE_STRING_POINTER(seh_fun->asm_header_text)),
216 asm_str.str().c_str(),
217 TREE_STRING_LENGTH(seh_fun->asm_header_text));
218
219 trace(stderr, "ASM: %s\n", asm_str.str().c_str());
220
221 delete seh_fun;
222}
struct _tree tree
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
#define stderr
#define error(str)
Definition: mkdosfs.c:1605
static short search(int val, const short *table, int size)
Definition: msg711.c:255
strncpy
Definition: string.h:335
#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 115 of file main.cpp.

116{
117 tree x, arg, line;
118 std::stringstream label_decl;
119 bool is_except;
120
121 if (!cfun)
122 {
123 error("%<#pragma REACTOS seh%> is not allowed outside functions");
124 return;
125 }
126
127 if ((pragma_lex(&x) != CPP_OPEN_PAREN) ||
128 (pragma_lex(&arg) != CPP_NAME) || // except or finally
129 (pragma_lex(&x) != CPP_COMMA) ||
130 (pragma_lex(&line) != CPP_NUMBER) || // Line number
131 (pragma_lex(&x) != CPP_CLOSE_PAREN) ||
132 (pragma_lex(&x) != CPP_EOF)
133 )
134 {
135 error("%<#pragma REACTOS seh%> needs two parameters%>");
136 return;
137 }
138
139 trace(stderr, "Pragma: %s, %u\n", IDENTIFIER_POINTER(arg), TREE_INT_CST_LOW(line));
140
141 const char* op = IDENTIFIER_POINTER(arg);
142
143 seh_function* seh_fun = get_seh_function();
144 if (strcmp(op, "__seh$$except") == 0)
145 {
146 is_except = true;
147 seh_fun->except = true;
148 }
149 else if (strcmp(op, "__seh$$finally") == 0)
150 {
151 is_except = false;
152 seh_fun->unwind = true;
153 }
154 else
155 {
156 error("Wrong argument for %<#pragma REACTOS seh%>. Expected \"except\" or \"finally\"");
157 return;
158 }
159 seh_fun->count++;
160
161 seh_fun->handlers.push_back({is_except, (unsigned int)TREE_INT_CST_LOW(line)});
162
163 /* Make sure we use a frame pointer. REACTOS' PSEH depends on this */
164 cfun->machine->accesses_prev_frame = 1;
165
166 /* Keep handlerdata generation canonical: one SEH block per function. */
168}
UINT op
Definition: effect.c:236
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
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
static void mark_seh_function_noinline(void)
Definition: main.cpp:102
Definition: parser.c:49
void * arg
Definition: msvc.h:10

Referenced by register_seh_pragmas().

◆ mark_seh_function_noinline()

static void mark_seh_function_noinline ( void  )
static

Definition at line 102 of file main.cpp.

103{
104 tree fndecl = current_function_decl;
105
106 if (fndecl == NULL_TREE)
107 return;
108
109 DECL_UNINLINABLE(fndecl) = 1;
110 DECL_DECLARED_INLINE_P(fndecl) = 0;
111}

Referenced by handle_seh_pragma().

◆ plugin_init()

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

Definition at line 234 of file main.cpp.

236{
237 if (!plugin_default_version_check (version, &gcc_version))
238 {
239 std::cerr << "This GCC plugin is for version " << GCCPLUGIN_VERSION_MAJOR << "." << GCCPLUGIN_VERSION_MINOR << "\n";
240 return 1;
241 }
242
243 register_callback(info->base_name, PLUGIN_PRAGMAS, register_seh_pragmas, NULL);
244 register_callback(info->base_name, PLUGIN_FINISH_PARSE_FUNCTION, finish_seh_function, NULL);
245
246 return 0;
247}
#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:226
static void finish_seh_function(void *event_data, void *UNUSED user_data)
Definition: main.cpp:172

◆ register_seh_pragmas()

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

Definition at line 226 of file main.cpp.

227{
228 c_register_pragma("REACTOS", "seh", handle_seh_pragma);
229}
static void handle_seh_pragma(cpp_reader *UNUSED parser)
Definition: main.cpp:115

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.