Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnome.org>2001-07-02 08:19:12 +0400
committerMiguel de Icaza <miguel@gnome.org>2001-07-02 08:19:12 +0400
commit3c8a3d1b0698f57ba31ff2b74473f1a619a93382 (patch)
treef933481a93f6417df486e8b7cd63a39aa0c3252d
parente04016adacbb074a8492c5e807a62dbaa91cf0f2 (diff)
Implement code disassembler.
svn path=/trunk/mono/; revision=45
-rw-r--r--configure.in1
-rw-r--r--mono/cil/.cvsignore3
-rw-r--r--mono/dis/.cvsignore1
-rw-r--r--mono/dis/ChangeLog4
-rw-r--r--mono/dis/Makefile.am3
-rw-r--r--mono/dis/dis-cil.c211
-rw-r--r--mono/dis/dis-cil.h1
-rw-r--r--mono/dis/main.c16
-rw-r--r--mono/dis/push-pop.h265
-rw-r--r--mono/metadata/ChangeLog5
-rw-r--r--mono/metadata/TODO5
-rw-r--r--mono/metadata/metadata.c8
-rw-r--r--mono/metadata/metadata.h1
-rw-r--r--notes/cil6
14 files changed, 523 insertions, 7 deletions
diff --git a/configure.in b/configure.in
index c0bde9b200b..865f09b2d2c 100644
--- a/configure.in
+++ b/configure.in
@@ -31,4 +31,5 @@ Makefile
mono/Makefile
mono/metadata/Makefile
mono/dis/Makefile
+mono/cil/Makefile
]) \ No newline at end of file
diff --git a/mono/cil/.cvsignore b/mono/cil/.cvsignore
new file mode 100644
index 00000000000..10dae49ad16
--- /dev/null
+++ b/mono/cil/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+opcode.def
diff --git a/mono/dis/.cvsignore b/mono/dis/.cvsignore
index e9407c9414e..8521f30085c 100644
--- a/mono/dis/.cvsignore
+++ b/mono/dis/.cvsignore
@@ -2,3 +2,4 @@ Makefile
Makefile.in
.libs
.deps
+monodirs
diff --git a/mono/dis/ChangeLog b/mono/dis/ChangeLog
index 15b16ceab79..b2af66214ed 100644
--- a/mono/dis/ChangeLog
+++ b/mono/dis/ChangeLog
@@ -1,3 +1,7 @@
+2001-07-01 Miguel de Icaza <miguel@ximian.com>
+
+ * dis-cil.c: New file. CIL opcode dissasembler.
+
2001-06-27 Miguel de Icaza <miguel@ximian.com>
* main.c: Split code.
diff --git a/mono/dis/Makefile.am b/mono/dis/Makefile.am
index 01ed731d940..9cb1baad6ad 100644
--- a/mono/dis/Makefile.am
+++ b/mono/dis/Makefile.am
@@ -5,7 +5,8 @@ bin_PROGRAMS = monodis
monodis_SOURCES = \
get.c \
get.h \
- dis.h \
+ dis-cil.c \
+ dis-cil.h \
dump.c \
dump.h \
main.c \
diff --git a/mono/dis/dis-cil.c b/mono/dis/dis-cil.c
new file mode 100644
index 00000000000..eede4e7300b
--- /dev/null
+++ b/mono/dis/dis-cil.c
@@ -0,0 +1,211 @@
+/*
+ * dis-cil.c: Disassembles CIL byte codes
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <glib.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "meta.h"
+#include "dump.h"
+#include "dis-cil.h"
+
+enum {
+ InlineBrTarget,
+ InlineField,
+ InlineI,
+ InlineI8,
+ InlineMethod,
+ InlineNone,
+ InlineR,
+ InlineSig,
+ InlineString,
+ InlineSwitch,
+ InlineTok,
+ InlineType,
+ InlineVar,
+ ShortInlineBrTarget,
+ ShortInlineI,
+ ShortInlineR,
+ ShortInlineVar
+};
+
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
+ { b, e, g, h, i },
+
+typedef struct {
+ char *name;
+ int argument;
+
+ /*
+ * we are not really using any of the following:
+ */
+ int bytes;
+ unsigned char o1, o2;
+} opcode_t;
+
+static opcode_t opcodes [300] = {
+#include "mono/cil/opcode.def"
+};
+
+void
+dissasemble_cil (metadata_t *m, const unsigned char *start, int size)
+{
+ const unsigned char *end = start + size;
+ const unsigned char *ptr = start;
+ opcode_t *entry;
+
+ while (ptr < end){
+ if (*ptr == 0xfe){
+ ptr++;
+ entry = &opcodes [*ptr + 256];
+ } else
+ entry = &opcodes [*ptr];
+
+ fprintf (output, "\tIL_%04x: %s ", (int) (ptr - start), entry->name);
+ ptr++;
+ switch (entry->argument){
+ case InlineBrTarget: {
+ gint target = *(gint32 *) ptr;
+ fprintf (output, "IL_%04x", ((int) (ptr - start)) + 4 + target);
+ ptr += 4;
+ break;
+ }
+
+ case InlineField: {
+ guint32 token = *(guint32 *) ptr;
+ fprintf (output, "fieldref-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI: {
+ int value = *(int *) ptr;
+
+ fprintf (output, "%d", value);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI8: {
+ gint64 top = *(guint64 *) ptr;
+
+ fprintf (output, "%lld", (long long) top);
+ ptr += 8;
+ break;
+ }
+
+ case InlineMethod: {
+ guint32 token = *(guint32 *) ptr;
+ fprintf (output, "method-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineNone:
+ break;
+
+ case InlineR: {
+ double r = *(double *) ptr;
+ fprintf (output, "%g", r);
+ ptr += 8;
+ break;
+ }
+
+ case InlineSig: {
+ guint32 token = *(guint32 *) ptr;
+ fprintf (output, "signature-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineString: {
+ guint32 token = *(guint32 *) ptr;
+
+ /*
+ * See section 23.1.4 on the encoding of the #US heap
+ */
+ fprintf (output, "string-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineSwitch: {
+ guint32 count = *(guint32 *) ptr;
+ guint32 i;
+
+ ptr += 4;
+ fprintf (output, "(\n\t\t\t");
+ for (i = 0; i < count; i++){
+ fprintf (output, "IL_%x", *(guint32 *) ptr);
+ ptr += 4;
+ }
+ fprintf (output, "\t\t\t)");
+ break;
+ }
+
+ case InlineTok: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "TOKEN_%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineType: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "Type-%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineVar: {
+ gint16 var_idx = *(gint16 *) ptr;
+
+ fprintf (output, "variable-%d\n", var_idx);
+ ptr += 2;
+ break;
+ }
+
+ case ShortInlineBrTarget: {
+ signed char x = *ptr;
+
+ fprintf (output, "IL_%04x", ptr - start + 1 + x);
+ ptr++;
+ break;
+ }
+
+ case ShortInlineI: {
+ char x = *ptr;
+
+ fprintf (output, "0x%02x", x);
+ ptr++;
+ break;
+ }
+
+ case ShortInlineR: {
+ float f = *(float *) ptr;
+
+ fprintf (output, "%g", (double) f);
+ ptr += 4;
+ break;
+ }
+
+ case ShortInlineVar: {
+ signed char x = *ptr;
+
+ fprintf (output, "Varidx-%d", (int) x);
+ ptr++;
+ break;
+ }
+
+ }
+
+ fprintf (output, "\n");
+ }
+}
diff --git a/mono/dis/dis-cil.h b/mono/dis/dis-cil.h
new file mode 100644
index 00000000000..7874d4e7ff1
--- /dev/null
+++ b/mono/dis/dis-cil.h
@@ -0,0 +1 @@
+void dissasemble_cil (metadata_t *m, const unsigned char *ptr, int size);
diff --git a/mono/dis/main.c b/mono/dis/main.c
index b18cf3a0b87..09126a1d0f1 100644
--- a/mono/dis/main.c
+++ b/mono/dis/main.c
@@ -1,5 +1,5 @@
/*
- * dis.c: Sample disassembler
+ * main.c: Sample disassembler
*
* Author:
* Miguel de Icaza (miguel@ximian.com)
@@ -290,11 +290,15 @@ dis_code (metadata_t *m, cli_image_info_t *ii, guint32 rva)
mh = mono_metadata_parse_mh (ptr);
fprintf (output, "\t.maxstack %d\n", mh->max_stack);
fprintf (output, "\t// Code size=%d (0x%x)\n", mh->code_size, mh->code_size);
- printf ("Values Code Size=%d/0x%x\nMaxStack=%d\nLocalTok=%x",
- mh->code_size, mh->code_size, mh->max_stack, mh->local_var_sig_tok);
- hex_dump (mh->code, 0, mh->code_size);
- printf ("\nAfter the code\n");
- hex_dump (mh->code + mh->code_size, 0, 64);
+ printf ("\t// Values Code Size=%d/0x%x\n\t// LocalTok=%x\n\n",
+ mh->code_size, mh->code_size, mh->local_var_sig_tok);
+ dissasemble_cil (m, mh->code, mh->code_size);
+
+/*
+ hex_dump (mh->code, 0, mh->code_size);
+ printf ("\nAfter the code\n");
+ hex_dump (mh->code + mh->code_size, 0, 64);
+*/
mono_metadata_free_mh (mh);
}
diff --git a/mono/dis/push-pop.h b/mono/dis/push-pop.h
new file mode 100644
index 00000000000..f74252e4327
--- /dev/null
+++ b/mono/dis/push-pop.h
@@ -0,0 +1,265 @@
+/* Poping */
+/* 1 bit */
+#define Pop0 1
+/* 2 bits */
+#define Pop1 2
+/* 3 bits */
+#define PopI 8
+/* 1 bit */
+#define PopI8 64
+/* 1 bit */
+#define Pop8 128
+/* 1 bit */
+#define PopR4 256
+/* 1 bit */
+#define PopR8 512
+/* 1 bit */
+#define PopRef 1024
+/* 1 bit */
+#define VarPop 2048
+
+/* Pushing */
+#define Push0 1
+#define PushI 2
+#define PushI8 4
+#define PushR4 8
+#define PushR8 16
+#define PushRef 32
+#define VarPush 64
+#define Push1 128
+
+/*
+ * dis-cil.c: Disassembles CIL byte codes
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <glib.h>
+#include <stdio.h>
+#include "meta.h"
+#include "dump.h"
+#include "dis-cil.h"
+
+/* Poping */
+/* 1 bit */
+#define Pop0 1
+/* 2 bits */
+#define Pop1 2
+/* 3 bits */
+#define PopI 8
+/* 1 bit */
+#define PopI8 64
+/* 1 bit */
+#define Pop8 128
+/* 1 bit */
+#define PopR4 256
+/* 1 bit */
+#define PopR8 512
+/* 1 bit */
+#define PopRef 1024
+/* 1 bit */
+#define VarPop 2048
+
+/* Pushing */
+#define Push0 1
+#define PushI 2
+#define PushI8 4
+#define PushR4 8
+#define PushR8 16
+#define PushRef 32
+#define VarPush 64
+#define Push1 128
+
+enum {
+ InlineBrTarget,
+ InlineField,
+ InlineI,
+ InlineI8,
+ InlineMethod,
+ InlineNone,
+ InlineR,
+ InlineSig,
+ InlineString,
+ InlineSwitch,
+ InlineTok,
+ InlineType,
+ InlineVar,
+ ShortInlineBrTarget,
+ ShortInlineI,
+ ShortInlineR,
+ ShortInlineVar
+};
+
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
+ { b, c, d, e, g, h, i },
+
+typedef struct {
+ char *name;
+ int pop, push;
+ int argument;
+ int bytes;
+ unsigned char o1, o2;
+} opcode_t;
+
+static opcode_t opcodes [300] = {
+#include "mono/cil/opcode.def"
+};
+
+void
+dissasemble_cil (metadata_t *m, const unsigned char *start, int size)
+{
+ const unsigned char *end = start + size;
+ const unsigned char *ptr = start;
+ opcode_t *entry;
+
+ while (ptr < end){
+ if (*ptr == 0xfe){
+ ptr++;
+ entry = &opcodes [*ptr + 256];
+ } else
+ entry = &opcodes [*ptr];
+
+ ptr++;
+
+ fprintf (output, "\tIL_%04x: %s ", ptr - start, entry->name);
+ switch (entry->argument){
+ case InlineBrTarget: {
+ gint target = *(gint32 *) ptr;
+ fprintf (output, "IL_%04x", ptr + 4 + target);
+ ptr += 4;
+ break;
+ }
+
+ case InlineField: {
+ token = *(guint32 *) ptr;
+ fprintf (output, "fieldref-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI: {
+ int value = *(int *) ptr;
+
+ fprintf (output, "%d", value);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI8: {
+ gint64 top = *(guint64 *) value;
+
+ fprintf (output, "%ld", top);
+ ptr += 8;
+ break;
+ }
+
+ case InlineMethod: {
+ token = *(guint32 *) ptr;
+ fprintf (output, "method-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineNone:
+ break;
+
+ case InlineR: {
+ double r = *(double *) ptr;
+ fprintf (output, "%g", r);
+ ptr += 8;
+ break;
+ }
+
+ case InlineSig: {
+ guint32 token = *(guint32 *) ptr;
+ fprintf (output, "signature-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineString: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "string-%0x08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineSwitch: {
+ guint32 count = *(guint32 *) ptr;
+ guint32 i;
+
+ ptr += 4;
+ fprintf (output, "(\n\t\t\t");
+ for (i = 0; i < count; i++){
+ fprintf (output, "IL_%x", *(guint32 *) ptr);
+ ptr += 4;
+ }
+ fprintf (output, "\t\t\t)");
+ break;
+ }
+
+ case InlineTok: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "TOKEN_%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineType: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "Type-%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineVar: {
+ gint16 var_idx = *(gint16 *) ptr;
+
+ fprintf (output, "variable-%d\n", var_idx);
+ ptr += 2;
+ break;
+ }
+
+ case ShortInlineBrTarget: {
+ signed char x = *ptr;
+
+ fprintf (output, "IL_%04x", ptr - start + 1 + x);
+ ptr++:
+ break;
+ }
+
+ case ShortInlineI: {
+ char x = *ptr;
+
+ fprintf (output, "0x%02x", x);
+ ptr++;
+ break;
+ }
+
+ case ShortInlineR: {
+ float f = *(float *) ptr;
+
+ fprintf (output, "%g", (double) f);
+ ptr += 4;
+ break;
+ }
+
+ case ShortInlineVar: {
+ signed char x = *ptr;
+
+ fprintf (output, "Varidx-%d", (int) x);
+ ptr++;
+ break;
+ }m
+
+ }
+
+ fprintf (output, "\n");
+ }
+}
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog
index ec8657a4d9e..2a339d6c8c1 100644
--- a/mono/metadata/ChangeLog
+++ b/mono/metadata/ChangeLog
@@ -1,3 +1,8 @@
+2001-07-01 Miguel de Icaza <miguel@ximian.com>
+
+ * metadata.c (mono_metadata_user_string): New function, provides
+ access to the UserString heap.
+
2001-06-27 Miguel de Icaza <miguel@ximian.com>
* metadata.c: Add inline documentation.
diff --git a/mono/metadata/TODO b/mono/metadata/TODO
new file mode 100644
index 00000000000..7c7da2c7aef
--- /dev/null
+++ b/mono/metadata/TODO
@@ -0,0 +1,5 @@
+
+* Rename assembly.c to module.c
+
+ * Rename all symbols called `assembly' to module, because that is
+ what they actually are. \ No newline at end of file
diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c
index cfaba846190..ea3a9727493 100644
--- a/mono/metadata/metadata.c
+++ b/mono/metadata/metadata.c
@@ -643,6 +643,12 @@ mono_metadata_string_heap (metadata_t *meta, guint32 index)
return meta->raw_metadata + meta->heap_strings.sh_offset + index;
}
+const char *
+mono_metadata_user_string (metadata_t *meta, guint32 index)
+{
+ return meta->raw_metadata + meta->heap_us.sh_offset + index;
+}
+
/**
* mono_metadata_blob_heap:
* @meta: metadata context
@@ -699,6 +705,7 @@ parse_exception_handler (const char *ptr, gboolean is_fat)
static void
parse_section_data (MonoMetaMethodHeader *mh, const char *ptr)
{
+#if 0
while ((*ptr) & METHOD_HEADER_SECTION_MORE_SECTS){
/* align on 32-bit boundary */
/* FIXME: not 64-bit clean code */
@@ -723,6 +730,7 @@ parse_section_data (MonoMetaMethodHeader *mh, const char *ptr)
ptr = dword_align (ptr);
}
+#endif
}
MonoMetaMethodHeader *
diff --git a/mono/metadata/metadata.h b/mono/metadata/metadata.h
index bd285ed162d..c2d8af6c336 100644
--- a/mono/metadata/metadata.h
+++ b/mono/metadata/metadata.h
@@ -172,6 +172,7 @@ char *mono_metadata_locate_token (metadata_t *meta, guint32 token);
const char *mono_metadata_string_heap (metadata_t *meta, guint32 index);
const char *mono_metadata_blob_heap (metadata_t *meta, guint32 index);
+const char *mono_metadata_user_string (metadata_t *meta, guint32 index);
typedef enum {
MONO_META_EXCEPTION_CLAUSE_NONE,
diff --git a/notes/cil b/notes/cil
new file mode 100644
index 00000000000..eaf550b9fe2
--- /dev/null
+++ b/notes/cil
@@ -0,0 +1,6 @@
+Random collection of notes
+
+ * What is the point of having the InlineVar argument to
+ opcodes be a signed integer instead of unsigned?
+
+