2003-08-22 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / dis / main.c
index 01091fb601f92cd8354fea275d185ef400075187..d7aab1873752deb52015b0e573486589c78ee461 100644 (file)
@@ -243,8 +243,8 @@ dis_field_list (MonoImage *m, guint32 start, guint32 end)
 
 static map_t method_access_map [] = {
        { METHOD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
-       { METHOD_ATTRIBUTE_PRIVATE,             "private" },
-       { METHOD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem" },
+       { METHOD_ATTRIBUTE_PRIVATE,             "private " },
+       { METHOD_ATTRIBUTE_FAM_AND_ASSEM,       "famandassem " },
        { METHOD_ATTRIBUTE_ASSEM,               "assembly " },
        { METHOD_ATTRIBUTE_FAMILY,              "family " },
        { METHOD_ATTRIBUTE_FAM_OR_ASSEM,        "famorassem " },
@@ -461,6 +461,26 @@ pinvoke_info (MonoImage *m, guint32 mindex)
        return NULL;
 }
 
+static void
+cattrs_for_method (MonoImage *m, guint32 midx, MonoMethodSignature *sig) {
+       MonoTableInfo *methodt;
+       MonoTableInfo *paramt;
+       guint param_index, lastp, i, pid;
+
+       methodt = &m->tables [MONO_TABLE_METHOD];
+       paramt = &m->tables [MONO_TABLE_PARAM];
+       param_index = mono_metadata_decode_row_col (methodt, midx, MONO_METHOD_PARAMLIST);
+       if (midx + 1 < methodt->rows)
+               lastp = mono_metadata_decode_row_col (methodt, midx + 1, MONO_METHOD_PARAMLIST);
+       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");
+       }
+}
+
 /**
  * dis_method_list:
  * @m: metadata context
@@ -470,7 +490,7 @@ pinvoke_info (MonoImage *m, guint32 mindex)
  * This routine displays the methods in the Method Table from @start to @end
  */
 static void
-dis_method_list (MonoImage *m, guint32 start, guint32 end)
+dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 end)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_METHOD];
        guint32 cols [MONO_METHOD_SIZE];
@@ -496,8 +516,8 @@ dis_method_list (MonoImage *m, guint32 start, guint32 end)
                sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
                mono_metadata_decode_blob_size (sig, &sig);
                ms = mono_metadata_parse_method_signature (m, i + 1, sig, &sig);
-               sig_str = dis_stringify_method_signature (m, ms, i + 1);
-                       
+               sig_str = dis_stringify_method_signature (m, ms, i + 1, FALSE);
+
                fprintf (output, "    // method line %d\n", i + 1);
                fprintf (output, "    .method %s", flags);
 
@@ -511,10 +531,11 @@ dis_method_list (MonoImage *m, guint32 start, guint32 end)
                
                fprintf (output, "    {\n");
                dump_cattrs (m, MONO_TOKEN_METHOD_DEF | (i + 1), "        ");
+               cattrs_for_method (m, i, ms);
                /* FIXME: need to sump also param custom attributes */
                fprintf (output, "        // Method begins at RVA 0x%x\n", cols [MONO_METHOD_RVA]);
                dis_code (m, cols [MONO_METHOD_RVA]);
-               fprintf (output, "    } // end of method %s\n\n", sig_str);
+               fprintf (output, "    } // end of method %s::%s\n\n", klass_name, sig_str);
                mono_metadata_free_method_signature (ms);
                g_free (sig_str);
        }
@@ -559,7 +580,7 @@ dis_property_methods (MonoImage *m, guint32 prop)
        start = mono_metadata_methods_from_property (m, prop, &end);
        while (start < end) {
                mono_metadata_decode_row (msemt, start, cols, MONO_METHOD_SEMA_SIZE);
-               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD]);
+               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD], TRUE);
                fprintf (output, "\t\t%s %s\n", type [cols [MONO_METHOD_SEMA_SEMANTICS]], sig);
                g_free (sig);
                ++start;
@@ -662,7 +683,7 @@ dis_event_methods (MonoImage *m, guint32 event)
        start = mono_metadata_methods_from_event (m, event, &end);
        while (start < end) {
                mono_metadata_decode_row (msemt, start, cols, MONO_METHOD_SEMA_SIZE);
-               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD]);
+               sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD], FALSE);
                switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
                case METHOD_SEMANTIC_OTHER:
                        type = ".other"; break;
@@ -702,6 +723,7 @@ dis_interfaces (MonoImage *m, guint32 typedef_row)
 {
        plocator_t loc;
        guint start;
+       gboolean first_interface = 1;
        guint32 cols [MONO_INTERFACEIMPL_SIZE];
        char *intf;
        MonoTableInfo *table = &m->tables [MONO_TABLE_INTERFACEIMPL];
@@ -731,12 +753,46 @@ dis_interfaces (MonoImage *m, guint32 typedef_row)
                if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx)
                        break;
                intf = get_typedef_or_ref (m, cols [MONO_INTERFACEIMPL_INTERFACE]);
