Skip to content

Instantly share code, notes, and snippets.

@kumpera
Created December 15, 2009 14:36
Show Gist options
  • Save kumpera/256982 to your computer and use it in GitHub Desktop.
Save kumpera/256982 to your computer and use it in GitHub Desktop.
diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c
index eb9b3ce..b2d1ce8 100644
--- a/mono/mini/mini-amd64.c
+++ b/mono/mini/mini-amd64.c
@@ -1423,6 +1423,14 @@ mono_arch_allocate_vars (MonoCompile *cfg)
/* Allocate locals */
if (!cfg->globalra) {
offsets = mono_allocate_stack_slots_full (cfg, cfg->arch.omit_fp ? FALSE: TRUE, &locals_stack_size, &locals_stack_align);
+ if (locals_stack_size > MONO_ARCH_MAX_FRAME_SIZE) {
+ char *mname = mono_method_full_name (cfg->method, TRUE);
+ cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
+ cfg->exception_message = g_strdup_printf ("Method %s stack is too big.", mname);
+ g_free (mname);
+ return;
+ }
+
if (locals_stack_align) {
offset += (locals_stack_align - 1);
offset &= ~(locals_stack_align - 1);
@@ -5727,6 +5735,18 @@ mono_arch_emit_prolog (MonoCompile *cfg)
/* See mono_emit_stack_alloc */
#if defined(HOST_WIN32) || defined(MONO_ARCH_SIGSEGV_ON_ALTSTACK)
guint32 remaining_size = alloc_size;
+
+//--- fix the under allocation
+ guint32 required_code_size = ((remaining_size / 0x1000) + 1) * 7; //7 is the max size of amd64_alu_reg_imm
+ guint32 offset = code - cfg->native_code;
+ if (G_UNLIKELY (required_code_size > (cfg->code_size - offset))) {
+ while (required_code_size > (cfg->code_size - offset))
+ cfg->code_size *= 2;
+ cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
+ code = cfg->native_code + offset;
+ mono_jit_stats.code_reallocs++;
+ }
+//---
while (remaining_size >= 0x1000) {
amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 0x1000);
if (cfg->arch.omit_fp) {
diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h
index 334e802..6775117 100644
--- a/mono/mini/mini-amd64.h
+++ b/mono/mini/mini-amd64.h
@@ -131,6 +131,9 @@ struct sigcontext {
#define MONO_ARCH_RETREG1 X86_EAX
#define MONO_ARCH_RETREG2 X86_EDX
+/*This is the max size of the locals area of a given frame. I think 1MB is a safe default for now*/
+#define MONO_ARCH_MAX_FRAME_SIZE 0x100000
+
struct MonoLMF {
/*
* If the lowest bit is set to 1, then this LMF has the rip field set. Otherwise,
diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c
index 07de7c4..397b2e1 100644
--- a/mono/mini/mini-x86.c
+++ b/mono/mini/mini-x86.c
@@ -990,6 +990,13 @@ mono_arch_allocate_vars (MonoCompile *cfg)
/* Allocate locals */
offsets = mono_allocate_stack_slots (cfg, &locals_stack_size, &locals_stack_align);
+ if (locals_stack_size > MONO_ARCH_MAX_FRAME_SIZE) {
+ char *mname = mono_method_full_name (cfg->method, TRUE);
+ cfg->exception_type = MONO_EXCEPTION_INVALID_PROGRAM;
+ cfg->exception_message = g_strdup_printf ("Method %s stack is too big.", mname);
+ g_free (mname);
+ return;
+ }
if (locals_stack_align) {
offset += (locals_stack_align - 1);
offset &= ~(locals_stack_align - 1);
diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h
index f0ac298..72be2e7 100644
--- a/mono/mini/mini-x86.h
+++ b/mono/mini/mini-x86.h
@@ -123,6 +123,9 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep);
#define MONO_ARCH_RETREG1 X86_EAX
#define MONO_ARCH_RETREG2 X86_EDX
+/*This is the max size of the locals area of a given frame. I think 1MB is a safe default for now*/
+#define MONO_ARCH_MAX_FRAME_SIZE 100000
+
struct MonoLMF {
/*
* If the lowest bit is set to 1, then this is a trampoline LMF frame.
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index 9aaab81..3500eda 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -3789,8 +3789,11 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
//print_dfn (cfg);
/* variables are allocated after decompose, since decompose could create temps */
- if (!cfg->globalra && !COMPILE_LLVM (cfg))
+ if (!cfg->globalra && !COMPILE_LLVM (cfg)) {
mono_arch_allocate_vars (cfg);
+ if (cfg->exception_type)
+ return cfg;
+ }
{
MonoBasicBlock *bb;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment