2 * get.c: Functions to get stringified values from the metadata tables.
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc.
18 #include <mono/metadata/class.h>
20 extern gboolean substitute_with_mscorlib_p;
23 get_typedef (MonoImage *m, int idx)
25 guint32 cols [MONO_TYPEDEF_SIZE];
28 mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], idx - 1, cols, MONO_TYPEDEF_SIZE);
30 ns = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]);
31 return g_strdup_printf (
32 "%s%s%s", ns, *ns?".":"",
33 mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]));
37 get_module (MonoImage *m, int idx)
39 guint32 cols [MONO_MODULE_SIZE];
42 * There MUST BE only one module in the Module table
46 mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULE], idx - 1, cols, MONO_MODULE_SIZE);
48 return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]));
52 get_assemblyref (MonoImage *m, int idx)
54 guint32 cols [MONO_ASSEMBLYREF_SIZE];
56 mono_metadata_decode_row (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, cols, MONO_ASSEMBLYREF_SIZE);
58 return g_strdup (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
63 * Returns a string representing the ArrayShape (22.2.16).
66 get_array_shape (MonoImage *m, const char *ptr, char **result)
68 GString *res = g_string_new ("[");
69 guint32 rank, num_sizes, num_lo_bounds;
70 guint32 *sizes = NULL, *lo_bounds = NULL;
74 rank = mono_metadata_decode_value (ptr, &ptr);
75 num_sizes = mono_metadata_decode_value (ptr, &ptr);
78 sizes = g_new (guint32, num_sizes);
80 for (i = 0; i < num_sizes; i++)
81 sizes [i] = mono_metadata_decode_value (ptr, &ptr);
83 num_lo_bounds = mono_metadata_decode_value (ptr, &ptr);
84 if (num_lo_bounds > 0)
85 lo_bounds = g_new (guint32, num_lo_bounds);
87 for (i = 0; i < num_lo_bounds; i++)
88 lo_bounds [i] = mono_metadata_decode_value (ptr, &ptr);
90 for (r = 0; r < rank; r++){
92 if (r < num_lo_bounds){
93 sprintf (buffer, "%d..%d", lo_bounds [r], lo_bounds [r] + sizes [r] - 1);
95 sprintf (buffer, "0..%d", sizes [r] - 1);
100 g_string_append (res, buffer);
102 g_string_append (res, ", ");
104 g_string_append (res, "]");
113 g_string_free (res, FALSE);
120 * @m: metadata context
121 * @blob_idx: index into the blob heap
123 * Returns the stringified representation of a TypeSpec signature (22.2.17)
126 get_typespec (MonoImage *m, guint32 idx)
128 guint32 cols [MONO_TYPESPEC_SIZE];
131 GString *res = g_string_new ("");
134 mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPESPEC], idx-1, cols, MONO_TYPESPEC_SIZE);
135 ptr = mono_metadata_blob_heap (m, cols [MONO_TYPESPEC_SIGNATURE]);
136 len = mono_metadata_decode_value (ptr, &ptr);
140 ptr = get_custom_mod (m, ptr, &s);
142 g_string_append (res, s);
143 g_string_append_c (res, ' ');
147 if (*ptr == MONO_TYPE_VOID)
148 g_string_append (res, "void");
150 ptr = get_type (m, ptr, &s);
152 g_string_append (res, s);
156 case MONO_TYPE_FNPTR:
157 g_string_append (res, "FNPTR ");
159 * we assume MethodRefSig, as we do not know
160 * whether it is a MethodDefSig or a MethodRefSig.
162 printf ("\n FNPTR:\n");
164 hex_dump (ptr, 0, 40);
167 case MONO_TYPE_ARRAY:
168 ptr = get_type (m, ptr, &s);
169 g_string_append (res, s);
171 g_string_append_c (res, ' ');
172 ptr = get_array_shape (m, ptr, &s);
173 g_string_append (res, s);
177 case MONO_TYPE_SZARRAY:
178 ptr = get_custom_mod (m, ptr, &s);
180 g_string_append (res, s);
181 g_string_append_c (res, ' ');
184 ptr = get_type (m, ptr, &s);
185 g_string_append (res, s);
186 g_string_append (res, "[]");
191 g_string_free (res, FALSE);
197 get_typeref (MonoImage *m, int idx)
199 guint32 cols [MONO_TYPEREF_SIZE];
202 guint32 rs_idx, table;
204 mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEREF], idx - 1, cols, MONO_TYPEREF_SIZE);
206 t = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]);
207 s = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]);
209 rs_idx = cols [MONO_TYPEREF_SCOPE] >> RESOLTION_SCOPE_BITS;
210 table = cols [MONO_TYPEREF_SCOPE] & RESOLTION_SCOPE_MASK;
213 case RESOLTION_SCOPE_MODULE: /* Module */
214 x = get_module (m, rs_idx);
215 ret = g_strdup_printf ("[%s] %s%s%s", x, s, *s?".":"", t);
219 case RESOLTION_SCOPE_MODULEREF: /* ModuleRef */
220 ret = g_strdup_printf ("TODO:TypeRef-ModuleRef (%s.%s)", s, t);
223 case RESOLTION_SCOPE_ASSEMBLYREF: /*
224 * AssemblyRef (ECMA docs claim it is 3, but it looks to
225 * me like it is 2 (tokens are prefixed with 0x23)
227 x = get_assemblyref (m, rs_idx);
228 ret = g_strdup_printf ("[%s]%s%s%s", x, s, *s?".":"", t);
232 case RESOLTION_SCOPE_TYPEREF: /* TypeRef */
233 x = get_typeref (m, rs_idx);
234 ret = g_strdup_printf ("%s/%s", x, t);
239 ret = g_strdup_printf ("Unknown table in TypeRef %d", table);
246 * get_typedef_or_ref:
247 * @m: metadata context
248 * @dor_token: def or ref encoded index
250 * Low two bits contain table to lookup from
251 * high bits contain the index into the def or ref table
253 * Returns: a stringified version of the MethodDef or MethodRef
254 * at (dor_token >> 2)
257 get_typedef_or_ref (MonoImage *m, guint32 dor_token)
259 char *temp = NULL, *s;
263 * low 2 bits contain encoding
265 table = dor_token & 0x03;
266 idx = dor_token >> 2;
269 case 0: /* TypeDef */
270 temp = get_typedef (m, idx);
271 s = g_strdup_printf ("%s", temp);
274 case 1: /* TypeRef */
275 temp = get_typeref (m, idx);
276 s = g_strdup_printf ("%s", temp);
279 case 2: /* TypeSpec */
280 s = get_typespec (m, idx);
284 g_error ("Unhandled encoding for typedef-or-ref coded index");
295 * get_encoded_typedef_or_ref:
296 * @m: metadata context
297 * @ptr: location to decode from.
298 * @result: pointer to string where resulting decoded string is stored
300 * result will point to a g_malloc()ed string.
302 * Returns: the new ptr to continue decoding
305 get_encoded_typedef_or_ref (MonoImage *m, const char *ptr, char **result)
309 token = mono_metadata_decode_value (ptr, &ptr);
311 *result = get_typedef_or_ref (m, token);
319 * Decodes a CustomMod (22.2.7)
321 * Returns: updated pointer location
324 get_custom_mod (MonoImage *m, const char *ptr, char **return_value)
328 if ((*ptr == MONO_TYPE_CMOD_OPT) ||
329 (*ptr == MONO_TYPE_CMOD_REQD)){
331 ptr = get_encoded_typedef_or_ref (m, ptr, &s);
333 *return_value = g_strconcat ("CMOD ", s, NULL);
336 *return_value = NULL;
341 static map_t element_type_map [] = {
342 { MONO_TYPE_END , "end" },
343 { MONO_TYPE_VOID , "void" },
344 { MONO_TYPE_BOOLEAN , "bool" },
345 { MONO_TYPE_CHAR , "char" },
346 { MONO_TYPE_I1 , "int8" },
347 { MONO_TYPE_U1 , "unsigned int8" },
348 { MONO_TYPE_I2 , "int16" },
349 { MONO_TYPE_U2 , "uint16" },
350 { MONO_TYPE_I4 , "int32" },
351 { MONO_TYPE_U4 , "uint32" },
352 { MONO_TYPE_I8 , "int64" },
353 { MONO_TYPE_U8 , "uint64" },
354 { MONO_TYPE_R4 , "float32" },
355 { MONO_TYPE_R8 , "float64" },
356 { MONO_TYPE_STRING , "string" },
357 { MONO_TYPE_TYPEDBYREF , "TypedByRef" },
358 { MONO_TYPE_I , "native int" },
359 { MONO_TYPE_U , "native unsigned int" },
360 { MONO_TYPE_OBJECT , "object" },
364 static map_t call_conv_type_map [] = {
365 { MONO_CALL_DEFAULT , "default" },
366 { MONO_CALL_C , "c" },
367 { MONO_CALL_STDCALL , "stdcall" },
368 { MONO_CALL_THISCALL , "thiscall" },
369 { MONO_CALL_FASTCALL , "fastcall" },
370 { MONO_CALL_VARARG , "vararg" },
375 dis_stringify_token (MonoImage *m, guint32 token)
377 guint idx = token & 0xffffff;
378 switch (token >> 24) {
379 case MONO_TABLE_TYPEDEF: return get_typedef (m, idx);
380 case MONO_TABLE_TYPEREF: return get_typeref (m, idx);
381 case MONO_TABLE_TYPESPEC: return get_typespec (m, idx);
385 return g_strdup_printf("0x%08x", token);
389 dis_stringify_array (MonoImage *m, MonoArrayType *array)
392 GString *s = g_string_new("");
395 type = dis_stringify_type (m, array->type);
396 g_string_append (s, type);
398 g_string_append_c (s, '[');
399 for (i = 0; i < array->rank; ++i) {
401 g_string_append_c (s, ',');
402 if (i < array->numsizes) {
403 if (i < array->numlobounds && array->lobounds[i] != 0)
404 g_string_sprintfa (s, "%d..%d", array->lobounds[i], array->sizes[i]);
406 g_string_sprintfa (s, "%d", array->sizes[i]);
409 g_string_append_c (s, ']');
411 g_string_free (s, FALSE);
416 dis_stringify_modifiers (MonoImage *m, int n, MonoCustomMod *mod)
418 GString *s = g_string_new("");
421 for (i = 0; i < n; ++i) {
422 char *tok = dis_stringify_token (m, mod[i].token);
423 g_string_sprintfa (s, "%s %s", mod[i].required ? "opt": "reqd", tok);
426 g_string_append_c (s, ' ');
428 g_string_free (s, FALSE);
433 dis_stringify_param (MonoImage *m, MonoType *param)
437 const char *out = param->attrs & 2 ? "[out] ": "";
438 t = dis_stringify_type (m, param);
439 result = g_strconcat (out, t, NULL);
445 dis_stringify_method_signature (MonoImage *m, MonoMethodSignature *method, int methoddef_row)
447 guint32 cols [MONO_METHOD_SIZE];
448 guint32 pcols [MONO_PARAM_SIZE];
449 guint32 param_index = 0;
450 const char *name = "";
453 GString *result = g_string_new ("");
456 g_assert (method || methoddef_row);
459 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row -1, cols, MONO_METHOD_SIZE);
460 name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
461 param_index = cols [MONO_METHOD_PARAMLIST];
463 const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
464 mono_metadata_decode_blob_size (sig, &sig);
465 method = mono_metadata_parse_method_signature (m, 1, sig, &sig);
470 retval = dis_stringify_param (m, method->ret);
472 g_string_append (result, "instance ");
473 g_string_append (result, map (method->call_convention, call_conv_type_map));
474 g_string_sprintfa (result, " %s %s(", retval, name);
476 for (i = 0; i < method->param_count; ++i) {
477 if (param_index && param_index <= m->tables [MONO_TABLE_PARAM].rows) {
478 mono_metadata_decode_row (&m->tables [MONO_TABLE_PARAM], param_index - 1, pcols, MONO_PARAM_SIZE);
479 name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
480 method->params [i]->attrs = pcols [MONO_PARAM_FLAGS];
486 g_string_append (result, ", ");
487 retval = dis_stringify_param (m, method->params [i]);
488 g_string_sprintfa (result, "%s %s", retval, name);
491 g_string_append (result, ") ");
494 mono_metadata_free_method_signature (method);
495 retval = result->str;
496 g_string_free (result, FALSE);
502 dis_stringify_object (MonoImage *m, MonoType *type)
504 const char *otype = type->type == MONO_TYPE_CLASS? "class" : "valuetype";
505 char *assemblyref = NULL, *result;
506 MonoClass *c = type->data.klass;
508 return g_strdup ("Unknown");
511 if (substitute_with_mscorlib_p && !strcmp ("corlib", c->image->assembly_name))
512 assemblyref = g_strdup_printf ("[%s]", "mscorlib");
514 assemblyref = g_strdup_printf ("[%s]", c->image->assembly_name);
516 result = g_strdup_printf ("%s %s%s%s%s", otype, assemblyref?assemblyref:"", c->name_space,
517 *c->name_space?".":"", c->name);
518 g_free (assemblyref);
523 dis_stringify_type (MonoImage *m, MonoType *type)
525 const char *pinned = "", *byref = "";
526 char *bare = NULL, *mods = NULL;
530 mods = dis_stringify_modifiers (m, type->num_mods, type->modifiers);
533 case MONO_TYPE_BOOLEAN:
547 case MONO_TYPE_STRING:
548 case MONO_TYPE_OBJECT:
549 case MONO_TYPE_TYPEDBYREF:
550 bare = g_strdup (map (type->type, element_type_map));
553 case MONO_TYPE_VALUETYPE:
554 case MONO_TYPE_CLASS:
555 bare = dis_stringify_object (m, type);
558 case MONO_TYPE_FNPTR:
559 bare = dis_stringify_method_signature (m, type->data.method, 0);
562 case MONO_TYPE_SZARRAY: {
564 child_type = dis_stringify_type (m, type->data.type);
566 bare = g_strdup_printf (type->type == MONO_TYPE_PTR ? "%s*" : "%s[]", child_type);
570 case MONO_TYPE_ARRAY:
571 bare = dis_stringify_array (m, type->data.array);
574 bare = g_strdup ("void");
577 g_error ("Do not know how to stringify type 0x%x", type->type);
586 result = g_strconcat (mods ? mods : "", bare, byref, pinned, NULL);
595 * @m: metadata context
596 * @ptr: location to decode from.
597 * @result: pointer to string where resulting decoded string is stored
599 * This routine returs in @result the stringified type pointed by @ptr.
602 * Returns: the new ptr to continue decoding
605 get_type (MonoImage *m, const char *ptr, char **result)
607 MonoType *type = mono_metadata_parse_type (m, MONO_PARSE_TYPE, 0, ptr, &ptr);
608 *result = dis_stringify_type (m, type);
609 mono_metadata_free_type (type);
615 * Returns a stringified representation of a FieldSig (22.2.4)
618 get_field_signature (MonoImage *m, guint32 blob_signature)
620 char *allocated_modifier_string, *allocated_type_string;
621 const char *ptr = mono_metadata_blob_heap (m, blob_signature);
626 len = mono_metadata_decode_value (ptr, &ptr);
629 g_assert (*ptr == 0x06);
630 /* hex_dump (ptr, 0, len); */
633 ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
634 ptr = get_type (m, ptr, &allocated_type_string);
636 res = g_strdup_printf (
638 allocated_modifier_string ? allocated_modifier_string : "",
639 allocated_type_string);
641 if (allocated_modifier_string)
642 g_free (allocated_modifier_string);
643 if (allocated_type_string)
644 g_free (allocated_modifier_string);
650 get_field_literal_type (MonoImage *m, guint32 blob_signature)
652 const char *ptr = mono_metadata_blob_heap (m, blob_signature);
654 char *allocated_modifier_string;
656 len = mono_metadata_decode_value (ptr, &ptr);
659 g_assert (*ptr == 0x06);
662 ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
663 if (allocated_modifier_string)
664 g_free (allocated_modifier_string);
666 return (MonoTypeEnum) *ptr;
672 * @m: metadata context
673 * @token: token to decode
675 * decodes the literal indexed by @token.
678 decode_literal (MonoImage *m, guint32 token)
680 return g_strdup ("LITERAL_VALUE");
685 * @m: metadata context
686 * @ptr: location to decode from.
687 * @result: pointer to string where resulting decoded string is stored
689 * This routine returns in @result the stringified RetType (22.2.11)
691 * Returns: the new ptr to continue decoding.
694 get_ret_type (MonoImage *m, const char *ptr, char **ret_type)
696 GString *str = g_string_new ("");
698 char *allocated_type_string;
700 ptr = get_custom_mod (m, ptr, &mod);
702 g_string_append (str, mod);
703 g_string_append_c (str, ' ');
707 if (*ptr == MONO_TYPE_TYPEDBYREF){
708 /* TODO: what does `typedbyref' mean? */
709 g_string_append (str, "/* FIXME: What does this mean? */ typedbyref ");
711 } else if (*ptr == MONO_TYPE_VOID){
712 g_string_append (str, "void");
715 if (*ptr == MONO_TYPE_BYREF){
716 g_string_append (str, "[out] ");
720 ptr = get_type (m, ptr, &allocated_type_string);
721 g_string_append (str, allocated_type_string);
722 g_free (allocated_type_string);
725 *ret_type = str->str;
726 g_string_free (str, FALSE);
733 * @m: metadata context
734 * @ptr: location to decode from.
735 * @result: pointer to string where resulting decoded string is stored
737 * This routine returns in @result the stringified Param (22.2.10)
739 * Returns: the new ptr to continue decoding.
742 get_param (MonoImage *m, const char *ptr, char **retval)
744 GString *str = g_string_new ("");
745 char *allocated_mod_string, *allocated_type_string;
747 ptr = get_custom_mod (m, ptr, &allocated_mod_string);
748 if (allocated_mod_string){
749 g_string_append (str, allocated_mod_string);
750 g_string_append_c (str, ' ');
751 g_free (allocated_mod_string);
754 if (*ptr == MONO_TYPE_TYPEDBYREF){
755 g_string_append (str, "/*FIXME: what does typedbyref mean? */ typedbyref ");
758 if (*ptr == MONO_TYPE_BYREF){
759 g_string_append (str, "[out] ");
762 ptr = get_type (m, ptr, &allocated_type_string);
763 g_string_append (str, allocated_type_string);
764 g_free (allocated_type_string);
768 g_string_free (str, FALSE);
772 static map_t param_map [] = {
773 { PARAM_ATTRIBUTE_IN, "[in] " },
774 { PARAM_ATTRIBUTE_OUT, "[out] " },
775 { PARAM_ATTRIBUTE_OPTIONAL, "optional " },
776 { PARAM_ATTRIBUTE_HAS_DEFAULT, "hasdefault " },
777 { PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL, "fieldmarshal " },
782 param_flags (guint32 f)
784 return g_strdup (flags (f, param_map));
787 static map_t field_access_map [] = {
788 { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
789 { FIELD_ATTRIBUTE_PRIVATE, "private " },
790 { FIELD_ATTRIBUTE_FAM_AND_ASSEM, "famandassem " },
791 { FIELD_ATTRIBUTE_ASSEMBLY, "assembly " },
792 { FIELD_ATTRIBUTE_FAMILY, "family " },
793 { FIELD_ATTRIBUTE_FAM_OR_ASSEM, "famorassem " },
794 { FIELD_ATTRIBUTE_PUBLIC, "public " },
798 static map_t field_flags_map [] = {
799 { FIELD_ATTRIBUTE_STATIC, "static " },
800 { FIELD_ATTRIBUTE_INIT_ONLY, "initonly " },
801 { FIELD_ATTRIBUTE_LITERAL, "literal " },
802 { FIELD_ATTRIBUTE_NOT_SERIALIZED, "notserialized " },
803 { FIELD_ATTRIBUTE_SPECIAL_NAME, "specialname " },
804 { FIELD_ATTRIBUTE_PINVOKE_IMPL, "FIXME:pinvokeimpl " },
805 { FIELD_ATTRIBUTE_RT_SPECIAL_NAME, "rtspecialname " },
806 { FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL, "hasfieldmarshal " },
807 { FIELD_ATTRIBUTE_HAS_DEFAULT, "hasdefault " },
808 { FIELD_ATTRIBUTE_HAS_FIELD_RVA, "hasfieldrva " },
815 * Returns a stringified version of a Field's flags
818 field_flags (guint32 f)
821 int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
825 strcat (buffer, map (access, field_access_map));
826 strcat (buffer, flags (f, field_flags_map));
827 return g_strdup (buffer);
831 * Returns a stringifed representation of a MethodRefSig (22.2.2)
834 get_methodref_signature (MonoImage *m, guint32 blob_signature, const char *fancy_name)
836 GString *res = g_string_new ("");
837 const char *ptr = mono_metadata_blob_heap (m, blob_signature);
838 char *allocated_ret_type, *s;
839 gboolean seen_vararg = 0;
840 int param_count, signature_len;
843 signature_len = mono_metadata_decode_value (ptr, &ptr);
847 g_string_append (res, "explicit-this ");
849 g_string_append (res, "instance "); /* has-this */
856 param_count = mono_metadata_decode_value (ptr, &ptr);
857 ptr = get_ret_type (m, ptr, &allocated_ret_type);
859 g_string_append (res, allocated_ret_type);
862 g_string_append_c (res, ' ');
863 g_string_append (res, fancy_name);
866 g_string_append (res, "(");
869 * param_count describes parameters *before* and *after*
870 * the vararg sentinel
872 for (i = 0; i < param_count; i++){
876 * If ptr is a SENTINEL
879 g_string_append (res, " varargs ");
883 ptr = get_param (m, ptr, ¶m);
884 g_string_append (res, param);
885 if (i+1 != param_count)
886 g_string_append (res, ", ");
889 g_string_append (res, ")");
894 g_free (allocated_ret_type);
896 g_string_free (res, FALSE);
902 * @m: metadata context
903 * @token: a FIELD_DEF token
905 * This routine has to locate the TypeDef that "owns" this Field.
906 * Since there is no backpointer in the Field table, we have to scan
907 * the TypeDef table and locate the actual "owner" of the field
910 get_field (MonoImage *m, guint32 token)
912 int idx = mono_metadata_token_index (token);
913 guint32 cols [MONO_FIELD_SIZE];
914 char *sig, *res, *type;
918 * We can get here also with a MenberRef token (for a field
919 * defined in another module/assembly, just like in get_method ()
921 if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) {
922 return g_strdup_printf ("fieldref-0x%08x", token);
924 g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF);
926 mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE);
927 sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
930 * To locate the actual "container" for this field, we have to scan
931 * the TypeDef table. LAME!
933 type_idx = mono_metadata_typedef_from_field (m, idx);
935 type = get_typedef (m, type_idx);
936 res = g_strdup_printf ("%s %s::%s",
938 mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
946 get_memberref_parent (MonoImage *m, guint32 mrp_token)
949 * mrp_index is a MemberRefParent coded index
951 guint32 table = mrp_token & 7;
952 guint32 idx = mrp_token >> 3;
955 case 0: /* TypeDef */
956 return get_typedef (m, idx);
958 case 1: /* TypeRef */
959 return get_typeref (m, idx);
961 case 2: /* ModuleRef */
962 return g_strdup_printf ("TODO:MemberRefParent-ModuleRef");
964 case 3: /* MethodDef */
965 return g_strdup ("TODO:MethodDef");
967 case 4: /* TypeSpec */
968 return get_typespec (m, idx);
970 g_assert_not_reached ();
976 * @m: metadata context
977 * @token: a METHOD_DEF or MEMBER_REF token
979 * This routine has to locate the TypeDef that "owns" this Field.
980 * Since there is no backpointer in the Field table, we have to scan
981 * the TypeDef table and locate the actual "owner" of the field
984 get_method (MonoImage *m, guint32 token)
986 int idx = mono_metadata_token_index (token);
987 guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
993 mh = mono_get_method (m, token, NULL);
995 name = g_strdup_printf ("%s%s%s::%s", mh->klass->name_space, *(mh->klass->name_space)?".":"",
996 mh->klass->name, mh->name);
1000 switch (mono_metadata_token_code (token)){
1001 case MONO_TOKEN_METHOD_DEF:
1002 mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD],
1003 idx - 1, method_cols, MONO_METHOD_SIZE);
1005 sig = get_methodref_signature (m, method_cols [MONO_METHOD_SIGNATURE], name);
1008 case MONO_TOKEN_MEMBER_REF: {
1010 mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
1011 idx - 1, member_cols, MONO_MEMBERREF_SIZE);
1013 name = g_strdup_printf ("%s::%s",
1014 get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS]),
1015 mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME]));
1016 sig = get_methodref_signature (
1017 m, member_cols [MONO_MEMBERREF_SIGNATURE], name);
1022 g_assert_not_reached ();
1024 g_assert_not_reached ();
1030 * @m: metadata context
1031 * @blob_index: index into the blob where the constant is stored
1033 * Returns: An allocated value representing a stringified version of the
1037 get_constant (MonoImage *m, MonoTypeEnum t, guint32 blob_index)
1039 const char *ptr = mono_metadata_blob_heap (m, blob_index);
1042 len = mono_metadata_decode_value (ptr, &ptr);
1045 case MONO_TYPE_BOOLEAN:
1046 return g_strdup_printf ("%s", *ptr ? "true" : "false");
1048 case MONO_TYPE_CHAR:
1049 return g_strdup_printf ("%c", *ptr); /* FIXME: unicode char */
1053 return g_strdup_printf ("int8(0x%02x)", (int) (*ptr));
1058 return g_strdup_printf ("int16(0x%08x)", (int) read16 (ptr));
1062 return g_strdup_printf ("int32(%d)", read32 (ptr));
1064 case MONO_TYPE_I8: {
1067 high = read32 (ptr + 4);
1068 return g_strdup_printf ("0x%08x%08x", high, low);
1070 case MONO_TYPE_U8: {
1073 high = read32 (ptr + 4);
1074 return g_strdup_printf ("0x%08x%08x", high, low);
1076 case MONO_TYPE_R4: {
1079 return g_strdup_printf ("%g", (double) r);
1081 case MONO_TYPE_R8: {
1084 return g_strdup_printf ("%g", r);
1086 case MONO_TYPE_STRING: {
1090 for (i = 0; !ptr [i+1]; i += 2){
1095 case '\n': /* add more */
1099 res = g_malloc (len + e + 3);
1103 for (i = 0; i < len; i += 2){
1116 res[j++] = isprint (ptr [i]) ? ptr [i] : '.';
1125 case MONO_TYPE_CLASS:
1126 return g_strdup ("CLASS CONSTANT. MUST BE ZERO");
1129 g_error ("Unknown MONO_TYPE (%d) on constant at Blob index (0x%08x)\n",
1130 (int) *ptr, blob_index);
1131 return g_strdup_printf ("Unknown");
1138 * @m: metadata context
1139 * @token: token that we want to decode.
1141 * Returns: An allocated value representing a stringified version of the
1145 get_token (MonoImage *m, guint32 token)
1147 guint32 idx = mono_metadata_token_index (token);
1149 switch (mono_metadata_token_code (token)){
1150 case MONO_TOKEN_FIELD_DEF:
1151 return (get_field (m, token));
1152 case MONO_TOKEN_TYPE_DEF:
1153 return get_typedef (m, idx);
1154 case MONO_TOKEN_TYPE_REF:
1155 return get_typeref (m, idx);
1156 case MONO_TOKEN_TYPE_SPEC:
1157 return get_typespec (m, idx);
1159 g_error ("Do not know how to decode tokens of type 0x%08x", token);
1162 g_assert_not_reached ();
1163 return g_strdup ("ERROR");
1168 * @m: metadata context
1169 * @token: the token can belong to any of the following tables:
1170 * MONO_TOKEN_TYPE_REF, MONO_TOKEN_TYPE_DEF, MONO_TOKEN_TYPE_SPEC
1172 * Returns: a stringified version of the MethodDef or MethodRef or TypeSpecn
1173 * at (token & 0xffffff)
1176 get_token_type (MonoImage *m, guint32 token)
1178 char *temp = NULL, *s;
1181 idx = mono_metadata_token_index (token);
1183 switch (mono_metadata_token_code (token)){
1184 case MONO_TOKEN_TYPE_DEF:
1185 temp = get_typedef (m, idx);
1186 s = g_strdup_printf ("%s", temp);
1189 case MONO_TOKEN_TYPE_REF:
1190 temp = get_typeref (m, idx);
1191 s = g_strdup_printf ("%s", temp);
1194 case MONO_TOKEN_TYPE_SPEC:
1195 s = get_typespec (m, idx);
1199 g_error ("Unhandled encoding for typedef-or-ref coded index");
1210 get_guid (MonoImage *m, guint32 guid_index)
1212 const unsigned char *guid;
1215 guid = mono_metadata_guid_heap (m, guid_index);
1217 result = g_strdup_printf ("{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
1218 guid [3], guid [2], guid [1], guid [0], guid [5], guid [4], guid [7], guid [6],
1219 guid [8], guid [9], guid [10], guid [11], guid [12], guid [13], guid [14], guid [15]);
1224 dis_get_custom_attrs (MonoImage *m, guint32 token)
1227 guint32 idx, i, j, len, mtoken;
1228 guint32 cols [MONO_CUSTOM_ATTR_SIZE];
1234 idx = mono_metadata_token_index (token);
1235 idx <<= CUSTOM_ATTR_BITS;
1237 switch (mono_metadata_token_table (token)) {
1238 case MONO_TABLE_TYPEDEF:
1239 idx |= CUSTOM_ATTR_TYPEDEF;
1241 case MONO_TABLE_ASSEMBLY:
1242 idx |= CUSTOM_ATTR_ASSEMBLY;
1244 case MONO_TABLE_PROPERTY:
1245 idx |= CUSTOM_ATTR_PROPERTY;
1247 case MONO_TABLE_EVENT:
1248 idx |= CUSTOM_ATTR_EVENT;
1250 case MONO_TABLE_FIELD:
1251 idx |= CUSTOM_ATTR_FIELDDEF;
1253 case MONO_TABLE_METHOD:
1254 idx |= CUSTOM_ATTR_METHODDEF;
1256 case MONO_TABLE_PARAM:
1257 idx |= CUSTOM_ATTR_PARAMDEF;
1260 g_print ("Missing custom attr get support for token 0x%08x\n", token);
1264 ca = &m->tables [MONO_TABLE_CUSTOMATTRIBUTE];
1265 /* the table is not sorted */
1266 for (i = 0; i < ca->rows; ++i) {
1267 mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
1268 if (cols [MONO_CUSTOM_ATTR_PARENT] != idx)
1270 mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS;
1271 switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) {
1272 case CUSTOM_ATTR_TYPE_METHODDEF:
1273 mtoken |= MONO_TOKEN_METHOD_DEF;
1275 case CUSTOM_ATTR_TYPE_MEMBERREF:
1276 mtoken |= MONO_TOKEN_MEMBER_REF;
1279 g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
1282 method = get_method (m, mtoken);
1283 val = mono_metadata_blob_heap (m, cols [MONO_CUSTOM_ATTR_VALUE]);
1284 len = mono_metadata_decode_value (val, &val);
1285 attr = g_string_new (".custom ");
1286 g_string_sprintfa (attr, "%s = (", method);
1287 for (j = 0; j < len; ++j) {
1288 if (len > 4 && !(j % 16))
1289 g_string_append (attr, "\n\t\t");
1290 g_string_sprintfa (attr, " %02X", (val [j] & 0xff));
1292 g_string_append_c (attr, ')');
1293 list = g_list_append (list, attr->str);
1294 g_string_free (attr, FALSE);