-               fprintf (output, "  \timplements %s\n", intf);
+               if (first_interface) {
+                       fprintf (output, "  \timplements %s", intf);
+                       first_interface = 0;
+               } else {
+                       fprintf (output, ", %s", intf);
+               }
                g_free (intf);
                ++start;
        }
 }
 
+static void
+dis_genericparam (MonoImage *m, guint32 typedef_row)
+{
+        MonoTableInfo *t = &m->tables [MONO_TABLE_GENERICPARAM];
+       guint32 cols [MONO_GENERICPARAM_SIZE];
+       int i, own_tok, table, idx, found_count;
+        
+        found_count = 0;
+       for (i = 1; i <= t->rows; i++) {
+               mono_metadata_decode_row (t, i - 1, cols, MONO_GENERICPARAM_SIZE);
+                own_tok = cols [MONO_GENERICPARAM_OWNER];
+                table = own_tok & 0x03;
+                idx = own_tok >> 2;
+                
+                if (table != 0 || idx != typedef_row)
+                        continue;
+
+                if (found_count == 0)
+                        fprintf (output, "<%s", mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
+                else
+                        fprintf (output, ", %s", mono_metadata_string_heap (m, cols [MONO_GENERICPARAM_NAME]));
+
+                found_count++;
+       }
+
+        if (found_count)
+                fprintf (output, ">");
+}
+
 /**
  * dis_type:
  * @m: metadata context
@@ -753,6 +809,7 @@ dis_type (MonoImage *m, int n)
        const char *name, *nspace;
        guint32 packing_size, class_size;
        gboolean next_is_valid, last;
+       guint32 nested;
        
        mono_metadata_decode_row (t, n, cols, MONO_TYPEDEF_SIZE);
 
@@ -768,7 +825,9 @@ dis_type (MonoImage *m, int n)
        name = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]);
 
        if ((cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK) == TYPE_ATTRIBUTE_CLASS){
-               fprintf (output, "  .class %s%s\n", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), name);
+               fprintf (output, "  .class %s%s", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), name);
+                dis_genericparam (m, n + 1);
+                fprintf (output, "\n");
                if (cols [MONO_TYPEDEF_EXTENDS]) {
                        char *base = get_typedef_or_ref (m, cols [MONO_TYPEDEF_EXTENDS]);
                        fprintf (output, "  \textends %s\n", base);
@@ -805,11 +864,18 @@ dis_type (MonoImage *m, int n)
                last = m->tables [MONO_TABLE_METHOD].rows;
        
        if (cols [MONO_TYPEDEF_METHOD_LIST] && cols [MONO_TYPEDEF_METHOD_LIST] <= m->tables [MONO_TABLE_METHOD].rows)
-               dis_method_list (m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last);
+               dis_method_list (name, m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last);
 
        dis_property_list (m, n);
        dis_event_list (m, n);
 
+       t = &m->tables [MONO_TABLE_NESTEDCLASS];
+       nested = mono_metadata_nesting_typedef (m, n + 1, 1);
+       while (nested) {
+               dis_type (m, mono_metadata_decode_row_col (t, nested - 1, MONO_NESTED_CLASS_NESTED) - 1);
+               nested = mono_metadata_nesting_typedef (m, n + 1, nested + 1);
+       }
+       
        fprintf (output, "  } // end of type %s%s%s\n", nspace, *nspace? ".": "", name);
        if (*nspace)
                fprintf (output, "}\n");
@@ -827,9 +893,14 @@ dis_types (MonoImage *m)
 {
        MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
        int i;
+       guint32 flags;
 
-       for (i = 1; i < t->rows; i++)
-               dis_type (m, i);
+       for (i = 1; i < t->rows; i++) {
+               flags = mono_metadata_decode_row_col (t, i, MONO_TYPEDEF_FLAGS);
+               flags &= TYPE_ATTRIBUTE_VISIBILITY_MASK;
+               if (flags == TYPE_ATTRIBUTE_PUBLIC || flags == TYPE_ATTRIBUTE_NOT_PUBLIC)
+                       dis_type (m, i);
+       }
 }
 
 /**
@@ -874,31 +945,34 @@ struct {
        int table;
        void (*dumper) (MonoImage *m);
 } table_list [] = {
-       { "--assembly",    MONO_TABLE_ASSEMBLY,    dump_table_assembly },
-       { "--assemblyref", MONO_TABLE_ASSEMBLYREF, dump_table_assemblyref },
-       { "--fields",      MONO_TABLE_FIELD,       dump_table_field },
-       { "--marshal",     MONO_TABLE_FIELDMARSHAL,     dump_table_field_marshal },
-       { "--memberref",   MONO_TABLE_MEMBERREF,   dump_table_memberref },
-       { "--param",       MONO_TABLE_PARAM,       dump_table_param },
-       { "--typedef",     MONO_TABLE_TYPEDEF,     dump_table_typedef },
-       { "--typeref",     MONO_TABLE_TYPEREF,     dump_table_typeref },
+       { "--assembly",    MONO_TABLE_ASSEMBLY,         dump_table_assembly },
+       { "--assemblyref", MONO_TABLE_ASSEMBLYREF,      dump_table_assemblyref },
+       { "--classlayout", MONO_TABLE_CLASSLAYOUT,      dump_table_class_layout },
+       { "--constant",    MONO_TABLE_CONSTANT,         dump_table_constant },
+       { "--customattr",  MONO_TABLE_CUSTOMATTRIBUTE,  dump_table_customattr },
+       { "--declsec",     MONO_TABLE_DECLSECURITY,     dump_table_declsec },
+       { "--event",       MONO_TABLE_EVENT,            dump_table_event },
        { "--exported",    MONO_TABLE_EXPORTEDTYPE,     dump_table_exported },
-       { "--nested",      MONO_TABLE_NESTEDCLASS, dump_table_nestedclass },
-       { "--interface",   MONO_TABLE_INTERFACEIMPL,     dump_table_interfaceimpl },
-       { "--classlayout", MONO_TABLE_CLASSLAYOUT, dump_table_class_layout },
-       { "--constant",    MONO_TABLE_CONSTANT,    dump_table_constant },
-       { "--customattr",  MONO_TABLE_CUSTOMATTRIBUTE,    dump_table_customattr },
-       { "--declsec",     MONO_TABLE_DECLSECURITY, dump_table_declsec },
-       { "--property",    MONO_TABLE_PROPERTY,    dump_table_property },
-       { "--propertymap", MONO_TABLE_PROPERTYMAP, dump_table_property_map },
-       { "--event",       MONO_TABLE_EVENT,       dump_table_event },
-       { "--file",        MONO_TABLE_FILE,        dump_table_file },
-       { "--moduleref",   MONO_TABLE_MODULEREF,   dump_table_moduleref },
-       { "--module",      MONO_TABLE_MODULE,      dump_table_module },
-       { "--method",      MONO_TABLE_METHOD,      dump_table_method },
-       { "--methodimpl",  MONO_TABLE_METHODIMPL,  dump_table_methodimpl },
-       { "--methodsem",   MONO_TABLE_METHODSEMANTICS,      dump_table_methodsem },
-       { "--manifest",    MONO_TABLE_MANIFESTRESOURCE,     dump_table_manifest },
+       { "--fields",      MONO_TABLE_FIELD,            dump_table_field },
+       { "--file",        MONO_TABLE_FILE,             dump_table_file },
+       { "--genericpar",  MONO_TABLE_GENERICPARAM,     dump_table_genericpar },
+       { "--interface",   MONO_TABLE_INTERFACEIMPL,    dump_table_interfaceimpl },
+       { "--manifest",    MONO_TABLE_MANIFESTRESOURCE, dump_table_manifest },
+       { "--marshal",     MONO_TABLE_FIELDMARSHAL,     dump_table_field_marshal },
+       { "--memberref",   MONO_TABLE_MEMBERREF,        dump_table_memberref },
+       { "--method",      MONO_TABLE_METHOD,           dump_table_method },
+       { "--methodimpl",  MONO_TABLE_METHODIMPL,       dump_table_methodimpl },
+       { "--methodsem",   MONO_TABLE_METHODSEMANTICS,  dump_table_methodsem },
+       { "--methodspec",  MONO_TABLE_METHODSPEC,       dump_table_methodspec },
+       { "--moduleref",   MONO_TABLE_MODULEREF,        dump_table_moduleref },
+       { "--module",      MONO_TABLE_MODULE,           dump_table_module },
+       { "--nested",      MONO_TABLE_NESTEDCLASS,      dump_table_nestedclass },
+       { "--param",       MONO_TABLE_PARAM,            dump_table_param },
+       { "--parconst",    MONO_TABLE_GENERICPARAMCONSTRAINT, dump_table_parconstraint },
+       { "--property",    MONO_TABLE_PROPERTY,         dump_table_property },
+       { "--propertymap", MONO_TABLE_PROPERTYMAP,      dump_table_property_map },
+       { "--typedef",     MONO_TABLE_TYPEDEF,          dump_table_typedef },
+       { "--typeref",     MONO_TABLE_TYPEREF,          dump_table_typeref },
        { NULL, -1 }
 };
 
@@ -940,7 +1014,7 @@ disassemble_file (const char *file)
 static void
 usage (void)
 {
-       GString *args = g_string_new ("[--output=filename] [--help] [--mscorlib] ");
+       GString *args = g_string_new ("[--output=filename] [--help] [--mscorlib]\n");
        int i;
        
        for (i = 0; table_list [i].name != NULL; i++){