2 * dis-cil.c: Disassembles CIL byte codes
5 * Miguel de Icaza (miguel@ximian.com)
7 * (C) 2001 Ximian, Inc.
38 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
46 * we are not really using any of the following:
52 static opcode_t opcodes [300] = {
53 #include "mono/cil/opcode.def"
57 * Strings on the US heap are encoded using UTF-16. Poor man's
58 * UTF-16 to UTF-8. I know its broken, use libunicode later.
61 get_encoded_user_string (const char *ptr)
66 len = mono_metadata_decode_blob_size (ptr, &ptr);
67 res = g_malloc (len + 1);
70 * I should really use some kind of libunicode here
72 for (i = 0, j = 0; i < len; j++, i += 2)
80 #define CODE_INDENT g_assert (indent_level < 127); \
81 indent[indent_level*2] = ' '; \
82 indent[indent_level*2+1] = ' '; \
84 indent[indent_level*2] = 0;
85 #define CODE_UNINDENT g_assert (indent_level); \
87 indent[indent_level*2] = 0;
90 dissasemble_cil (metadata_t *m, MonoMetaMethodHeader *mh)
92 const unsigned char *start = mh->code;
93 int size = mh->code_size;
94 const unsigned char *end = start + size;
95 const unsigned char *ptr = start;
98 int i, indent_level = 0;
99 char *clause_names[] = {"catch", "filter", "finally", "fault"};
104 /* first pass to get the end clauses */
105 for (i = 0; i < mh->num_clauses; ++i) {
106 if (!mh->clauses[i].flags && ptr == start + mh->clauses[i].try_offset + mh->clauses[i].try_len) {
108 fprintf (output, "\t%s} // end .try %d\n", indent, i);
110 if (ptr == start + mh->clauses[i].handler_offset + mh->clauses[i].handler_len) {
112 fprintf (output, "\t%s} // end handler %d\n", indent, i);
115 for (i = 0; i < mh->num_clauses; ++i) {
116 if (!mh->clauses[i].flags && ptr == start + mh->clauses[i].try_offset) {
117 fprintf (output, "\t%s.try { // %d\n", indent, i);
120 if (ptr == start + mh->clauses[i].handler_offset) {
121 char * klass = mh->clauses[i].flags ? g_strdup ("") : dis_stringify_token (m, mh->clauses[i].token_or_filter);
122 fprintf (output, "\t%s%s %s { // %d\n", indent, clause_names [mh->clauses[i].flags], klass, i);
129 entry = &opcodes [*ptr + 256];
131 entry = &opcodes [*ptr];
133 fprintf (output, "\t%sIL_%04x: %s ", indent, (int) (ptr - start), entry->name);
135 switch (entry->argument){
136 case InlineBrTarget: {
137 gint target = *(gint32 *) ptr;
138 fprintf (output, "IL_%04x", ((int) (ptr - start)) + 4 + target);
144 guint32 token = *(guint32 *) ptr;
147 s = get_field (m, token);
148 fprintf (output, "%s", s);
155 int value = *(int *) ptr;
157 fprintf (output, "%d", value);
163 gint64 top = *(guint64 *) ptr;
165 fprintf (output, "%lld", (long long) top);
171 guint32 token = *(guint32 *) ptr;
174 s = get_method (m, token);
175 fprintf (output, "%s", s);
185 double r = *(double *) ptr;
186 fprintf (output, "%g", r);
192 guint32 token = *(guint32 *) ptr;
193 fprintf (output, "signature-0x%08x", token);
199 guint32 token = *(guint32 *) ptr;
201 char *s = get_encoded_user_string (
202 mono_metadata_user_string (m, token & 0xffffff));
205 * See section 23.1.4 on the encoding of the #US heap
207 fprintf (output, "\"%s\"", s);
214 guint32 count = *(guint32 *) ptr;
218 fprintf (output, "(\n\t\t\t");
219 for (i = 0; i < count; i++){
220 fprintf (output, "IL_%x", *(guint32 *) ptr);
223 fprintf (output, "\t\t\t)");
228 guint32 token = *(guint32 *) ptr;
231 s = get_token (m, token);
232 fprintf (output, "%s", s);
240 guint32 token = *(guint32 *) ptr;
241 char *s = get_token_type (m, token);
242 fprintf (output, "%s", s);
249 gint16 var_idx = *(gint16 *) ptr;
251 fprintf (output, "variable-%d\n", var_idx);
256 case ShortInlineBrTarget: {
257 signed char x = *ptr;
259 fprintf (output, "IL_%04x", ptr - start + 1 + x);
267 fprintf (output, "0x%02x", x);
273 float f = *(float *) ptr;
275 fprintf (output, "%g", (double) f);
280 case ShortInlineVar: {
281 signed char x = *ptr;
283 fprintf (output, "V_%d", (int) x);
291 fprintf (output, "\n");