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 = {};
99 std::stringstream label_decl;
104 error(
"%<#pragma REACTOS seh%> is not allowed outside functions");
108 if ((pragma_lex(&
x) != CPP_OPEN_PAREN) ||
109 (pragma_lex(&
arg) != CPP_NAME) ||
110 (pragma_lex(&
x) != CPP_COMMA) ||
111 (pragma_lex(&
line) != CPP_NUMBER) ||
112 (pragma_lex(&
x) != CPP_CLOSE_PAREN) ||
113 (pragma_lex(&
x) != CPP_EOF)
116 error(
"%<#pragma REACTOS seh%> needs two parameters%>");
122 const char*
op = IDENTIFIER_POINTER(
arg);
125 if (
strcmp(
op,
"__seh$$except") == 0)
130 else if (
strcmp(
op,
"__seh$$finally") == 0)
137 error(
"Wrong argument for %<#pragma REACTOS seh%>. Expected \"except\" or \"finally\"");
142 seh_fun->
handlers.push_back({is_except, (
unsigned int)TREE_INT_CST_LOW(
line)});
145 cfun->machine->accesses_prev_frame = 1;
153 struct function* fun = DECL_STRUCT_FUNCTION(fndef);
163 if (DECL_FUNCTION_PERSONALITY(fndef) !=
nullptr)
165 error(
"Function %s has a personality. Are you mixing SEH with C++ exceptions ?",
166 IDENTIFIER_POINTER(fndef));
171 std::stringstream asm_str;
172 asm_str <<
".seh_handler __C_specific_handler";
174 asm_str <<
", @unwind";
176 asm_str <<
", @except";
178 asm_str <<
"\t.seh_handlerdata\n";
179 asm_str <<
"\t.long " << seh_fun->
count <<
"\n";
183 asm_str <<
"\n\t.rva " <<
"__seh2$$begin_try__" <<
handler.line;
184 asm_str <<
"\n\t.rva " <<
"__seh2$$end_try__" <<
handler.line;
185 asm_str <<
"\n\t.rva " <<
"__seh2$$filter__" <<
handler.line;
187 asm_str <<
"\n\t.rva " <<
"__seh2$$begin_except__" <<
handler.line;
189 asm_str <<
"\n\t.long 0";
191 asm_str <<
"\n\t.seh_code\n";
194 asm_str.str().c_str(),
213 struct plugin_gcc_version *
version)
215 if (!plugin_default_version_check (
version, &gcc_version))
217 std::cerr <<
"This GCC plugin is for version " << GCCPLUGIN_VERSION_MAJOR <<
"." << GCCPLUGIN_VERSION_MINOR <<
"\n";
int strcmp(const char *String1, const char *String2)
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
static const WCHAR version[]
UINT(* handler)(MSIPACKAGE *)
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 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)