#include <mono/metadata/loader.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/appdomain.h>
+#include <mono/utils/bsearch.h>
static void setup_filter (MonoImage *image);
static gboolean should_include_type (int idx);
{ METHOD_ATTRIBUTE_RT_SPECIAL_NAME, "rtspecialname " },
{ METHOD_ATTRIBUTE_UNMANAGED_EXPORT, "export " },
/* 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_HAS_SECURITY, "" /*"hassecurity"*/ },
+ { METHOD_ATTRIBUTE_REQUIRE_SEC_OBJECT, "requiresecobj " },
{ METHOD_ATTRIBUTE_PINVOKE_IMPL, "pinvokeimpl " },
{ METHOD_ATTRIBUTE_STRICT, "strict " },
{ 0, NULL }
{
GString *str = g_string_new ("");
int access = f & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK;
+ int rest = f & ~access;
char *s;
g_string_append (str, map (access, method_access_map));
- g_string_append (str, flags (f, method_flags_map));
+ g_string_append (str, flags (rest, method_flags_map));
s = str->str;
g_string_free (str, FALSE);
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" },
+ { 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 }
};
GString *str = g_string_new ("");
int cset = f & PINVOKE_ATTRIBUTE_CHAR_SET_MASK;
int cconv = f & PINVOKE_ATTRIBUTE_CALL_CONV_MASK;
+ int rest = f & ~(cset | cconv);
char *s;
g_string_append (str, map (cset, pinvoke_char_set_map));
g_string_append (str, map (cconv, pinvoke_call_conv_map));
- g_string_append (str, flags (f, pinvoke_flags_map));
+ g_string_append (str, flags (rest, pinvoke_flags_map));
s = g_strdup(str->str);
g_string_free (str, FALSE);
return s;
}
-static dis_map_t method_impl_map [] = {
- { METHOD_IMPL_ATTRIBUTE_IL, "cil " },
- { METHOD_IMPL_ATTRIBUTE_NATIVE, "native " },
- { METHOD_IMPL_ATTRIBUTE_OPTIL, "optil " },
- { METHOD_IMPL_ATTRIBUTE_RUNTIME, "runtime " },
- { 0, NULL }
-};
-
-static dis_map_t managed_type_map [] = {
- { METHOD_IMPL_ATTRIBUTE_UNMANAGED, "unmanaged " },
- { METHOD_IMPL_ATTRIBUTE_MANAGED, "managed " },
- { 0, NULL }
-};
-
-static dis_map_t managed_impl_flags [] = {
- { METHOD_IMPL_ATTRIBUTE_FORWARD_REF, "fwdref " },
- { METHOD_IMPL_ATTRIBUTE_PRESERVE_SIG, "preservesig " },
- { METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL, "internalcall " },
- { METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED, "synchronized " },
- { METHOD_IMPL_ATTRIBUTE_NOINLINING, "noinlining " },
- { 0, NULL }
-};
-
-static char *
-method_impl_flags (guint32 f)
-{
- GString *str = g_string_new ("");
- char *s;
- int code_type = f & METHOD_IMPL_ATTRIBUTE_CODE_TYPE_MASK;
- int managed_type = f & METHOD_IMPL_ATTRIBUTE_MANAGED_MASK;
-
- g_string_append (str, map (code_type, method_impl_map));
- g_string_append (str, map (managed_type, managed_type_map));
- g_string_append (str, flags (f, managed_impl_flags));
-
- s = str->str;
- g_string_free (str, FALSE);
- return s;
-}
-
static void
dis_locals (MonoImage *m, MonoMethodHeader *mh, const char *ptr)
{
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;
+ guint32 local_var_sig_tok, init_locals;
g_assert (format == METHOD_HEADER_FAT_FORMAT);
fat_flags = read16 (ptr);
ptr += 2;
- hsize = (fat_flags >> 12) & 0xf;
- max_stack = read16 (ptr);
+ /* max_stack = read16 (ptr); */
ptr += 2;
- code_size = read32 (ptr);
+ /* code_size = read32 (ptr); */
ptr += 4;
local_var_sig_tok = read32 (ptr);
ptr += 4;
}
mh = mono_metadata_parse_mh_full (m, container, ptr);
- if ((entry_point = mono_image_get_entry_point (m)) && mono_metadata_token_index (entry_point)){
+ entry_point = mono_image_get_entry_point (m);
+ if (entry_point && mono_metadata_token_index (entry_point) && mono_metadata_token_table (entry_point) == MONO_TABLE_METHOD) {
loc = mono_metadata_locate_token (m, entry_point);
if (rva == read32 (loc))
fprintf (output, "\t.entrypoint\n");
}
for (i = start; i < end; i++){
+ MonoError error;
MonoMethodSignature *ms;
MonoGenericContainer *container;
char *flags, *impl_flags;
mono_metadata_decode_row (t, i, cols, MONO_METHOD_SIZE);
flags = method_flags (cols [MONO_METHOD_FLAGS]);
- impl_flags = method_impl_flags (cols [MONO_METHOD_IMPLFLAGS]);
+ impl_flags = get_method_impl_flags (cols [MONO_METHOD_IMPLFLAGS]);
sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
mono_metadata_decode_blob_size (sig, &sig);
container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | (i + 1), type_container);
- if (container)
- mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | (i + 1), container);
- else
+ if (container) {
+ MonoError error;
+ mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_METHOD_DEF | (i + 1), container, &error);
+ g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/
+ } else {
container = type_container;
+ }
- ms = mono_metadata_parse_method_signature_full (m, container, i + 1, sig, &sig);
- sig_str = dis_stringify_method_signature (m, ms, i + 1, container, FALSE);
- method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
+ ms = mono_metadata_parse_method_signature_full (m, container, i + 1, sig, &sig, &error);
+ if (ms != NULL){
+ sig_str = dis_stringify_method_signature (m, ms, i + 1, container, FALSE);
+ method_name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
+ } else {
+ sig_str = NULL;
+ method_name = g_strdup ("<NULL METHOD SIGNATURE>");
+ mono_error_cleanup (&error);
+ }
fprintf (output, " // method line %d\n", i + 1);
fprintf (output, " .method %s", flags);
g_string_append (res, "instance ");
ptr++;
pcount = mono_metadata_decode_value (ptr, &ptr);
- type = mono_metadata_parse_type_full (m, container, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ type = mono_metadata_parse_type_full (m, container, 0, ptr, &ptr);
blurb = dis_stringify_type (m, type, TRUE);
if (prop_flags & 0x0200)
g_string_append (res, "specialname ");
if (prop_flags & 0x0400)
g_string_append (res, "rtspecialname ");
qk = get_escaped_name (name);
- g_string_sprintfa (res, "%s %s (", blurb, qk);
+ g_string_append_printf (res, "%s %s (", blurb, qk);
g_free (qk);
g_free (blurb);
for (i = 0; i < pcount; i++) {
if (i)
g_string_append (res, ", ");
- param = mono_metadata_parse_type_full (m, container, MONO_PARSE_PARAM, 0, ptr, &ptr);
+ param = mono_metadata_parse_type_full (m, container, 0, ptr, &ptr);
blurb = dis_stringify_param (m, param);
g_string_append (res, blurb);
g_free (blurb);
g_string_append (res, "specialname ");
if (event_flags & 0x0400)
g_string_append (res, "rtspecialname ");
- g_string_sprintfa (res, "%s %s", type, esname);
+ g_string_append_printf (res, "%s %s", type, esname);
g_free (type);
g_free (esname);
loc.col_idx = MONO_INTERFACEIMPL_CLASS;
loc.idx = typedef_row;
- if (!bsearch (&loc, table->base, table->rows, table->row_size, table_locator))
+ if (!mono_binary_search (&loc, table->base, table->rows, table->row_size, table_locator))
return;
start = loc.result;
name = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]);
nspace = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]);
- if (*nspace && !is_nested)
- fprintf (output, ".namespace %s\n{\n", nspace);
+ if (*nspace && !is_nested) {
+ char *esnspace;
+ esnspace = get_escaped_name (nspace);
+ fprintf (output, ".namespace %s\n{\n", esnspace);
+ g_free (esnspace);
+ }
container = mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | (n + 1), NULL);
- if (container)
- mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_TYPE_DEF | (n + 1), container);
+ if (container) {
+ MonoError error;
+ mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_TYPE_DEF | (n + 1), container, &error);
+ g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/
+ }
esname = get_escaped_name (name);
if ((cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK) == TYPE_ATTRIBUTE_CLASS){
param = get_generic_param (m, container);
if (param) {
- fprintf (output, param);
+ fprintf (output, "%s", param);
g_free (param);
}
fprintf (output, "\n");
param = get_generic_param (m, container);
if (param) {
- fprintf (output, param);
+ fprintf (output, "%s", param);
g_free (param);
}
fprintf (output, "\n");
}
-static void
-dis_mresource (MonoImage *m)
+static void dis_resources_worker (MonoImage *m, gboolean just_print)
{
MonoTableInfo *t = &m->tables [MONO_TABLE_MANIFESTRESOURCE];
int i;
mono_metadata_decode_row (t, i, cols, MONO_MANIFEST_SIZE);
name = mono_metadata_string_heap (m, cols [MONO_MANIFEST_NAME]);
+
+ if (just_print)
+ fprintf (output, "%8x: %s", cols [MONO_MANIFEST_OFFSET], name);
- if (! (res = mono_image_get_resource (m, cols [MONO_MANIFEST_OFFSET], &size)))
+ if (! (res = mono_image_get_resource (m, cols [MONO_MANIFEST_OFFSET], &size))) {
+ if (just_print)
+ fprintf (output, " (absent from image)\n");
continue;
+ }
+ if (just_print) {
+ fprintf (output, " (size %u)\n", size);
+ continue;
+ }
+
if ( (fp = fopen (name, "ab")) ) {
if (ftell (fp) == 0)
fwrite (res, size, 1, fp);
}
}
+static void
+dis_mresource (MonoImage *m)
+{
+ dis_resources_worker (m, FALSE);
+}
+
+static void
+dis_presource (MonoImage *m)
+{
+ dis_resources_worker (m, TRUE);
+}
+
+static char *
+exported_type_flags (guint32 flags)
+{
+ static char buffer [1024];
+ int visibility = flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+
+ buffer [0] = 0;
+
+ if (flags & TYPE_ATTRIBUTE_FORWARDER) {
+ strcat (buffer, "forwarder ");
+ return buffer;
+ }
+
+ strcat (buffer, map (visibility, visibility_map));
+ return buffer;
+}
+
+static char *
+get_escaped_fullname (MonoImage *m, guint32 nspace_idx, guint32 name_idx)
+{
+ const char *name, *nspace;
+ char *fullname, *esfullname;
+
+ nspace = mono_metadata_string_heap (m, nspace_idx);
+ name = mono_metadata_string_heap (m, name_idx);
+
+ fullname = g_strdup_printf ("%s%s%s", nspace, *nspace ? "." : "", name);
+ esfullname = get_escaped_name (fullname);
+
+ g_free (fullname);
+
+ return esfullname;
+}
+
+static void
+dis_exported_types (MonoImage *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_EXPORTEDTYPE];
+ int i;
+
+ for (i = 1; i <= t->rows; i++) {
+ char *fullname;
+ guint32 impl, idx, type_token;
+ guint32 cols [MONO_EXP_TYPE_SIZE];
+
+ mono_metadata_decode_row (t, i - 1, cols, MONO_EXP_TYPE_SIZE);
+
+ fullname = get_escaped_fullname (m, cols [MONO_EXP_TYPE_NAMESPACE], cols [MONO_EXP_TYPE_NAME]);
+
+ fprintf (output, "\n");
+ fprintf (output, ".class extern %s%s\n", exported_type_flags (cols [MONO_EXP_TYPE_FLAGS]), fullname);
+ fprintf (output, "{\n");
+
+ g_free (fullname);
+
+ impl = cols [MONO_EXP_TYPE_IMPLEMENTATION];
+ if (impl) {
+ idx = impl >> MONO_IMPLEMENTATION_BITS;
+ switch (impl & MONO_IMPLEMENTATION_MASK) {
+ case MONO_IMPLEMENTATION_FILE:
+ fprintf (output, " .file '%s'\n",
+ mono_metadata_string_heap (m, mono_metadata_decode_row_col (&m->tables [MONO_TABLE_FILE], idx - 1, MONO_FILE_NAME)));
+ break;
+ case MONO_IMPLEMENTATION_ASSEMBLYREF:
+ fprintf (output, " .assembly extern '%s'\n",
+ mono_metadata_string_heap (m, mono_metadata_decode_row_col (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, MONO_ASSEMBLYREF_NAME)));
+ break;
+ case MONO_IMPLEMENTATION_EXP_TYPE:
+ fullname = get_escaped_fullname (
+ m,
+ mono_metadata_decode_row_col (&m->tables [MONO_TABLE_EXPORTEDTYPE], idx - 1, MONO_EXP_TYPE_NAMESPACE),
+ mono_metadata_decode_row_col (&m->tables [MONO_TABLE_EXPORTEDTYPE], idx - 1, MONO_EXP_TYPE_NAME));
+ fprintf (output, " .class extern %s\n", fullname);
+ g_free (fullname);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+ type_token = cols [MONO_EXP_TYPE_TYPEDEF];
+ if (type_token)
+ fprintf (output, " .class 0x%08x\n", type_token | MONO_TOKEN_TYPE_DEF);
+
+ fprintf (output, "}\n");
+ }
+}
+
/**
* dis_types:
* @m: metadata context
{ "--moduleref", MONO_TABLE_MODULEREF, dump_table_moduleref },
{ "--module", MONO_TABLE_MODULE, dump_table_module },
{ "--mresources", 0, dis_mresource },
+ { "--presources", 0, dis_presource },
{ "--nested", MONO_TABLE_NESTEDCLASS, dump_table_nestedclass },
{ "--param", MONO_TABLE_PARAM, dump_table_param },
{ "--parconst", MONO_TABLE_GENERICPARAMCONSTRAINT, dump_table_parconstraint },
{
MonoImageOpenStatus status;
MonoImage *img;
- MonoAssembly *assembly;
-
img = mono_image_open (file, &status);
if (!img) {
fprintf (stderr, "Error while trying to process %s\n", file);
return;
} else {
- assembly = mono_assembly_load_from_full (img, file, &status, FALSE);
+ /* FIXME: is this call necessary? */
+ mono_assembly_load_from_full (img, file, &status, FALSE);
}
setup_filter (img);
dis_directive_mresource (img);
dis_directive_module (img);
dis_directive_moduleref (img);
+ dis_exported_types (img);
dis_nt_header (img);
if (dump_managed_resources)
dis_mresource (img);
{
if (!tf->count)
return FALSE;
- return bsearch (&idx, tf->elems, tf->count, sizeof (int), int_cmp) != NULL;
+ return mono_binary_search (&idx, tf->elems, tf->count, sizeof (int), int_cmp) != NULL;
}
static gboolean