Weekend work

svn path=/trunk/mono/; revision=32


Commit migrated from 3094b32e9d
This commit is contained in:
Miguel de Icaza 2001-06-25 17:22:30 +00:00
parent cf34add341
commit baed4b1502
7 changed files with 530 additions and 36 deletions

View File

@ -3,7 +3,9 @@ INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)
bin_PROGRAMS = monodis
monodis_SOURCES = \
main.c
main.c \
util.c \
util.h
monodis_LDADD = \
../metadata/libmetadata.a \

View File

@ -14,6 +14,9 @@
#include <mono/metadata/cil-coff.h>
#include <mono/metadata/endian.h>
#include <mono/metadata/typeattr.h>
#include <mono/metadata/fieldattr.h>
#include <mono/metadata/eltype.h>
#include "util.h"
FILE *output;
@ -113,23 +116,6 @@ dis_directive_assemblyref (metadata_t *m)
}
}
typedef struct {
int code;
char *str;
} map_t;
static const char *
map (int code, map_t *table)
{
int i;
for (i = 0; table [i].str != NULL; i++)
if (table [i].code == code)
return table [i].str;
g_assert_not_reached ();
return "";
}
static map_t visibility_map [] = {
{ TYPE_ATTRIBUTE_NOT_PUBLIC, "not-public " },
{ TYPE_ATTRIBUTE_PUBLIC, "public " },
@ -186,31 +172,433 @@ typedef_flags (guint32 flags)
return buffer;
}
static void
dis_fields (metadata_t *m, guint32 idx)
static map_t access_map [] = {
{ FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
{ FIELD_ATTRIBUTE_PRIVATE, "private " },
{ FIELD_ATTRIBUTE_FAM_AND_ASSEM, "famandassem " },
{ FIELD_ATTRIBUTE_ASSEMBLY, "assembly " },
{ FIELD_ATTRIBUTE_FAMILY, "family " },
{ FIELD_ATTRIBUTE_FAM_OR_ASSEM, "famorassem " },
{ FIELD_ATTRIBUTE_PUBLIC, "public " },
{ 0, NULL }
};
static map_t field_flags_map [] = {
{ FIELD_ATTRIBUTE_STATIC, "static " },
{ FIELD_ATTRIBUTE_INIT_ONLY, "initonly " },
{ FIELD_ATTRIBUTE_LITERAL, "literal " },
{ FIELD_ATTRIBUTE_NOT_SERIALIZED, "notserialized " },
{ FIELD_ATTRIBUTE_SPECIAL_NAME, "specialname " },
{ FIELD_ATTRIBUTE_PINVOKE_IMPL, "FIXME:pinvokeimpl " },
{ 0, NULL }
};
static map_t element_type_map [] = {
{ ELEMENT_TYPE_END , "end" },
{ ELEMENT_TYPE_VOID , "System.Void" },
{ ELEMENT_TYPE_BOOLEAN , "System.Bool" },
{ ELEMENT_TYPE_CHAR , "System.Char" },
{ ELEMENT_TYPE_I1 , "System.SByte" },
{ ELEMENT_TYPE_U1 , "System.Byte" },
{ ELEMENT_TYPE_I2 , "System.Int16" },
{ ELEMENT_TYPE_U2 , "System.UInt16" },
{ ELEMENT_TYPE_I4 , "System.Int32" },
{ ELEMENT_TYPE_U4 , "System.UInt32" },
{ ELEMENT_TYPE_I8 , "System.Int64" },
{ ELEMENT_TYPE_U8 , "System.UInt64" },
{ ELEMENT_TYPE_R4 , "System.Single" },
{ ELEMENT_TYPE_R8 , "System.Double" },
{ ELEMENT_TYPE_STRING , "System.String" },
{ ELEMENT_TYPE_TYPEDBYREF , "TypedByRef" },
{ ELEMENT_TYPE_I , "System.Int32" },
{ ELEMENT_TYPE_U , "System.UPtr" },
{ ELEMENT_TYPE_OBJECT , "System.Object" },
{ 0, NULL }
};
/**
* field_flags:
*
* Returns a stringified version of a Field's flags
*/
static char *
field_flags (guint32 f)
{
fprintf (output, "FIELD_LIST: %d\n", idx);
static char buffer [1024];
int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
buffer [0] = 0;
strcat (buffer, map (access, access_map));
strcat (buffer, flags (f, field_flags_map));
return g_strdup (buffer);
}
static void
dis_methods (metadata_t *m, guint32 idx)
/**
* get_encoded_value:
* @ptr: pointer to decode from
* @len: result value is stored here.
*
* This routine decompresses 32-bit values as specified in the "Blob and
* Signature" section (22.2)
*
* Returns: updated pointer location
*/
static const char *
get_encoded_value (const char *_ptr, guint32 *len)
{
const unsigned char *ptr = (unsigned char *) _ptr;
unsigned char b = *ptr;
if ((b & 0x80) == 0){
*len = b;
return ptr+1;
} else if ((b & 0x40) == 0){
*len = ((b & 0x3f) << 8 | ptr [1]);
return ptr + 2;
}
*len = ((b & 0x1f) << 24) |
(ptr [1] << 16) |
(ptr [2] << 8) |
ptr [3];
return ptr + 4;
}
/**
* get_custom_mod:
*
* Decodes a CustomMod (22.2.7)
*
* Returns: updated pointer location
*/
static const char *
get_custom_mod (const char *ptr, char **return_value)
{
if ((*ptr == ELEMENT_TYPE_CMOD_OPT) ||
(*ptr == ELEMENT_TYPE_CMOD_REQD)){
fprintf (stderr, "FIXME: still do not support CustomMods (22.2.7)");
exit (1);
}
*return_value = NULL;
return ptr;
}
static char *
typedef_or_ref (guint32 index)
{
return "";
}
static void
dis_type (metadata_t *m, metadata_tableinfo_t *t, int n)
get_typedef (metadata_t *m, int idx)
{
guint32 cols [6];
expand (&m->tables [META_TABLE_TYPEDEF], idx - 1, cols, CSIZE (cols));
return g_strdup_printf (
"%s.%s",
mono_metadata_string_heap (m, cols [2]),
mono_metadata_string_heap (m, cols [1]));
}
static char *
get_module (metadata_t *m, int idx)
{
guint32 cols [9];
/* g_assert (idx <= m->tables [META_TABLE_MODULE].rows); */
/* return g_strdup_printf ("IDX=0x%x", idx); */
expand (&m->tables [META_TABLE_ASSEMBLYREF], 0, cols, CSIZE (cols));
return g_strdup (mono_metadata_string_heap (m, cols [6]));
}
static char *
get_typeref (metadata_t *m, int idx)
{
guint32 cols [3];
const char *s, *t;
char *x, *ret;
guint32 rs_idx, table;
expand (&m->tables [META_TABLE_TYPEREF], idx - 1, cols, CSIZE (cols));
t = mono_metadata_string_heap (m, cols [1]);
s = mono_metadata_string_heap (m, cols [2]);
rs_idx = cols [0] >> 3;
table = cols [0] & 7;
printf ("------------ %d %d --------\n", rs_idx, table);
switch (table){
case 0: /* Module */
x = get_module (m, rs_idx);
ret = g_strdup_printf ("[%08x:%s] %s.%s", cols [0], x, s, t);
g_free (x);
break;
case 1: /* ModuleRef */
ret = g_strdup_printf ("TypeRef: ModuleRef (%s.%s)", s, t);
case 3: /* AssemblyRef */
ret = g_strdup_printf ("TypeRef: AssemblyRef (%s.%s)", s, t);
case 4: /* TypeRef */
ret = g_strdup_printf ("TypeRef: TYPEREF! (%s.%s)", s, t);
default:
ret = g_strdup ("ERROR");
}
return ret;
}
static char *
typedef_or_ref (metadata_t *m, guint32 dor_token)
{
int table = dor_token & 0x03;
int idx = dor_token >> 2;
char *s, *temp = NULL;
switch (table){
case 0: /* TypeDef */
temp = get_typedef (m, idx);
s = g_strdup_printf ("%s", temp);
break;
case 1: /* TypeRef */
temp = get_typeref (m, idx);
s = g_strdup_printf ("/* 0x%08x */ %s", dor_token, temp);
break;
case 2: /* TypeSpec */
s = g_strdup_printf ("TypeSpec: 0x%08x", dor_token);
break;
}
if (temp)
g_free (temp);
return s;
}
/**
* get_encoded_typedef_or_ref:
* @m: metadata context
* @ptr: location to decode from.
* @result: pointer to string where resulting decoded string is stored
*
* result will point to a g_malloc()ed string.
*
* Returns: the new ptr to continue decoding
*/
static const char *
get_encoded_typedef_or_ref (metadata_t *m, const char *ptr, char **result)
{
guint32 token;
ptr = get_encoded_value (ptr, &token);
*result = typedef_or_ref (m, token);
return ptr;
}
/**
* methoddefref_signature:
* @m: metadata context
* @ptr: location to decode from.
* @result: pointer to string where resulting decoded string is stored
*
* This routine decodes into a string a MethodDef or a MethodRef.
*
* result will point to a g_malloc()ed string.
*
* Returns: the new ptr to continue decoding
*/
static const char *
methoddefref_signature (metadata_t *m, const char *ptr, char **result)
{
*result = g_strdup ("method-def-or-ref");
return ptr;
}
/**
* get_type:
* @m: metadata context
* @ptr: location to decode from.
* @result: pointer to string where resulting decoded string is stored
*
* This routine returs in @result the stringified type pointed by @ptr.
*
* Returns: the new ptr to continue decoding
*/
static const char *
get_type (metadata_t *m, const char *ptr, char **result)
{
char c;
c = *ptr++;
switch (c){
case ELEMENT_TYPE_BOOLEAN:
case ELEMENT_TYPE_CHAR:
case ELEMENT_TYPE_I1:
case ELEMENT_TYPE_U1:
case ELEMENT_TYPE_I2:
case ELEMENT_TYPE_U2:
case ELEMENT_TYPE_I4:
case ELEMENT_TYPE_U4:
case ELEMENT_TYPE_I8:
case ELEMENT_TYPE_U8:
case ELEMENT_TYPE_R4:
case ELEMENT_TYPE_R8:
case ELEMENT_TYPE_I:
case ELEMENT_TYPE_STRING:
case ELEMENT_TYPE_OBJECT:
*result = g_strdup (map (c, element_type_map));
break;
case ELEMENT_TYPE_VALUETYPE:
case ELEMENT_TYPE_CLASS:
ptr = get_encoded_typedef_or_ref (m, ptr, result);
break;
case ELEMENT_TYPE_FNPTR:
ptr = methoddefref_signature (m, ptr, result);
break;
case ELEMENT_TYPE_ARRAY:
*result = g_strdup ("ARRAY:TODO");
break;
case ELEMENT_TYPE_SZARRAY:
*result = g_strdup ("SZARRAY:TODO");
}
return ptr;
}
/**
*
* Returns a stringified representation of a FieldSig (22.2.4)
*/
static char *
field_signature (metadata_t *m, guint32 blob_signature)
{
char *allocated_modifier_string, *allocated_type_string;
const char *ptr = mono_metadata_blob_heap (m, blob_signature);
const char *base;
int len;
static char buffer [8192];
ptr = get_encoded_value (ptr, &len);
base = ptr;
/* FIELD is 0x06 */
g_assert (*ptr == 0x06);
hex_dump (ptr, 0, len);
ptr++; len--;
ptr = get_custom_mod (ptr, &allocated_modifier_string);
ptr = get_type (m, ptr, &allocated_type_string);
sprintf (buffer, "LEN=%d:::: ", len);
strcat (buffer, allocated_type_string);
if (allocated_modifier_string)
g_free (allocated_modifier_string);
if (allocated_type_string)
g_free (allocated_modifier_string);
return g_strdup (buffer);
}
/**
* decode_literal:
* @m: metadata context
* @token: token to decode
*
* decodes the literal indexed by @token.
*/
static char *
decode_literal (metadata_t *m, guint32 token)
{
return g_strdup ("LITERAL_VALUE");
}
/**
* dis_field_list:
* @m: metadata context
* @start: starting index into the Field Table.
* @end: ending index into Field table.
*
* This routine displays all the decoded fields from @start to @end
*/
static void
dis_field_list (metadata_t *m, guint32 start, guint32 end)
{
metadata_tableinfo_t *t = &m->tables [META_TABLE_FIELD];
guint32 cols [3];
int i;
if (end > t->rows + 1){
fprintf (output, "ERROR index out of range in fields");
exit (1);
}
for (i = start; i < end; i++){
char *sig, *flags;
expand (t, i, cols, CSIZE (cols));
sig = field_signature (m, cols [2]);
flags = field_flags (cols [0]);
if (cols [0] & FIELD_ATTRIBUTE_LITERAL){
char *lit = decode_literal (m, cols [2]);
fprintf (output, " .field %s %s %s = ",
flags, sig,
mono_metadata_string_heap (m, cols [1]));
fprintf (output, "%s\n", lit);
g_free (lit);
} else
fprintf (output, " .field %s %s %s\n",
flags, sig,
mono_metadata_string_heap (m, cols [1]));
g_free (flags);
g_free (sig);
}
}
/**
* dis_field_list:
* @m: metadata context
* @start: starting index into the Method Table.
* @end: ending index into Method table.
*
* This routine displays the methods in the Method Table from @start to @end
*/
static void
dis_method_list (metadata_t *m, guint32 start, guint32 end)
{
}
/**
* dis_type:
* @m: metadata context
* @n: index of type to disassemble
*
* Disassembles the type whose index in the TypeDef table is @n.
*/
static void
dis_type (metadata_t *m, int n)
{
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
guint32 cols [6];
guint32 cols_next [6];
const char *name;
char *tn;
expand (t, n, cols, CSIZE (cols));
expand (t, n + 1, cols_next, CSIZE (cols_next));
name = mono_metadata_string_heap (m, cols [1]);
@ -220,24 +608,43 @@ dis_type (metadata_t *m, metadata_tableinfo_t *t, int n)
tn = "interface";
fprintf (output, " .%s %s%s\n", tn, typedef_flags (cols [0]), name);
fprintf (output, " \textends %s\n", typedef_or_ref (cols [3]));
fprintf (output, " \textends %s\n", typedef_or_ref (m, cols [3]));
fprintf (output, " {\n");
dis_fields (m, cols [4]);
dis_methods (m, cols [5]);
/*
* The value in the table is always valid, we know we have fields
* if the value stored is different than the next record.
*/
if (cols [4] != cols_next [4])
dis_field_list (m, cols [4] - 1, cols_next [4] - 1);
if (cols [4] != cols_next [5])
dis_method_list (m, cols [5], cols_next [5]);
fprintf (output, " }\n");
}
/**
* dis_types:
* @m: metadata context
*
* disassembles all types in the @m context
*/
static void
dis_types (metadata_t *m)
{
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
int i;
for (i = 0; i < t->rows; i++){
dis_type (m, t, i);
}
for (i = 0; i < t->rows; i++)
dis_type (m, i);
}
/**
* disassemble_file:
* @file: file containing CIL code.
*
* Disassembles the @file file.
*/
static void
disassemble_file (const char *file)
{

View File

@ -8,7 +8,9 @@ libmetadata_a_SOURCES = \
assembly.h \
assembly.c \
cil-coff.h \
eltype.h \
endian.h \
fieldattr.h \
metadata.c \
metadata.h \
rawbuffer.c \

View File

@ -0,0 +1,40 @@
#ifndef _MONO_METADATA_ELTYPE_H_
#define _MONO_METADATA_ELTYPE_H_
typedef enum {
ELEMENT_TYPE_END = 0x00, /* End of List */
ELEMENT_TYPE_VOID = 0x01,
ELEMENT_TYPE_BOOLEAN = 0x02,
ELEMENT_TYPE_CHAR = 0x03,
ELEMENT_TYPE_I1 = 0x04,
ELEMENT_TYPE_U1 = 0x05,
ELEMENT_TYPE_I2 = 0x06,
ELEMENT_TYPE_U2 = 0x07,
ELEMENT_TYPE_I4 = 0x08,
ELEMENT_TYPE_U4 = 0x09,
ELEMENT_TYPE_I8 = 0x0a,
ELEMENT_TYPE_U8 = 0x0b,
ELEMENT_TYPE_R4 = 0x0c,
ELEMENT_TYPE_R8 = 0x0d,
ELEMENT_TYPE_STRING = 0x0e,
ELEMENT_TYPE_PTR = 0x0f, /* arg: <type> token */
ELEMENT_TYPE_BYREF = 0x10, /* arg: <type> token */
ELEMENT_TYPE_VALUETYPE = 0x11, /* arg: <type> token */
ELEMENT_TYPE_CLASS = 0x12, /* arg: <type> token */
ELEMENT_TYPE_ARRAY = 0x14, /* type, rank, boundsCount, bound1, loCount, lo1 */
ELEMENT_TYPE_TYPEDBYREF = 0x15,
ELEMENT_TYPE_I = 0x18,
ELEMENT_TYPE_U = 0x19,
ELEMENT_TYPE_FNPTR = 0x1b, /* arg: full method signature */
ELEMENT_TYPE_OBJECT = 0x1c,
ELEMENT_TYPE_SZARRAY = 0x1d, /* 0-based one-dim-array */
ELEMENT_TYPE_CMOD_REQD = 0x1f, /* arg: typedef or typeref token */
ELEMENT_TYPE_CMOD_OPT = 0x20, /* optional arg: typedef or typref token */
ELEMENT_TYPE_INTERNAL = 0x21, /* CLR internal type */
ELEMENT_TYPE_MODIFIER = 0x40, /* Or with the following types */
ELEMENT_TYPE_SENTINEL = 0x41, /* Sentinel for varargs method signature */
ELEMENT_TYPE_PINNED = 0x45, /* Local var that points to pinned object */
} ElementTypeEnum;
#endif /* _MONO_METADATA_ELTYPE_H_ */

View File

@ -0,0 +1,34 @@
#ifndef _MONO_METADATA_FIELDATTR_H_
#define _MONO_METADATA_FIELDATTR_H_
/*
* Flags for bitmasks in the metadata tables
*/
/*
* Field Attributes (21.1.5).
*/
#define FIELD_ATTRIBUTE_FIELD_ACCESS_MASK 0x0007
#define FIELD_ATTRIBUTE_COMPILER_CONTROLLED 0x0000
#define FIELD_ATTRIBUTE_PRIVATE 0x0001
#define FIELD_ATTRIBUTE_FAM_AND_ASSEM 0x0002
#define FIELD_ATTRIBUTE_ASSEMBLY 0x0003
#define FIELD_ATTRIBUTE_FAMILY 0x0004
#define FIELD_ATTRIBUTE_FAM_OR_ASSEM 0x0005
#define FIELD_ATTRIBUTE_PUBLIC 0x0006
#define FIELD_ATTRIBUTE_STATIC 0x0010
#define FIELD_ATTRIBUTE_INIT_ONLY 0x0020
#define FIELD_ATTRIBUTE_LITERAL 0x0040
#define FIELD_ATTRIBUTE_NOT_SERIALIZED 0x0080
#define FIELD_ATTRIBUTE_SPECIAL_NAME 0x0200
#define FIELD_ATTRIBUTE_PINVOKE_IMPL 0x2000
/* For runtime use only */
#define FIELD_ATTRIBUTE_RESERVED_MASK 0x9500
#define FIELD_ATTRIBUTE_RT_SPECIAL_NAME 0x0400
#define FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL 0x1000
#define FIELD_ATTRIBUTE_HAS_DEFAULT 0x8000
#define FIELD_ATTRIBUTE_HAS_FIELD_RVA 0x0100
#endif

View File

@ -604,3 +604,11 @@ mono_metadata_string_heap (metadata_t *meta, guint32 index)
{
return meta->raw_metadata + meta->heap_strings.sh_offset + index;
}
const char *
mono_metadata_blob_heap (metadata_t *meta, guint32 index)
{
return meta->raw_metadata + meta->heap_blob.sh_offset + index;
}

View File

@ -171,3 +171,4 @@ char *mono_metadata_locate (metadata_t *meta, int table, int idx)
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);