Removed my table, and reuse the table that Jackson had put in place.
[mono.git] / mono / dis / main.c
index 52913d9c6ee1c72c2b3f8d8d696c37003df39dd3..08f1afa24462891a47597ba1ccd6862a21c4d954 100644 (file)
@@ -48,11 +48,10 @@ dump_header_data (MonoImage *img)
 }
 
 static void
-dump_cattrs (MonoImage *m, guint32 token, const char *indent)
+dump_cattrs_list (GList *list,  const char *indent)
 {
-       GList *tmp, *list;
+       GList *tmp;
 
-       list = dis_get_custom_attrs (m, token);
        for (tmp = list; tmp; tmp = tmp->next) {
                fprintf (output, "%s%s\n", indent, (char*)tmp->data);
                g_free (tmp->data);
@@ -60,6 +59,86 @@ dump_cattrs (MonoImage *m, guint32 token, const char *indent)
        g_list_free (list);
 }
 
+static void
+dump_cattrs (MonoImage *m, guint32 token, const char *indent)
+{
+       GList *list;
+
+       list = dis_get_custom_attrs (m, token);
+       dump_cattrs_list (list, indent);
+}
+
+static const char*
+get_il_security_action (int val) 
+{
+       static char buf [32];
+
+       switch (val) {
+       case SECURITY_ACTION_DEMAND:
+               return "demand";
+       case SECURITY_ACTION_ASSERT:
+               return "assert";
+       case SECURITY_ACTION_DENY:
+               return "deny";
+       case SECURITY_ACTION_PERMITONLY:
+               return "permitonly";
+       case SECURITY_ACTION_LINKDEMAND:
+               return "linkcheck";
+       case SECURITY_ACTION_INHERITDEMAND:
+               return "inheritcheck";
+       case SECURITY_ACTION_REQMIN:
+               return "reqmin";
+       case SECURITY_ACTION_REQOPT:
+               return "reqopt";
+       case SECURITY_ACTION_REQREFUSE:
+               return "reqrefuse";
+       /* Special actions (for non CAS permissions) */
+       case SECURITY_ACTION_NONCASDEMAND:
+               return "noncasdemand";
+       case SECURITY_ACTION_NONCASLINKDEMAND:
+               return "noncaslinkdemand";
+       case SECURITY_ACTION_NONCASINHERITANCE:
+               return "noncasinheritance";
+       /* Fx 2.0 actions (for both CAS and non-CAS permissions) */
+       case SECURITY_ACTION_LINKDEMANDCHOICE:
+               return "linkdemandor";
+       case SECURITY_ACTION_INHERITDEMANDCHOICE:
+               return "inheritancedemandor";
+       case SECURITY_ACTION_DEMANDCHOICE:
+               return "demandor";
+       default:
+               g_snprintf (buf, sizeof (buf), "0x%04X", val);
+               return buf;
+       }
+}
+
+#define OBJECT_TYPE_TYPEDEF    0
+#define OBJECT_TYPE_METHODDEF  1
+#define OBJECT_TYPE_ASSEMBLYDEF        2
+
+static void
+dump_declarative_security (MonoImage *m, guint32 objectType, guint32 token, const char *indent)
+{
+       MonoTableInfo *t = &m->tables [MONO_TABLE_DECLSECURITY];
+       guint32 cols [MONO_DECL_SECURITY_SIZE];
+       int i, len;
+       guint32 idx;
+       const char *blob, *action;
+       
+       for (i = 1; i <= t->rows; i++) {
+               mono_metadata_decode_row (t, i - 1, cols, MONO_DECL_SECURITY_SIZE);
+               blob = mono_metadata_blob_heap (m, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
+               len = mono_metadata_decode_blob_size (blob, &blob);
+               action = get_il_security_action (cols [MONO_DECL_SECURITY_ACTION]);
+               idx = cols [MONO_DECL_SECURITY_PARENT];
+               if (((idx & MONO_HAS_DECL_SECURITY_MASK) == objectType) && ((idx >> MONO_HAS_DECL_SECURITY_BITS) == token)) {
+                       char *dump = data_dump (blob, len, indent);
+                       fprintf (output, "%s.permissionset %s = %s", indent, action, dump);
+                       g_free (dump);
+               }
+       }
+}
+
 static void
 dis_directive_assembly (MonoImage *m)
 {
@@ -74,6 +153,7 @@ dis_directive_assembly (MonoImage *m)
        fprintf (output, ".assembly '%s'\n{\n",
                 mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]));
        dump_cattrs (m, MONO_TOKEN_ASSEMBLY | 1, "  ");
+       dump_declarative_security (m, OBJECT_TYPE_ASSEMBLYDEF, 1, "  ");
        fprintf (output,
                 "  .hash algorithm 0x%08x\n"
                 "  .ver  %d:%d:%d:%d\n",
@@ -103,17 +183,32 @@ dis_directive_assemblyref (MonoImage *m)
                return;
 
        for (i = 0; i < t->rows; i++){
+               char *esc;
+
                mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
 
+               esc = get_escaped_name (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
+               
                fprintf (output,
                         ".assembly extern %s\n"
                         "{\n"
-                        "  .ver %d:%d:%d:%d\n"
-                        "}\n",
-                        mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]),
+                        "  .ver %d:%d:%d:%d\n",
+                        esc,
                         cols [MONO_ASSEMBLYREF_MAJOR_VERSION], cols [MONO_ASSEMBLYREF_MINOR_VERSION], 
                         cols [MONO_ASSEMBLYREF_BUILD_NUMBER], cols [MONO_ASSEMBLYREF_REV_NUMBER]
                        );
+               if (cols [MONO_ASSEMBLYREF_CULTURE]){
+                       fprintf (output, "  .locale %s\n", mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_CULTURE]));
+               }
+               if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]){
+                       const char* b = mono_metadata_blob_heap (m, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
+                       int len = mono_metadata_decode_blob_size (b, &b);
+                       char *dump = data_dump (b, len, "\t\t");
+                       fprintf (output, "  .publickeytoken =%s", dump);
+                       g_free (dump);
+               }
+               fprintf (output, "}\n");
+               g_free (esc);
        }
 }
 
