}
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);
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)
{
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",
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);
}
}
{ 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 }
};
{ 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 }
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 }
};
}
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)
}
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);
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);
/*
}
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];
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");
}
}
char *flags, *impl_flags;
const char *sig;
char *sig_str;
+ guint32 token;
mono_metadata_decode_row (t, i, cols, MONO_METHOD_SIZE);
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);
++start;
}
}
-
static char*
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 ("");
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++) {
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;
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++;
}
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");
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);
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 */
{ "--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, }
};
/**
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;
}