static MonoMethod*
create_allocator (int atype, ManagedAllocatorVariant variant)
{
- int p_var, size_var, thread_var G_GNUC_UNUSED;
+ int p_var, size_var, real_size_var, thread_var G_GNUC_UNUSED;
gboolean slowpath = variant == MANAGED_ALLOCATOR_SLOW_PATH;
guint32 slowpath_branch, max_size_branch;
MonoMethodBuilder *mb;
mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_NONE);
#endif
+ if (nursery_canaries_enabled ()) {
+ real_size_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+ mono_mb_emit_ldloc (mb, size_var);
+ mono_mb_emit_stloc(mb, real_size_var);
+ }
+ else
+ real_size_var = size_var;
+
/* size += ALLOC_ALIGN - 1; */
mono_mb_emit_ldloc (mb, size_var);
mono_mb_emit_icon (mb, SGEN_ALLOC_ALIGN - 1);
mono_mb_emit_ldloc (mb, size_var);
mono_mb_emit_byte (mb, CEE_CONV_I);
mono_mb_emit_byte (mb, CEE_ADD);
+
+ if (nursery_canaries_enabled ()) {
+ mono_mb_emit_icon (mb, CANARY_SIZE);
+ mono_mb_emit_byte (mb, CEE_ADD);
+ }
mono_mb_emit_stloc (mb, new_next_var);
/* if (G_LIKELY (new_next < tlab_temp_end)) */
/* FIXME: mono_gc_alloc_obj takes a 'size_t' as an argument, not an int32 */
mono_mb_emit_ldarg (mb, 0);
- mono_mb_emit_ldloc (mb, size_var);
+ mono_mb_emit_ldloc (mb, real_size_var);
if (atype == ATYPE_NORMAL || atype == ATYPE_SMALL) {
mono_mb_emit_icall (mb, mono_gc_alloc_obj);
} else if (atype == ATYPE_VECTOR) {
mono_mb_emit_ldarg (mb, 0);
mono_mb_emit_byte (mb, CEE_STIND_I);
+ /* mark object end with nursery word */
+ if (nursery_canaries_enabled ()) {
+ mono_mb_emit_ldloc (mb, p_var);
+ mono_mb_emit_ldloc (mb, real_size_var);
+ mono_mb_emit_byte (mb, MONO_CEE_ADD);
+ mono_mb_emit_icon8 (mb, (mword) CANARY_STRING);
+ mono_mb_emit_icon (mb, CANARY_SIZE);
+ mono_mb_emit_byte (mb, MONO_CEE_PREFIX1);
+ mono_mb_emit_byte (mb, CEE_CPBLK);
+ }
+
if (atype == ATYPE_VECTOR) {
/* arr->max_length = max_length; */
mono_mb_emit_ldloc (mb, p_var);
sgen_gc_init ();
- if (nursery_canaries_enabled ())
- sgen_set_use_managed_allocator (FALSE);
-
#if defined(HAVE_KW_THREAD)
/* This can happen with using libmonosgen.so */
if (mono_tls_key_get_offset (TLS_KEY_SGEN_THREAD_INFO) == -1)
#define CANARY_VALID(addr) (strncmp ((char*) (addr), CANARY_STRING, CANARY_SIZE) == 0)
#define CHECK_CANARY_FOR_OBJECT(addr,fail) if (nursery_canaries_enabled ()) { \
- char* canary_ptr = (char*) (addr) + sgen_safe_object_get_size_unaligned ((GCObject *) (addr)); \
+ guint size = sgen_safe_object_get_size_unaligned ((GCObject *) (addr)); \
+ char* canary_ptr = (char*) (addr) + size; \
if (!CANARY_VALID(canary_ptr)) { \
- char canary_copy[CANARY_SIZE +1]; \
- strncpy (canary_copy, canary_ptr, CANARY_SIZE); \
- canary_copy[CANARY_SIZE] = 0; \
- if ((fail)) \
- g_error ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), CANARY_STRING, canary_copy); \
- else \
- g_warning ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), CANARY_STRING, canary_copy); \
+ char *window_start, *window_end; \
+ window_start = (char*)(addr) - 128; \
+ if (!sgen_ptr_in_nursery (window_start)) \
+ window_start = sgen_get_nursery_start (); \
+ window_end = (char*)(addr) + 128; \
+ if (!sgen_ptr_in_nursery (window_end)) \
+ window_end = sgen_get_nursery_end (); \
+ fprintf (stderr, "\nCANARY ERROR - Type:%s Size:%d Address:%p Data:\n", sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), size, (char*) addr); \
+ fwrite (addr, sizeof (char), size, stderr); \
+ fprintf (stderr, "\nCanary zone (next 12 chars):\n"); \
+ fwrite (canary_ptr, sizeof (char), 12, stderr); \
+ fprintf (stderr, "\nOriginal canary string:\n"); \
+ fwrite (CANARY_STRING, sizeof (char), 8, stderr); \
+ for (int x = -8; x <= 8; x++) { \
+ if (canary_ptr + x < (char*) addr); \
+ continue; \
+ if (CANARY_VALID(canary_ptr +x)) \
+ fprintf (stderr, "\nCANARY ERROR - canary found at offset %d\n", x); \
+ } \
+ fprintf (stderr, "\nSurrounding nursery (%p - %p):\n", window_start, window_end); \
+ fwrite (window_start, sizeof (char), window_end - window_start, stderr); \
} }
/*