@@ -197,9 +292,9 @@ static dis_map_t visibility_map [] = {
        { TYPE_ATTRIBUTE_NESTED_PUBLIC,        "nested public " },
        { TYPE_ATTRIBUTE_NESTED_PRIVATE,       "nested private " },
        { TYPE_ATTRIBUTE_NESTED_FAMILY,        "nested family " },
-       { TYPE_ATTRIBUTE_NESTED_ASSEMBLY,      "nested assembly" },
-       { TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM, "nested famandassem" },
-       { TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM,  "nested famorassem" },
+       { TYPE_ATTRIBUTE_NESTED_ASSEMBLY,      "nested assembly " },
+       { TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM, "nested famandassem " },
+       { TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM,  "nested famorassem " },
        { 0, NULL }
 };
 
@@ -338,7 +433,8 @@ static dis_map_t method_flags_map [] = {
        { METHOD_ATTRIBUTE_SPECIAL_NAME,        "specialname " },
        { METHOD_ATTRIBUTE_RT_SPECIAL_NAME,     "rtspecialname " },
        { METHOD_ATTRIBUTE_UNMANAGED_EXPORT,    "export " },
-       { METHOD_ATTRIBUTE_HAS_SECURITY,        "hassecurity" },
+/* MS ilasm doesn't compile this statement - is must be added automagically when permissionset are present */
+/*     { METHOD_ATTRIBUTE_HAS_SECURITY,        "hassecurity" }, */
        { METHOD_ATTRIBUTE_REQUIRE_SEC_OBJECT,  "requiresecobj" },
        { METHOD_ATTRIBUTE_PINVOKE_IMPL,        "pinvokeimpl " }, 
        { 0, NULL }
@@ -368,6 +464,10 @@ method_flags (guint32 f)
 static dis_map_t pinvoke_flags_map [] = {
        { PINVOKE_ATTRIBUTE_NO_MANGLE ,            "nomangle " },
        { PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR,   "lasterr " },
+       { PINVOKE_ATTRIBUTE_BEST_FIT_ENABLED,      "bestfit:on" },
+       { PINVOKE_ATTRIBUTE_BEST_FIT_DISABLED,      "bestfit:off" },
+       { PINVOKE_ATTRIBUTE_THROW_ON_UNMAPPABLE_ENABLED, "charmaperror:on" },
+       { PINVOKE_ATTRIBUTE_THROW_ON_UNMAPPABLE_DISABLED, "charmaperror:off" },
        { 0, NULL }
 };
 
@@ -452,11 +552,38 @@ method_impl_flags (guint32 f)
 }
 
 static void
