1 /**
2  * \file
3  * Routines for encoding SRE builders into a
4  * MonoDynamicImage and generating tokens.
5  *
6  *
7  * Author:
8  *   Paolo Molaro (lupus@ximian.com)
9  *
10  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
12  * Copyright 2011 Rodrigo Kumpera
13  * Copyright 2016 Microsoft
14  *
15  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
16  */
17 #include <config.h>
18 #include <glib.h>
19 
20 #include "mono/metadata/dynamic-image-internals.h"
21 #include "mono/metadata/dynamic-stream-internals.h"
22 #include "mono/metadata/object-internals.h"
23 #include "mono/metadata/reflection-internals.h"
24 #include "mono/metadata/sre-internals.h"
25 #include "mono/metadata/tabledefs.h"
26 #include "mono/metadata/tokentype.h"
27 #include "mono/utils/checked-build.h"
28 
29 typedef struct {
30 	char *p;
31 	char *buf;
32 	char *end;
33 } SigBuffer;
34 
35 static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
36 static void    encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
37 static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
38 
39 static guint32
mono_image_add_stream_data(MonoDynamicStream * stream,const char * data,guint32 len)40 mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
41 {
42 	return mono_dynstream_add_data (stream, data, len);
43 }
44 
45 static void
alloc_table(MonoDynamicTable * table,guint nrows)46 alloc_table (MonoDynamicTable *table, guint nrows)
47 {
48 	mono_dynimage_alloc_table (table, nrows);
49 }
50 
51 static void
sigbuffer_init(SigBuffer * buf,int size)52 sigbuffer_init (SigBuffer *buf, int size)
53 {
54 	MONO_REQ_GC_NEUTRAL_MODE;
55 
56 	buf->buf = (char *)g_malloc (size);
57 	buf->p = buf->buf;
58 	buf->end = buf->buf + size;
59 }
60 
61 static void
sigbuffer_make_room(SigBuffer * buf,int size)62 sigbuffer_make_room (SigBuffer *buf, int size)
63 {
64 	MONO_REQ_GC_NEUTRAL_MODE;
65 
66 	if (buf->end - buf->p < size) {
67 		int new_size = buf->end - buf->buf + size + 32;
68 		char *p = (char *)g_realloc (buf->buf, new_size);
69 		size = buf->p - buf->buf;
70 		buf->buf = p;
71 		buf->p = p + size;
72 		buf->end = buf->buf + new_size;
73 	}
74 }
75 
76 static void
sigbuffer_add_value(SigBuffer * buf,guint32 val)77 sigbuffer_add_value (SigBuffer *buf, guint32 val)
78 {
79 	MONO_REQ_GC_NEUTRAL_MODE;
80 
81 	sigbuffer_make_room (buf, 6);
82 	mono_metadata_encode_value (val, buf->p, &buf->p);
83 }
84 
85 static void
sigbuffer_add_byte(SigBuffer * buf,guint8 val)86 sigbuffer_add_byte (SigBuffer *buf, guint8 val)
87 {
88 	MONO_REQ_GC_NEUTRAL_MODE;
89 
90 	sigbuffer_make_room (buf, 1);
91 	buf->p [0] = val;
92 	buf->p++;
93 }
94 
95 static void
sigbuffer_add_mem(SigBuffer * buf,char * p,guint32 size)96 sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
97 {
98 	MONO_REQ_GC_NEUTRAL_MODE;
99 
100 	sigbuffer_make_room (buf, size);
101 	memcpy (buf->p, p, size);
102 	buf->p += size;
103 }
104 
105 static void
sigbuffer_free(SigBuffer * buf)106 sigbuffer_free (SigBuffer *buf)
107 {
108 	MONO_REQ_GC_NEUTRAL_MODE;
109 
110 	g_free (buf->buf);
111 }
112 
113 static guint32
sigbuffer_add_to_blob_cached(MonoDynamicImage * assembly,SigBuffer * buf)114 sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
115 {
116 	MONO_REQ_GC_NEUTRAL_MODE;
117 
118 	char blob_size [8];
119 	char *b = blob_size;
120 	guint32 size = buf->p - buf->buf;
121 	/* store length */
122 	g_assert (size <= (buf->end - buf->buf));
123 	mono_metadata_encode_value (size, b, &b);
124 	return mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
125 }
126 
127 
128 static void
encode_generic_class(MonoDynamicImage * assembly,MonoGenericClass * gclass,SigBuffer * buf)129 encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
130 {
131 	MONO_REQ_GC_NEUTRAL_MODE;
132 
133 	int i;
134 	MonoGenericInst *class_inst;
135 	MonoClass *klass;
136 
137 	g_assert (gclass);
138 
139 	class_inst = gclass->context.class_inst;
140 
141 	sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
142 	klass = gclass->container_class;
143 	sigbuffer_add_value (buf, klass->byval_arg.type);
144 	sigbuffer_add_value (buf, mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
145 
146 	sigbuffer_add_value (buf, class_inst->type_argc);
147 	for (i = 0; i < class_inst->type_argc; ++i)
148 		encode_type (assembly, class_inst->type_argv [i], buf);
149 
150 }
151 
152 static void
encode_type(MonoDynamicImage * assembly,MonoType * type,SigBuffer * buf)153 encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
154 {
155 	MONO_REQ_GC_NEUTRAL_MODE;
156 
157 	if (!type) {
158 		g_assert_not_reached ();
159 		return;
160 	}
161 
162 	if (type->byref)
163 		sigbuffer_add_value (buf, MONO_TYPE_BYREF);
164 
165 	switch (type->type){
166 	case MONO_TYPE_VOID:
167 	case MONO_TYPE_BOOLEAN:
168 	case MONO_TYPE_CHAR:
169 	case MONO_TYPE_I1:
170 	case MONO_TYPE_U1:
171 	case MONO_TYPE_I2:
172 	case MONO_TYPE_U2:
173 	case MONO_TYPE_I4:
174 	case MONO_TYPE_U4:
175 	case MONO_TYPE_I8:
176 	case MONO_TYPE_U8:
177 	case MONO_TYPE_R4:
178 	case MONO_TYPE_R8:
179 	case MONO_TYPE_I:
180 	case MONO_TYPE_U:
181 	case MONO_TYPE_STRING:
182 	case MONO_TYPE_OBJECT:
183 	case MONO_TYPE_TYPEDBYREF:
184 		sigbuffer_add_value (buf, type->type);
185 		break;
186 	case MONO_TYPE_PTR:
187 		sigbuffer_add_value (buf, type->type);
188 		encode_type (assembly, type->data.type, buf);
189 		break;
190 	case MONO_TYPE_SZARRAY:
191 		sigbuffer_add_value (buf, type->type);
192 		encode_type (assembly, &type->data.klass->byval_arg, buf);
193 		break;
194 	case MONO_TYPE_VALUETYPE:
195 	case MONO_TYPE_CLASS: {
196 		MonoClass *k = mono_class_from_mono_type (type);
197 
198 		if (mono_class_is_gtd (k)) {
199 			MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, mono_class_get_generic_container (k)->context.class_inst, TRUE);
200 			encode_generic_class (assembly, gclass, buf);
201 		} else {
202 			/*
203 			 * Make sure we use the correct type.
204 			 */
205 			sigbuffer_add_value (buf, k->byval_arg.type);
206 			/*
207 			 * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
208 			 * otherwise two typerefs could point to the same type, leading to
209 			 * verification errors.
210 			 */
211 			sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, &k->byval_arg));
212 		}
213 		break;
214 	}
215 	case MONO_TYPE_ARRAY:
216 		sigbuffer_add_value (buf, type->type);
217 		encode_type (assembly, &type->data.array->eklass->byval_arg, buf);
218 		sigbuffer_add_value (buf, type->data.array->rank);
219 		sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
220 		sigbuffer_add_value (buf, 0);
221 		break;
222 	case MONO_TYPE_GENERICINST:
223 		encode_generic_class (assembly, type->data.generic_class, buf);
224 		break;
225 	case MONO_TYPE_VAR:
226 	case MONO_TYPE_MVAR:
227 		sigbuffer_add_value (buf, type->type);
228 		sigbuffer_add_value (buf, mono_type_get_generic_param_num (type));
229 		break;
230 	default:
231 		g_error ("need to encode type %x", type->type);
232 	}
233 }
234 
235 static void
encode_reflection_type(MonoDynamicImage * assembly,MonoReflectionTypeHandle type,SigBuffer * buf,MonoError * error)236 encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionTypeHandle type, SigBuffer *buf, MonoError *error)
237 {
238 	MONO_REQ_GC_UNSAFE_MODE;
239 
240 	error_init (error);
241 
242 	if (!type) {
243 		sigbuffer_add_value (buf, MONO_TYPE_VOID);
244 		return;
245 	}
246 
247 	MonoType *t = mono_reflection_type_handle_mono_type (type, error);
248 	return_if_nok (error);
249 	encode_type (assembly, t, buf);
250 }
251 
252 static void
encode_reflection_type_raw(MonoDynamicImage * assembly,MonoReflectionType * type_raw,SigBuffer * buf,MonoError * error)253 encode_reflection_type_raw (MonoDynamicImage *assembly, MonoReflectionType* type_raw, SigBuffer *buf, MonoError *error)
254 {
255 	HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_reflection_type_raw should use handles */
256 	error_init (error);
257 	MONO_HANDLE_DCL (MonoReflectionType, type);
258 	encode_reflection_type (assembly, type, buf, error);
259 	HANDLE_FUNCTION_RETURN ();
260 }
261 
262 
263 static void
encode_custom_modifiers(MonoDynamicImage * assembly,MonoArrayHandle modreq,MonoArrayHandle modopt,SigBuffer * buf,MonoError * error)264 encode_custom_modifiers (MonoDynamicImage *assembly, MonoArrayHandle modreq, MonoArrayHandle modopt, SigBuffer *buf, MonoError *error)
265 {
266 	HANDLE_FUNCTION_ENTER ();
267 	MONO_REQ_GC_UNSAFE_MODE;
268 
269 	int i;
270 
271 	error_init (error);
272 
273 	if (!MONO_HANDLE_IS_NULL (modreq)) {
274 		for (i = 0; i < mono_array_handle_length (modreq); ++i) {
275 			MonoType *mod = mono_type_array_get_and_resolve (modreq, i, error);
276 			goto_if_nok (error, leave);
277 			sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
278 			sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
279 		}
280 	}
281 	if (!MONO_HANDLE_IS_NULL (modopt)) {
282 		for (i = 0; i < mono_array_handle_length (modopt); ++i) {
283 			MonoType *mod = mono_type_array_get_and_resolve (modopt, i, error);
284 			goto_if_nok (error, leave);
285 			sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
286 			sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
287 		}
288 	}
289 leave:
290 	HANDLE_FUNCTION_RETURN ();
291 }
292 
293 static void
encode_custom_modifiers_raw(MonoDynamicImage * assembly,MonoArray * modreq_raw,MonoArray * modopt_raw,SigBuffer * buf,MonoError * error)294 encode_custom_modifiers_raw (MonoDynamicImage *assembly, MonoArray *modreq_raw, MonoArray *modopt_raw, SigBuffer *buf, MonoError *error)
295 {
296 	HANDLE_FUNCTION_ENTER (); /* FIXME callers of encode_custom_modifiers_raw should use handles */
297 	error_init (error);
298 	MONO_HANDLE_DCL (MonoArray, modreq);
299 	MONO_HANDLE_DCL (MonoArray, modopt);
300 	encode_custom_modifiers (assembly, modreq, modopt, buf, error);
301 	HANDLE_FUNCTION_RETURN ();
302 }
303 
304 
305 #ifndef DISABLE_REFLECTION_EMIT
306 guint32
mono_dynimage_encode_method_signature(MonoDynamicImage * assembly,MonoMethodSignature * sig)307 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
308 {
309 	MONO_REQ_GC_UNSAFE_MODE;
310 
311 	SigBuffer buf;
312 	int i;
313 	guint32 nparams =  sig->param_count;
314 	guint32 idx;
315 
316 	if (!assembly->save)
317 		return 0;
318 
319 	sigbuffer_init (&buf, 32);
320 	/*
321 	 * FIXME: vararg, explicit_this, differenc call_conv values...
322 	 */
323 	idx = sig->call_convention;
324 	if (sig->hasthis)
325 		idx |= 0x20; /* hasthis */
326 	if (sig->generic_param_count)
327 		idx |= 0x10; /* generic */
328 	sigbuffer_add_byte (&buf, idx);
329 	if (sig->generic_param_count)
330 		sigbuffer_add_value (&buf, sig->generic_param_count);
331 	sigbuffer_add_value (&buf, nparams);
332 	encode_type (assembly, sig->ret, &buf);
333 	for (i = 0; i < nparams; ++i) {
334 		if (i == sig->sentinelpos)
335 			sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
336 		encode_type (assembly, sig->params [i], &buf);
337 	}
338 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
339 	sigbuffer_free (&buf);
340 	return idx;
341 }
342 #else /* DISABLE_REFLECTION_EMIT */
343 guint32
mono_dynimage_encode_method_signature(MonoDynamicImage * assembly,MonoMethodSignature * sig)344 mono_dynimage_encode_method_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
345 {
346 	g_assert_not_reached ();
347 	return 0;
348 }
349 #endif
350 
351 guint32
mono_dynimage_encode_method_builder_signature(MonoDynamicImage * assembly,ReflectionMethodBuilder * mb,MonoError * error)352 mono_dynimage_encode_method_builder_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb, MonoError *error)
353 {
354 	MONO_REQ_GC_UNSAFE_MODE;
355 
356 	error_init (error);
357 
358 	/*
359 	 * FIXME: reuse code from method_encode_signature().
360 	 */
361 	SigBuffer buf;
362 	int i;
363 	guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
364 	guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
365 	guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
366 	guint32 idx;
367 
368 	sigbuffer_init (&buf, 32);
369 	/* LAMESPEC: all the call conv spec is foobared */
370 	idx = mb->call_conv & 0x60; /* has-this, explicit-this */
371 	if (mb->call_conv & 2)
372 		idx |= 0x5; /* vararg */
373 	if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
374 		idx |= 0x20; /* hasthis */
375 	if (ngparams)
376 		idx |= 0x10; /* generic */
377 	sigbuffer_add_byte (&buf, idx);
378 	if (ngparams)
379 		sigbuffer_add_value (&buf, ngparams);
380 	sigbuffer_add_value (&buf, nparams + notypes);
381 	encode_custom_modifiers_raw (assembly, mb->return_modreq, mb->return_modopt, &buf, error);
382 	goto_if_nok (error, leave);
383 	encode_reflection_type_raw (assembly, mb->rtype, &buf, error);
384 	goto_if_nok (error, leave);
385 	for (i = 0; i < nparams; ++i) {
386 		MonoArray *modreq = NULL;
387 		MonoArray *modopt = NULL;
388 		MonoReflectionType *pt;
389 
390 		if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
391 			modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
392 		if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
393 			modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
394 		encode_custom_modifiers_raw (assembly, modreq, modopt, &buf, error);
395 		goto_if_nok (error, leave);
396 		pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
397 		encode_reflection_type_raw (assembly, pt, &buf, error);
398 		goto_if_nok (error, leave);
399 	}
400 	if (notypes)
401 		sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
402 	for (i = 0; i < notypes; ++i) {
403 		MonoReflectionType *pt;
404 
405 		pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
406 		encode_reflection_type_raw (assembly, pt, &buf, error);
407 		goto_if_nok (error, leave);
408 	}
409 
410 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
411 leave:
412 	sigbuffer_free (&buf);
413 	return idx;
414 }
415 
416 guint32
mono_dynimage_encode_locals(MonoDynamicImage * assembly,MonoReflectionILGen * ilgen,MonoError * error)417 mono_dynimage_encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, MonoError *error)
418 {
419 	MONO_REQ_GC_UNSAFE_MODE;
420 
421 	error_init (error);
422 
423 	MonoDynamicTable *table;
424 	guint32 *values;
425 	guint32 idx, sig_idx;
426 	guint nl = mono_array_length (ilgen->locals);
427 	SigBuffer buf;
428 	int i;
429 
430 	sigbuffer_init (&buf, 32);
431 	sigbuffer_add_value (&buf, 0x07);
432 	sigbuffer_add_value (&buf, nl);
433 	for (i = 0; i < nl; ++i) {
434 		MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
435 
436 		if (lb->is_pinned)
437 			sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
438 
439 		encode_reflection_type_raw (assembly, (MonoReflectionType*)lb->type, &buf, error);
440 		if (!is_ok (error)) {
441 			sigbuffer_free (&buf);
442 			return 0;
443 		}
444 	}
445 	sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
446 	sigbuffer_free (&buf);
447 
448 	if (assembly->standalonesig_cache == NULL)
449 		assembly->standalonesig_cache = g_hash_table_new (NULL, NULL);
450 	idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx)));
451 	if (idx)
452 		return idx;
453 
454 	table = &assembly->tables [MONO_TABLE_STANDALONESIG];
455 	idx = table->next_idx ++;
456 	table->rows ++;
457 	alloc_table (table, table->rows);
458 	values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
459 
460 	values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
461 
462 	g_hash_table_insert (assembly->standalonesig_cache, GUINT_TO_POINTER (sig_idx), GUINT_TO_POINTER (idx));
463 
464 	return idx;
465 }
466 
467 
468 /*
469  * Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
470  * dest may be misaligned.
471  */
472 static void
swap_with_size(char * dest,const char * val,int len,int nelem)473 swap_with_size (char *dest, const char* val, int len, int nelem) {
474 	MONO_REQ_GC_NEUTRAL_MODE;
475 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
476 	int elem;
477 
478 	for (elem = 0; elem < nelem; ++elem) {
479 		switch (len) {
480 		case 1:
481 			*dest = *val;
482 			break;
483 		case 2:
484 			dest [0] = val [1];
485 			dest [1] = val [0];
486 			break;
487 		case 4:
488 			dest [0] = val [3];
489 			dest [1] = val [2];
490 			dest [2] = val [1];
491 			dest [3] = val [0];
492 			break;
493 		case 8:
494 			dest [0] = val [7];
495 			dest [1] = val [6];
496 			dest [2] = val [5];
497 			dest [3] = val [4];
498 			dest [4] = val [3];
499 			dest [5] = val [2];
500 			dest [6] = val [1];
501 			dest [7] = val [0];
502 			break;
503 		default:
504 			g_assert_not_reached ();
505 		}
506 		dest += len;
507 		val += len;
508 	}
509 #else
510 	memcpy (dest, val, len * nelem);
511 #endif
512 }
513 
514 
515 guint32
mono_dynimage_encode_constant(MonoDynamicImage * assembly,MonoObject * val,MonoTypeEnum * ret_type)516 mono_dynimage_encode_constant (MonoDynamicImage *assembly, MonoObject *val, MonoTypeEnum *ret_type)
517 {
518 	MONO_REQ_GC_UNSAFE_MODE;
519 
520 	char blob_size [64];
521 	char *b = blob_size;
522 	char *box_val;
523 	char* buf;
524 	guint32 idx = 0, len = 0, dummy = 0;
525 
526 	buf = (char *)g_malloc (64);
527 	if (!val) {
528 		*ret_type = MONO_TYPE_CLASS;
529 		len = 4;
530 		box_val = (char*)&dummy;
531 	} else {
532 		box_val = ((char*)val) + sizeof (MonoObject);
533 		*ret_type = val->vtable->klass->byval_arg.type;
534 	}
535 handle_enum:
536 	switch (*ret_type) {
537 	case MONO_TYPE_BOOLEAN:
538 	case MONO_TYPE_U1:
539 	case MONO_TYPE_I1:
540 		len = 1;
541 		break;
542 	case MONO_TYPE_CHAR:
543 	case MONO_TYPE_U2:
544 	case MONO_TYPE_I2:
545 		len = 2;
546 		break;
547 	case MONO_TYPE_U4:
548 	case MONO_TYPE_I4:
549 	case MONO_TYPE_R4:
550 		len = 4;
551 		break;
552 	case MONO_TYPE_U8:
553 	case MONO_TYPE_I8:
554 		len = 8;
555 		break;
556 	case MONO_TYPE_R8:
557 		len = 8;
558 		break;
559 	case MONO_TYPE_VALUETYPE: {
560 		MonoClass *klass = val->vtable->klass;
561 
562 		if (klass->enumtype) {
563 			*ret_type = mono_class_enum_basetype (klass)->type;
564 			goto handle_enum;
565 		} else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
566 			len = 8;
567 		} else
568 			g_error ("we can't encode valuetypes, we should have never reached this line");
569 		break;
570 	}
571 	case MONO_TYPE_CLASS:
572 		break;
573 	case MONO_TYPE_STRING: {
574 		MonoString *str = (MonoString*)val;
575 		/* there is no signature */
576 		len = str->length * 2;
577 		mono_metadata_encode_value (len, b, &b);
578 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
579 		{
580 			char *swapped = g_malloc (2 * mono_string_length (str));
581 			const char *p = (const char*)mono_string_chars (str);
582 
583 			swap_with_size (swapped, p, 2, mono_string_length (str));
584 			idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, swapped, len);
585 			g_free (swapped);
586 		}
587 #else
588 		idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, (char*)mono_string_chars (str), len);
589 #endif
590 
591 		g_free (buf);
592 		return idx;
593 	}
594 	case MONO_TYPE_GENERICINST:
595 		*ret_type = mono_class_get_generic_class (val->vtable->klass)->container_class->byval_arg.type;
596 		goto handle_enum;
597 	default:
598 		g_error ("we don't encode constant type 0x%02x yet", *ret_type);
599 	}
600 
601 	/* there is no signature */
602 	mono_metadata_encode_value (len, b, &b);
603 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
604 	idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
605 	swap_with_size (blob_size, box_val, len, 1);
606 	mono_image_add_stream_data (&assembly->blob, blob_size, len);
607 #else
608 	idx = mono_dynamic_image_add_to_blob_cached (assembly, blob_size, b-blob_size, box_val, len);
609 #endif
610 
611 	g_free (buf);
612 	return idx;
613 }
614 
615 guint32
mono_dynimage_encode_field_signature(MonoDynamicImage * assembly,MonoReflectionFieldBuilder * fb,MonoError * error)616 mono_dynimage_encode_field_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb, MonoError *error)
617 {
618 	MONO_REQ_GC_UNSAFE_MODE;
619 
620 	error_init (error);
621 
622 	SigBuffer buf;
623 	guint32 idx;
624 	guint32 typespec = 0;
625 	MonoType *type;
626 	MonoClass *klass;
627 
628 	type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
629 	return_val_if_nok (error, 0);
630 	klass = mono_class_from_mono_type (type);
631 
632 	sigbuffer_init (&buf, 32);
633 
634 	sigbuffer_add_value (&buf, 0x06);
635 	encode_custom_modifiers_raw (assembly, fb->modreq, fb->modopt, &buf, error);
636 	goto_if_nok (error, fail);
637 	/* encode custom attributes before the type */
638 
639 	if (mono_class_is_gtd (klass))
640 		typespec = create_typespec (assembly, type);
641 
642 	if (typespec) {
643 		MonoGenericClass *gclass;
644 		gclass = mono_metadata_lookup_generic_class (klass, mono_class_get_generic_container (klass)->context.class_inst, TRUE);
645 		encode_generic_class (assembly, gclass, &buf);
646 	} else {
647 		encode_type (assembly, type, &buf);
648 	}
649 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
650 	sigbuffer_free (&buf);
651 	return idx;
652 fail:
653 	sigbuffer_free (&buf);
654 	return 0;
655 }
656 
657 #ifndef DISABLE_REFLECTION_EMIT
658 /*field_image is the image to which the eventual custom mods have been encoded against*/
659 guint32
mono_dynimage_encode_fieldref_signature(MonoDynamicImage * assembly,MonoImage * field_image,MonoType * type)660 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
661 {
662 	MONO_REQ_GC_NEUTRAL_MODE;
663 
664 	SigBuffer buf;
665 	guint32 idx, i, token;
666 
667 	if (!assembly->save)
668 		return 0;
669 
670 	sigbuffer_init (&buf, 32);
671 
672 	sigbuffer_add_value (&buf, 0x06);
673 	/* encode custom attributes before the type */
674 	if (type->num_mods) {
675 		for (i = 0; i < type->num_mods; ++i) {
676 			if (field_image) {
677 				MonoError error;
678 				MonoClass *klass = mono_class_get_checked (field_image, type->modifiers [i].token, &error);
679 				g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
680 
681 				token = mono_image_typedef_or_ref (assembly, &klass->byval_arg);
682 			} else {
683 				token = type->modifiers [i].token;
684 			}
685 
686 			if (type->modifiers [i].required)
687 				sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_REQD);
688 			else
689 				sigbuffer_add_byte (&buf, MONO_TYPE_CMOD_OPT);
690 
691 			sigbuffer_add_value (&buf, token);
692 		}
693 	}
694 	encode_type (assembly, type, &buf);
695 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
696 	sigbuffer_free (&buf);
697 	return idx;
698 }
699 #else /* DISABLE_REFLECTION_EMIT */
700 guint32
mono_dynimage_encode_fieldref_signature(MonoDynamicImage * assembly,MonoImage * field_image,MonoType * type)701 mono_dynimage_encode_fieldref_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
702 {
703 	g_assert_not_reached ();
704 	return 0;
705 }
706 #endif /* DISABLE_REFLECTION_EMIT */
707 
708 static guint32
create_typespec(MonoDynamicImage * assembly,MonoType * type)709 create_typespec (MonoDynamicImage *assembly, MonoType *type)
710 {
711 	MONO_REQ_GC_NEUTRAL_MODE;
712 
713 	MonoDynamicTable *table;
714 	guint32 *values;
715 	guint32 token;
716 	SigBuffer buf;
717 
718 	if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
719 		return token;
720 
721 	sigbuffer_init (&buf, 32);
722 	switch (type->type) {
723 	case MONO_TYPE_FNPTR:
724 	case MONO_TYPE_PTR:
725 	case MONO_TYPE_SZARRAY:
726 	case MONO_TYPE_ARRAY:
727 	case MONO_TYPE_VAR:
728 	case MONO_TYPE_MVAR:
729 	case MONO_TYPE_GENERICINST:
730 		encode_type (assembly, type, &buf);
731 		break;
732 	case MONO_TYPE_CLASS:
733 	case MONO_TYPE_VALUETYPE: {
734 		MonoClass *k = mono_class_from_mono_type (type);
735 		if (!k || !mono_class_is_gtd (k)) {
736 			sigbuffer_free (&buf);
737 			return 0;
738 		}
739 		encode_type (assembly, type, &buf);
740 		break;
741 	}
742 	default:
743 		sigbuffer_free (&buf);
744 		return 0;
745 	}
746 
747 	table = &assembly->tables [MONO_TABLE_TYPESPEC];
748 	if (assembly->save) {
749 		token = sigbuffer_add_to_blob_cached (assembly, &buf);
750 		alloc_table (table, table->rows + 1);
751 		values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
752 		values [MONO_TYPESPEC_SIGNATURE] = token;
753 	}
754 	sigbuffer_free (&buf);
755 
756 	token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
757 	g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
758 	table->next_idx ++;
759 	return token;
760 }
761 
762 guint32
mono_dynimage_encode_typedef_or_ref_full(MonoDynamicImage * assembly,MonoType * type,gboolean try_typespec)763 mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
764 {
765 	MONO_REQ_GC_UNSAFE_MODE;
766 	HANDLE_FUNCTION_ENTER ();
767 
768 	MonoDynamicTable *table;
769 	guint32 *values;
770 	guint32 token, scope, enclosing;
771 	MonoClass *klass;
772 
773 	/* if the type requires a typespec, we must try that first*/
774 	if (try_typespec && (token = create_typespec (assembly, type)))
775 		goto leave;
776 	token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
777 	if (token)
778 		goto leave;
779 	klass = mono_class_from_mono_type (type);
780 
781 	MonoReflectionTypeBuilderHandle tb = MONO_HANDLE_CAST (MonoReflectionTypeBuilder, mono_class_get_ref_info (klass));
782 	/*
783 	 * If it's in the same module and not a generic type parameter:
784 	 */
785 	if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) &&
786 			(type->type != MONO_TYPE_MVAR)) {
787 		token = MONO_TYPEDEFORREF_TYPEDEF | (MONO_HANDLE_GETVAL (tb, table_idx) << MONO_TYPEDEFORREF_BITS);
788 		/* This function is called multiple times from sre and sre-save, so same object is okay */
789 		mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
790 		goto leave;
791 	}
792 
793 	if (klass->nested_in) {
794 		enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
795 		/* get the typeref idx of the enclosing type */
796 		enclosing >>= MONO_TYPEDEFORREF_BITS;
797 		scope = (enclosing << MONO_RESOLUTION_SCOPE_BITS) | MONO_RESOLUTION_SCOPE_TYPEREF;
798 	} else {
799 		scope = mono_reflection_resolution_scope_from_image (assembly, klass->image);
800 	}
801 	table = &assembly->tables [MONO_TABLE_TYPEREF];
802 	if (assembly->save) {
803 		alloc_table (table, table->rows + 1);
804 		values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
805 		values [MONO_TYPEREF_SCOPE] = scope;
806 		values [MONO_TYPEREF_NAME] = mono_dynstream_insert_string (&assembly->sheap, klass->name);
807 		values [MONO_TYPEREF_NAMESPACE] = mono_dynstream_insert_string (&assembly->sheap, klass->name_space);
808 	}
809 	token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
810 	g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
811 	table->next_idx ++;
812 
813 
814 	if (!MONO_HANDLE_IS_NULL (tb)) {
815 		/* This function is called multiple times from sre and sre-save, so same object is okay */
816 		mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
817 	}
818 
819 leave:
820 	HANDLE_FUNCTION_RETURN_VAL (token);
821 }
822 
823 /*
824  * Despite the name, we handle also TypeSpec (with the above helper).
825  */
826 static guint32
mono_image_typedef_or_ref(MonoDynamicImage * assembly,MonoType * type)827 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
828 {
829 	return mono_dynimage_encode_typedef_or_ref_full (assembly, type, TRUE);
830 }
831 
832 guint32
mono_dynimage_encode_generic_method_sig(MonoDynamicImage * assembly,MonoGenericContext * context)833 mono_dynimage_encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
834 {
835 	SigBuffer buf;
836 	int i;
837 	guint32 nparams = context->method_inst->type_argc;
838 	guint32 idx;
839 
840 	if (!assembly->save)
841 		return 0;
842 
843 	sigbuffer_init (&buf, 32);
844 	/*
845 	 * FIXME: vararg, explicit_this, differenc call_conv values...
846 	 */
847 	sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
848 	sigbuffer_add_value (&buf, nparams);
849 
850 	for (i = 0; i < nparams; i++)
851 		encode_type (assembly, context->method_inst->type_argv [i], &buf);
852 
853 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
854 	sigbuffer_free (&buf);
855 	return idx;
856 }
857 
858 #ifndef DISABLE_REFLECTION_EMIT
859 static gboolean
encode_sighelper_arg(MonoDynamicImage * assembly,int i,MonoArrayHandle helper_arguments,MonoArrayHandle helper_modreqs,MonoArrayHandle helper_modopts,SigBuffer * buf,MonoError * error)860 encode_sighelper_arg (MonoDynamicImage *assembly, int i, MonoArrayHandle helper_arguments, MonoArrayHandle helper_modreqs, MonoArrayHandle helper_modopts, SigBuffer* buf, MonoError *error)
861 {
862 	HANDLE_FUNCTION_ENTER();
863 	error_init (error);
864 	MonoArrayHandle modreqs = MONO_HANDLE_NEW (MonoArray, NULL);
865 	MonoArrayHandle modopts = MONO_HANDLE_NEW (MonoArray, NULL);
866 
867 	if (!MONO_HANDLE_IS_NULL (helper_modreqs) && (i < mono_array_handle_length (helper_modreqs)))
868 		MONO_HANDLE_ARRAY_GETREF (modreqs, helper_modreqs, i);
869 	if (!MONO_HANDLE_IS_NULL (helper_modopts) && (i < mono_array_handle_length (helper_modopts)))
870 		MONO_HANDLE_ARRAY_GETREF (modopts, helper_modopts, i);
871 
872 	encode_custom_modifiers (assembly, modreqs, modopts, buf, error);
873 	goto_if_nok (error, leave);
874 	MonoReflectionTypeHandle pt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
875 	MONO_HANDLE_ARRAY_GETREF (pt, helper_arguments, i);
876 	encode_reflection_type (assembly, pt, buf, error);
877 	goto_if_nok (error, leave);
878 leave:
879 	HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
880 }
881 
882 guint32
mono_dynimage_encode_reflection_sighelper(MonoDynamicImage * assembly,MonoReflectionSigHelperHandle helper,MonoError * error)883 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
884 {
885 	SigBuffer buf;
886 	guint32 nargs;
887 	guint32 i, idx;
888 
889 	error_init (error);
890 
891 	if (!assembly->save)
892 		return 0;
893 
894 	/* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
895 	g_assert (MONO_HANDLE_GETVAL (helper, type) == 2);
896 
897 	MonoArrayHandle arguments = MONO_HANDLE_NEW_GET (MonoArray, helper, arguments);
898 	if (!MONO_HANDLE_IS_NULL (arguments))
899 		nargs = mono_array_handle_length (arguments);
900 	else
901 		nargs = 0;
902 
903 	sigbuffer_init (&buf, 32);
904 
905 	/* Encode calling convention */
906 	/* Change Any to Standard */
907 	if ((MONO_HANDLE_GETVAL (helper, call_conv) & 0x03) == 0x03)
908 		MONO_HANDLE_SETVAL (helper, call_conv, guint32, 0x01);
909 	/* explicit_this implies has_this */
910 	if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x40)
911 		MONO_HANDLE_SETVAL (helper, call_conv, guint32, MONO_HANDLE_GETVAL (helper, call_conv) & 0x20);
912 
913 	if (MONO_HANDLE_GETVAL (helper, call_conv) == 0) { /* Unmanaged */
914 		idx = MONO_HANDLE_GETVAL (helper, unmanaged_call_conv) - 1;
915 	} else {
916 		/* Managed */
917 		idx = MONO_HANDLE_GETVAL (helper, call_conv) & 0x60; /* has_this + explicit_this */
918 		if (MONO_HANDLE_GETVAL (helper, call_conv) & 0x02) /* varargs */
919 			idx += 0x05;
920 	}
921 
922 	sigbuffer_add_byte (&buf, idx);
923 	sigbuffer_add_value (&buf, nargs);
924 	encode_reflection_type (assembly, MONO_HANDLE_NEW_GET (MonoReflectionType, helper, return_type), &buf, error);
925 	goto_if_nok (error, fail);
926 	MonoArrayHandle modreqs = MONO_HANDLE_NEW_GET (MonoArray, helper, modreqs);
927 	MonoArrayHandle modopts = MONO_HANDLE_NEW_GET (MonoArray, helper, modopts);
928 	for (i = 0; i < nargs; ++i) {
929 		if (!encode_sighelper_arg (assembly, i, arguments, modreqs, modopts, &buf, error))
930 			goto fail;
931 	}
932 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
933 	sigbuffer_free (&buf);
934 
935 	return idx;
936 fail:
937 	sigbuffer_free (&buf);
938 	return 0;
939 }
940 #else /* DISABLE_REFLECTION_EMIT */
941 guint32
mono_dynimage_encode_reflection_sighelper(MonoDynamicImage * assembly,MonoReflectionSigHelperHandle helper,MonoError * error)942 mono_dynimage_encode_reflection_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelperHandle helper, MonoError *error)
943 {
944 	g_assert_not_reached ();
945 	return 0;
946 }
947 #endif /* DISABLE_REFLECTION_EMIT */
948 
949 static gboolean
encode_reflection_types(MonoDynamicImage * assembly,MonoArrayHandle sig_arguments,int i,SigBuffer * buf,MonoError * error)950 encode_reflection_types (MonoDynamicImage *assembly, MonoArrayHandle sig_arguments, int i, SigBuffer *buf, MonoError *error)
951 {
952 	HANDLE_FUNCTION_ENTER ();
953 	error_init (error);
954 	MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL);
955 	MONO_HANDLE_ARRAY_GETREF (type, sig_arguments, i);
956 	encode_reflection_type (assembly, type, buf, error);
957 	HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
958 }
959 
960 static MonoArrayHandle
reflection_sighelper_get_signature_local(MonoReflectionSigHelperHandle sig,MonoError * error)961 reflection_sighelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
962 {
963 	MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
964 	MonoDynamicImage *assembly = MONO_HANDLE_IS_NULL (module) ? NULL : MONO_HANDLE_GETVAL (module, dynamic_image);
965 	MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
966 	guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
967 	guint32 buflen, i;
968 	SigBuffer buf;
969 
970 	error_init (error);
971 
972 	sigbuffer_init (&buf, 32);
973 
974 	sigbuffer_add_value (&buf, 0x07);
975 	sigbuffer_add_value (&buf, na);
976 	if (assembly != NULL){
977 		for (i = 0; i < na; ++i) {
978 			if (!encode_reflection_types (assembly, sig_arguments, i, &buf, error))
979 				goto fail;
980 		}
981 	}
982 
983 	buflen = buf.p - buf.buf;
984 	MonoArrayHandle result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
985 	goto_if_nok (error, fail);
986 	uint32_t gchandle;
987 	void *base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
988 	memcpy (base, buf.buf, buflen);
989 	sigbuffer_free (&buf);
990 	mono_gchandle_free (gchandle);
991 	return result;
992 fail:
993 	sigbuffer_free (&buf);
994 	return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
995 }
996 
997 static MonoArrayHandle
reflection_sighelper_get_signature_field(MonoReflectionSigHelperHandle sig,MonoError * error)998 reflection_sighelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
999 {
1000 	MonoReflectionModuleBuilderHandle module = MONO_HANDLE_NEW_GET (MonoReflectionModuleBuilder, sig, module);
1001 	MonoDynamicImage *assembly = MONO_HANDLE_GETVAL (module, dynamic_image);
1002 	MonoArrayHandle sig_arguments = MONO_HANDLE_NEW_GET (MonoArray, sig, arguments);
1003 	guint32 na = MONO_HANDLE_IS_NULL (sig_arguments) ? 0 : mono_array_handle_length (sig_arguments);
1004 	guint32 buflen, i;
1005 	SigBuffer buf;
1006 
1007 	error_init (error);
1008 
1009 	sigbuffer_init (&buf, 32);
1010 
1011 	sigbuffer_add_value (&buf, 0x06);
1012 	for (i = 0; i < na; ++i) {
1013 		if (! encode_reflection_types (assembly, sig_arguments, i, &buf, error))
1014 			goto fail;
1015 	}
1016 
1017 	buflen = buf.p - buf.buf;
1018 	MonoArrayHandle result = mono_array_new_handle (mono_domain_get (), mono_defaults.byte_class, buflen, error);
1019 	goto_if_nok (error, fail);
1020 	uint32_t gchandle;
1021 	void *base = MONO_ARRAY_HANDLE_PIN (result, char, 0, &gchandle);
1022 	memcpy (base, buf.buf, buflen);
1023 	sigbuffer_free (&buf);
1024 	mono_gchandle_free (gchandle);
1025 
1026 	return result;
1027 fail:
1028 	sigbuffer_free (&buf);
1029 	return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1030 }
1031 
1032 static char*
type_get_fully_qualified_name(MonoType * type)1033 type_get_fully_qualified_name (MonoType *type)
1034 {
1035 	MONO_REQ_GC_NEUTRAL_MODE;
1036 
1037 	return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
1038 }
1039 
1040 #ifndef DISABLE_REFLECTION_EMIT_SAVE
1041 guint32
mono_dynimage_save_encode_marshal_blob(MonoDynamicImage * assembly,MonoReflectionMarshal * minfo,MonoError * error)1042 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1043 {
1044 	MONO_REQ_GC_UNSAFE_MODE;
1045 
1046 	error_init (error);
1047 
1048 	char *str;
1049 	SigBuffer buf;
1050 	guint32 idx, len;
1051 
1052 	sigbuffer_init (&buf, 32);
1053 
1054 	sigbuffer_add_value (&buf, minfo->type);
1055 
1056 	switch (minfo->type) {
1057 	case MONO_NATIVE_BYVALTSTR:
1058 	case MONO_NATIVE_BYVALARRAY:
1059 		sigbuffer_add_value (&buf, minfo->count);
1060 		break;
1061 	case MONO_NATIVE_LPARRAY:
1062 		if (minfo->eltype || minfo->has_size) {
1063 			sigbuffer_add_value (&buf, minfo->eltype);
1064 			if (minfo->has_size) {
1065 				sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
1066 				sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
1067 
1068 				/* LAMESPEC: ElemMult is undocumented */
1069 				sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
1070 			}
1071 		}
1072 		break;
1073 	case MONO_NATIVE_SAFEARRAY:
1074 		if (minfo->eltype)
1075 			sigbuffer_add_value (&buf, minfo->eltype);
1076 		break;
1077 	case MONO_NATIVE_CUSTOM:
1078 		if (minfo->guid) {
1079 			str = mono_string_to_utf8_checked (minfo->guid, error);
1080 			if (!is_ok (error)) {
1081 				sigbuffer_free (&buf);
1082 				return 0;
1083 			}
1084 			len = strlen (str);
1085 			sigbuffer_add_value (&buf, len);
1086 			sigbuffer_add_mem (&buf, str, len);
1087 			g_free (str);
1088 		} else {
1089 			sigbuffer_add_value (&buf, 0);
1090 		}
1091 		/* native type name */
1092 		sigbuffer_add_value (&buf, 0);
1093 		/* custom marshaler type name */
1094 		if (minfo->marshaltype || minfo->marshaltyperef) {
1095 			if (minfo->marshaltyperef) {
1096 				MonoType *marshaltype = mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef, error);
1097 				if (!is_ok (error)) {
1098 					sigbuffer_free (&buf);
1099 					return 0;
1100 				}
1101 				str = type_get_fully_qualified_name (marshaltype);
1102 			} else {
1103 				str = mono_string_to_utf8_checked (minfo->marshaltype, error);
1104 				if (!is_ok (error)) {
1105 					sigbuffer_free (&buf);
1106 					return 0;
1107 				}
1108 			}
1109 			len = strlen (str);
1110 			sigbuffer_add_value (&buf, len);
1111 			sigbuffer_add_mem (&buf, str, len);
1112 			g_free (str);
1113 		} else {
1114 			/* FIXME: Actually a bug, since this field is required.  Punting for now ... */
1115 			sigbuffer_add_value (&buf, 0);
1116 		}
1117 		if (minfo->mcookie) {
1118 			str = mono_string_to_utf8_checked (minfo->mcookie, error);
1119 			if (!is_ok (error)) {
1120 				sigbuffer_free (&buf);
1121 				return 0;
1122 			}
1123 			len = strlen (str);
1124 			sigbuffer_add_value (&buf, len);
1125 			sigbuffer_add_mem (&buf, str, len);
1126 			g_free (str);
1127 		} else {
1128 			sigbuffer_add_value (&buf, 0);
1129 		}
1130 		break;
1131 	default:
1132 		break;
1133 	}
1134 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1135 	sigbuffer_free (&buf);
1136 	return idx;
1137 }
1138 
1139 guint32
mono_dynimage_save_encode_property_signature(MonoDynamicImage * assembly,MonoReflectionPropertyBuilder * fb,MonoError * error)1140 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1141 {
1142 	MONO_REQ_GC_UNSAFE_MODE;
1143 
1144 	error_init (error);
1145 
1146 	SigBuffer buf;
1147 	guint32 nparams = 0;
1148 	MonoReflectionMethodBuilder *mb = fb->get_method;
1149 	MonoReflectionMethodBuilder *smb = fb->set_method;
1150 	guint32 idx, i;
1151 
1152 	if (mb && mb->parameters)
1153 		nparams = mono_array_length (mb->parameters);
1154 	if (!mb && smb && smb->parameters)
1155 		nparams = mono_array_length (smb->parameters) - 1;
1156 	sigbuffer_init (&buf, 32);
1157 	if (fb->call_conv & 0x20)
1158 		sigbuffer_add_byte (&buf, 0x28);
1159 	else
1160 		sigbuffer_add_byte (&buf, 0x08);
1161 	sigbuffer_add_value (&buf, nparams);
1162 	if (mb) {
1163 		encode_reflection_type_raw (assembly, (MonoReflectionType*)mb->rtype, &buf, error);
1164 		if (!is_ok (error))
1165 			goto fail;
1166 		for (i = 0; i < nparams; ++i) {
1167 			MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
1168 			encode_reflection_type_raw (assembly, pt, &buf, error);
1169 			if (!is_ok (error))
1170 				goto fail;
1171 		}
1172 	} else if (smb && smb->parameters) {
1173 		/* the property type is the last param */
1174 		encode_reflection_type_raw (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf, error);
1175 		if (!is_ok (error))
1176 			goto fail;
1177 
1178 		for (i = 0; i < nparams; ++i) {
1179 			MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
1180 			encode_reflection_type_raw (assembly, pt, &buf, error);
1181 			if (!is_ok (error))
1182 				goto fail;
1183 		}
1184 	} else {
1185 		encode_reflection_type_raw (assembly, (MonoReflectionType*)fb->type, &buf, error);
1186 		if (!is_ok (error))
1187 			goto fail;
1188 	}
1189 
1190 	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
1191 	sigbuffer_free (&buf);
1192 	return idx;
1193 fail:
1194 	sigbuffer_free (&buf);
1195 	return 0;
1196 }
1197 
1198 
1199 #else /*DISABLE_REFLECTION_EMIT_SAVE*/
1200 guint32
mono_dynimage_save_encode_marshal_blob(MonoDynamicImage * assembly,MonoReflectionMarshal * minfo,MonoError * error)1201 mono_dynimage_save_encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo, MonoError *error)
1202 {
1203 	g_assert_not_reached ();
1204 	return 0;
1205 }
1206 
1207 guint32
mono_dynimage_save_encode_property_signature(MonoDynamicImage * assembly,MonoReflectionPropertyBuilder * fb,MonoError * error)1208 mono_dynimage_save_encode_property_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb, MonoError *error)
1209 {
1210 	g_assert_not_reached ();
1211 	return 0;
1212 }
1213 #endif /*DISABLE_REFLECTION_EMIT_SAVE*/
1214 
1215 #ifndef DISABLE_REFLECTION_EMIT
1216 MonoArrayHandle
ves_icall_SignatureHelper_get_signature_local(MonoReflectionSigHelperHandle sig,MonoError * error)1217 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
1218 {
1219 	error_init (error);
1220 	return reflection_sighelper_get_signature_local (sig, error);
1221 }
1222 
1223 MonoArrayHandle
ves_icall_SignatureHelper_get_signature_field(MonoReflectionSigHelperHandle sig,MonoError * error)1224 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1225 {
1226 	error_init (error);
1227 	return reflection_sighelper_get_signature_field (sig, error);
1228 }
1229 #else /* DISABLE_REFLECTION_EMIT */
1230 MonoArrayHandle
ves_icall_SignatureHelper_get_signature_local(MonoReflectionSigHelperHandle sig,MonoError * error)1231 ves_icall_SignatureHelper_get_signature_local (MonoReflectionSigHelperHandle sig, MonoError *error)
1232 {
1233 	error_init (error);
1234 	g_assert_not_reached ();
1235 	return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1236 }
1237 
1238 MonoArrayHandle
ves_icall_SignatureHelper_get_signature_field(MonoReflectionSigHelperHandle sig,MonoError * error)1239 ves_icall_SignatureHelper_get_signature_field (MonoReflectionSigHelperHandle sig, MonoError *error)
1240 {
1241 	error_init (error);
1242 	g_assert_not_reached ();
1243 	return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1244 }
1245 
1246 #endif /* DISABLE_REFLECTION_EMIT */
1247