10#include <plugin-version.h>
13#include <c-family/c-pragma.h>
14#include <c-family/c-common.h>
18#include <unordered_map>
23#define trace(...) fprintf(stderr, __VA_ARGS__)
28#define is_alpha(c) (((c)>64 && (c)<91) || ((c)>96 && (c)<123))
30#if defined(_WIN32) || defined(WIN32)
31#define VISIBLE __declspec(dllexport)
33#define VISIBLE __attribute__((__visibility__("default")))
36#define UNUSED __attribute__((__unused__))
72 asm_header = build_stmt(fun->function_start_locus, ASM_EXPR,
asm_header_text, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
78static std::unordered_map<struct function*, struct seh_function*>
func_seh_map = {};
104 tree fndecl = current_function_decl;
106 if (fndecl == NULL_TREE)
109 DECL_UNINLINABLE(fndecl) = 1;
110 DECL_DECLARED_INLINE_P(fndecl) = 0;
118 std::stringstream label_decl;
123 error(
"%<#pragma REACTOS seh%> is not allowed outside functions");
127 if ((pragma_lex(&
x) != CPP_OPEN_PAREN) ||
128 (pragma_lex(&
arg) != CPP_NAME) ||
129 (pragma_lex(&
x) != CPP_COMMA) ||
130 (pragma_lex(&
line) != CPP_NUMBER) ||
131 (pragma_lex(&
x) != CPP_CLOSE_PAREN) ||
132 (pragma_lex(&
x) != CPP_EOF)
135 error(
"%<#pragma REACTOS seh%> needs two parameters%>");
141 const char*
op = IDENTIFIER_POINTER(
arg);
144 if (
strcmp(
op,
"__seh$$except") == 0)
149 else if (
strcmp(
op,
"__seh$$finally") == 0)
156 error(
"Wrong argument for %<#pragma REACTOS seh%>. Expected \"except\" or \"finally\"");
161 seh_fun->
handlers.push_back({is_except, (
unsigned int)TREE_INT_CST_LOW(
line)});
164 cfun->machine->accesses_prev_frame = 1;
175 struct function* fun = DECL_STRUCT_FUNCTION(fndef);
185 if (DECL_FUNCTION_PERSONALITY(fndef) !=
nullptr)
187 error(
"Function %s has a personality. Are you mixing SEH with C++ exceptions ?",
188 IDENTIFIER_POINTER(fndef));
193 std::stringstream asm_str;
194 asm_str <<
".seh_handler __C_specific_handler";
196 asm_str <<
", @unwind";
198 asm_str <<
", @except";
200 asm_str <<
"\t.seh_handlerdata\n";
201 asm_str <<
"\t.long " << seh_fun->
count <<
"\n";
205 asm_str <<
"\n\t.rva " <<
"__seh2$$begin_try__" <<
handler.line;
206 asm_str <<
"\n\t.rva " <<
"__seh2$$end_try__" <<
handler.line;
207 asm_str <<
"\n\t.rva " <<
"__seh2$$filter__" <<
handler.line;
209 asm_str <<
"\n\t.rva " <<
"__seh2$$begin_except__" <<
handler.line;
211 asm_str <<
"\n\t.long 0";
213 asm_str <<
"\n\t.seh_code\n";
216 asm_str.str().c_str(),
235 struct plugin_gcc_version *
version)
237 if (!plugin_default_version_check (
version, &gcc_version))
239 std::cerr <<
"This GCC plugin is for version " << GCCPLUGIN_VERSION_MAJOR <<
"." << GCCPLUGIN_VERSION_MINOR <<
"\n";
static const WCHAR version[]
UINT(* handler)(MSIPACKAGE *)
_ACRTIMP int __cdecl strcmp(const char *, const char *)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei count
GLenum GLuint GLenum GLsizei const GLchar * buf
static short search(int val, const short *table, int size)
constexpr size_t k_header_statement_max_size
static void handle_seh_pragma(cpp_reader *UNUSED parser)
static struct seh_function * get_seh_function()
static void register_seh_pragmas(void *UNUSED event_data, void *UNUSED user_data)
int VISIBLE plugin_is_GPL_compatible
static void mark_seh_function_noinline(void)
static std::unordered_map< struct function *, struct seh_function * > func_seh_map
static void finish_seh_function(void *event_data, void *UNUSED user_data)
VISIBLE int plugin_init(struct plugin_name_args *info, struct plugin_gcc_version *version)
std::vector< seh_handler > handlers
seh_function(struct function *fun)