-dis_locals (MonoImage *m, MonoMethodHeader *mh) 
+dis_locals (MonoImage *m, MonoMethodHeader *mh, const char *ptr
 {
        int i;
 
-       fprintf(output, "\t.locals %s(\n", mh->init_locals ? "init " : "");
+       if (show_tokens) {
+               unsigned char flags = *(const unsigned char *) ptr;
+               unsigned char format = flags & METHOD_HEADER_FORMAT_MASK;
+               guint16 fat_flags;
+               guint32 local_var_sig_tok, max_stack, code_size, init_locals;
+               int hsize;
+
+               g_assert (format == METHOD_HEADER_FAT_FORMAT);
+               fat_flags = read16 (ptr);
+               ptr += 2;
+               hsize = (fat_flags >> 12) & 0xf;
+               max_stack = read16 (ptr);
+               ptr += 2;
+               code_size = read32 (ptr);
+               ptr += 4;
+               local_var_sig_tok = read32 (ptr);
+               ptr += 4;
+
+               if (fat_flags & METHOD_HEADER_INIT_LOCALS)
+                       init_locals = 1;
+               else
+                       init_locals = 0;
+
+               fprintf(output, "\t.locals /*%08x*/ %s(\n",
+                       local_var_sig_tok, init_locals ? "init " : "");
+       } else
+               fprintf(output, "\t.locals %s(\n", mh->init_locals ? "init " : "");
+
        for (i=0; i < mh->num_locals; ++i) {
                char * desc;
                if (i)
@@ -470,17 +597,23 @@ dis_locals (MonoImage *m, MonoMethodHeader *mh)
 }
 
 static void
-dis_code (MonoImage *m, guint32 rva)
+dis_code (MonoImage *m, guint32 token, guint32 rva)
 {
        MonoMethodHeader *mh;
-       MonoCLIImageInfo *ii = m->image_info;
-       const char *ptr = mono_cli_rva_map (ii, rva);
+       const char *ptr = mono_image_rva_map (m, rva);
        const char *loc;
+       gchar *override;
        guint32 entry_point;
 
        if (rva == 0)
                return;
 
+       override = get_method_override (m, token);
+       if (override) {
+               fprintf (output, "\t.override %s\n", override);
+               g_free (override);
+       }
+
        mh = mono_metadata_parse_mh (m, ptr);
        if ((entry_point = mono_image_get_entry_point (m))){
                loc = mono_metadata_locate_token (m, entry_point);
@@ -491,7 +624,7 @@ dis_code (MonoImage *m, guint32 rva)
        fprintf (output, "\t// Code size %d (0x%x)\n", mh->code_size, mh->code_size);
        fprintf (output, "\t.maxstack %d\n", mh->max_stack);
        if (mh->num_locals)
-               dis_locals (m, mh);
+               dis_locals (m, mh, ptr);
        dissasemble_cil (m, mh);
        
 /*
@@ -538,10 +671,10 @@ pinvoke_info (MonoImage *m, guint32 mindex)
 }
 
 static void
-cattrs_for_method (MonoImage *m, guint32 midx, MonoMethodSignature *sig) {
+dump_cattrs_for_method_params (MonoImage *m, guint32 midx, MonoMethodSignature *sig) {
        MonoTableInfo *methodt;
        MonoTableInfo *paramt;
-       guint param_index, lastp, i, pid;
+       guint param_index, lastp, i;
 
        methodt = &m->tables [MONO_TABLE_METHOD];
        paramt = &m->tables [MONO_TABLE_PARAM];
@@ -551,9 +684,32 @@ cattrs_for_method (MonoImage *m, guint32 midx, MonoMethodSignature *sig) {
        else
                lastp = paramt->rows + 1;
        for (i = param_index; i < lastp; ++i) {
-               pid = mono_metadata_decode_row_col (paramt, i - 1, MONO_PARAM_SEQUENCE);
-               fprintf (output, "\t.param [%d]\n", pid);
-               dump_cattrs (m, MONO_TOKEN_PARAM_DEF | i, "\t");
+               char *lit;
+               int crow;
+               guint32 param_cols [MONO_PARAM_SIZE];
+               GList *list;
+               
+               list = dis_get_custom_attrs (m, MONO_TOKEN_PARAM_DEF | i);
+
+               mono_metadata_decode_row (paramt, i-1, param_cols, MONO_PARAM_SIZE);
+               if (!(param_cols[MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
+                       if(list != NULL)
+                               fprintf (output, "\t.param [%d]\n", param_cols[MONO_PARAM_SEQUENCE]);
+               } else {
+                       fprintf (output, "\t.param [%d] = ", param_cols[MONO_PARAM_SEQUENCE]);
+                 
+                       if ((crow = mono_metadata_get_constant_index(m, MONO_TOKEN_PARAM_DEF | i, 0))) {
+                               guint32 const_cols [MONO_CONSTANT_SIZE];
+                               mono_metadata_decode_row( &m->tables[MONO_TABLE_CONSTANT], crow-1, const_cols, MONO_CONSTANT_SIZE);
+                               lit = get_constant(m, const_cols [MONO_CONSTANT_TYPE], const_cols [MONO_CONSTANT_VALUE]);
+                       }
+                       else {
+                               lit = g_strdup ("not found");
+                       }
+                 fprintf(output, "%s\n", lit);
+                 g_free(lit);
+               }
+               dump_cattrs_list (list, "\t");
        }
 }
 
@@ -583,6 +739,7 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en
                char *flags, *impl_flags;
                const char *sig;
                char *sig_str;
+               guint32 token;
                
                mono_metadata_decode_row (t, i, cols, MONO_METHOD_SIZE);
 
@@ -609,16 +766,19 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en
                fprintf (output, " %s\n", impl_flags);
                g_free (flags);
                g_free (impl_flags);
+
+               token = MONO_TOKEN_METHOD_DEF | (i + 1);
                
                fprintf (output, "    {\n");
-               dump_cattrs (m, MONO_TOKEN_METHOD_DEF | (i + 1), "        ");
-               cattrs_for_method (m, i, ms);
+               dump_cattrs (m, token, "        ");
+               dump_cattrs_for_method_params (m, i, ms);
                /* FIXME: need to sump also param custom attributes */
                fprintf (output, "        // Method begins at RVA 0x%x\n", cols [MONO_METHOD_RVA]);
+               dump_declarative_security (m, OBJECT_TYPE_METHODDEF, i + 1, "        ");
                if (cols [MONO_METHOD_IMPLFLAGS] & METHOD_IMPL_ATTRIBUTE_NATIVE)
                        fprintf (output, "          // Disassembly of native methods is not supported\n");
                else
-                       dis_code (m, cols [MONO_METHOD_RVA]);
+                       dis_code (m, token, cols [MONO_METHOD_RVA]);
                fprintf (output, "    } // end of method %s::%s\n\n", klass_name, sig_str);
                mono_metadata_free_method_signature (ms);
                g_free (sig_str);
@@ -670,7 +830,6 @@ dis_property_methods (MonoImage *m, guint32 prop)
                ++start;
        }
 }
-
 static char*
 dis_property_signature (MonoImage *m, guint32 prop_idx)
 {
@@ -680,7 +839,7 @@ dis_property_signature (MonoImage *m, guint32 prop_idx)
        guint32 cols [MONO_PROPERTY_SIZE];
        MonoType *type;
        MonoType *param;
-       char *blurb;
+       char *blurb, *qk;
        const char *name;
        int prop_flags;
        GString *res = g_string_new ("");
@@ -701,7 +860,9 @@ dis_property_signature (MonoImage *m, guint32 prop_idx)
                g_string_append (res, "specialname ");
        if (prop_flags & 0x0400)
                g_string_append (res, "rtspecialname ");
-       g_string_sprintfa (res, "%s %s (", blurb, name);
+       qk = get_escaped_name (name);
+       g_string_sprintfa (res, "%s %s (", blurb, qk);
+       g_free (qk);
        g_free (blurb);
        mono_metadata_free_type (type);
        for (i = 0; i < pcount; i++) {
@@ -889,9 +1050,9 @@ dis_generic_param_and_constraints (MonoImage *m, int table_type, guint32 typedef
                         continue;
 
                 if (found_count == 0)
-                        fprintf (output, "<%s", mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
+                        fprintf (output, "<");
                 else
-                        fprintf (output, ", %s", mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
+                        fprintf (output, ", ");
 
                 for (cnst_ind = cnst_start; cnst_ind < ct->rows; cnst_ind++) {
                         char *sig;
@@ -901,12 +1062,13 @@ dis_generic_param_and_constraints (MonoImage *m, int table_type, guint32 typedef
                         if (cnst_block == NULL)
                                 cnst_block = g_string_new ("");
                         sig = get_typedef_or_ref (m, ccols [MONO_GENPARCONSTRAINT_CONSTRAINT]);
-                        g_string_append_printf (cnst_block, "    .constraint !%d is %s\n",
-                                        cols [MONO_GENERICPARAM_NUMBER], sig);
+                       fprintf (output, "(%s) ", sig);
                         g_free (sig);
                         cnst_start = cnst_ind;
                 }
-                
+
+               fprintf (output, "%s", mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
+               
                 found_count++;
        }
 
@@ -960,8 +1122,13 @@ dis_type (MonoImage *m, int n)
                        fprintf (output, "  \textends %s\n", base);
                        g_free (base);
                }
-       } else
-               fprintf (output, "  .class interface %s%s\n", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), esname);
+       } else {
+               fprintf (output, "  .class interface %s%s", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), esname);
+
+                cnst_block = dis_generic_param_and_constraints (m, MONO_TYPEORMETHOD_TYPE, n+1);
+               fprintf (output, "\n");
+       }
+
        g_free (esname);
        dis_interfaces (m, n + 1);
        fprintf (output, "  {\n");
@@ -970,6 +1137,7 @@ dis_type (MonoImage *m, int n)
                 g_string_free (cnst_block, TRUE);
         }
        dump_cattrs (m, MONO_TOKEN_TYPE_DEF | (n + 1), "    ");
+       dump_declarative_security (m, OBJECT_TYPE_TYPEDEF, (n + 1), "    ");
 
        if (mono_metadata_packing_from_typedef (m, n + 1, &packing_size, &class_size)) {
                fprintf (output, "    .pack %d\n", packing_size);
@@ -1007,7 +1175,7 @@ dis_type (MonoImage *m, int n)
                nested = mono_metadata_nesting_typedef (m, n + 1, nested + 1);
        }
        
-       fprintf (output, "  } // end of type %s%s%s\n", nspace, *nspace? ".": "", name);
+       fprintf (output, "  } // end of class %s%s%s\n", nspace, *nspace? ".": "", name);
        if (*nspace)
                fprintf (output, "}\n");
        fprintf (output, "\n");
@@ -1105,7 +1273,7 @@ dis_data (MonoImage *m)
 
        for (i = 0; i < t->rows; i++) {
                mono_metadata_decode_row (t, i, cols, MONO_FIELD_RVA_SIZE);
-               rva = mono_cli_rva_map (m->image_info, cols [MONO_FIELD_RVA_RVA]);
+               rva = mono_image_rva_map (m, cols [MONO_FIELD_RVA_RVA]);
                sig = mono_metadata_blob_heap (m, mono_metadata_decode_row_col (ft, cols [MONO_FIELD_RVA_FIELD] -1, MONO_FIELD_SIGNATURE));
                mono_metadata_decode_value (sig, &sig);
                /* FIELD signature == 0x06 */
@@ -1158,8 +1326,9 @@ struct {
        { "--typeref",     MONO_TABLE_TYPEREF,          dump_table_typeref },
        { "--typespec",    MONO_TABLE_TYPESPEC,         dump_table_typespec },
        { "--implmap",     MONO_TABLE_IMPLMAP,          dump_table_implmap },
-       { "--blob",        NULL,                        dump_stream_blob },
-       { NULL, -1 }
+       { "--standalonesig", MONO_TABLE_STANDALONESIG,  dump_table_standalonesig },
+       { "--blob",        0,                   dump_stream_blob },
+       { NULL, -1, }
 };
 
 /**
@@ -1263,11 +1432,21 @@ main (int argc, char *argv [])
 
        if (input_files == NULL)
                usage ();
-       
-       mono_init (argv [0]);
 
-       for (l = input_files; l; l = l->next)
-               disassemble_file (l->data);
+       /*
+        * If we just have one file, use the corlib version it requires.
+        */
+       if (!input_files->next) {
+               char *filename = input_files->data;
+
+               mono_init_from_assembly (argv [0], filename);
+               disassemble_file (filename);
+       } else {
+               mono_init (argv [0]);
+
+               for (l = input_files; l; l = l->next)
+                       disassemble_file (l->data);
+       }
 
        return 0;
 }