mirror of https://github.com/dotnet/runtime
2001-06-27 Miguel de Icaza <miguel@ximian.com>
* main.c: Split code.
svn path=/trunk/mono/; revision=40
Commit migrated from f10919de96
This commit is contained in:
parent
781642bf71
commit
be71b0fcf3
|
@ -3,7 +3,13 @@ INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)
|
|||
bin_PROGRAMS = monodis
|
||||
|
||||
monodis_SOURCES = \
|
||||
get.c \
|
||||
get.h \
|
||||
dis.h \
|
||||
dump.c \
|
||||
dump.h \
|
||||
main.c \
|
||||
meta.h \
|
||||
util.c \
|
||||
util.h
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* dump.c: Dumping routines for the disassembler.
|
||||
*
|
||||
* Author:
|
||||
* Miguel de Icaza (miguel@ximian.com)
|
||||
*
|
||||
* (C) 2001 Ximian, Inc.
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include "meta.h"
|
||||
#include "util.h"
|
||||
#include "dump.h"
|
||||
#include "get.h"
|
||||
|
||||
void
|
||||
dump_table_typeref (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEREF];
|
||||
int i;
|
||||
|
||||
fprintf (output, "Typeref Table\n");
|
||||
|
||||
for (i = 1; i <= t->rows; i++){
|
||||
char *s = get_typeref (m, i);
|
||||
|
||||
fprintf (output, "%d: %s\n", i, s);
|
||||
g_free (s);
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
dump_table_typedef (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
|
||||
int i;
|
||||
|
||||
fprintf (output, "Typedef Table\n");
|
||||
|
||||
for (i = 1; i <= t->rows; i++){
|
||||
char *s = get_typedef (m, i);
|
||||
|
||||
fprintf (output, "%d: %s\n", i, s);
|
||||
g_free (s);
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
dump_table_assemblyref (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_ASSEMBLYREF];
|
||||
int i;
|
||||
|
||||
fprintf (output, "AssemblyRef Table\n");
|
||||
|
||||
for (i = 0; i < t->rows; i++){
|
||||
guint32 cols [9];
|
||||
|
||||
expand (t, i, cols, CSIZE (cols));
|
||||
fprintf (output, "%d: %d.%d.%d.%d %s\n", i,
|
||||
cols [0], cols [1], cols [2], cols [3],
|
||||
mono_metadata_string_heap (m, cols [6]));
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
dump_table_param (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_PARAM];
|
||||
int i;
|
||||
|
||||
fprintf (output, "Param Table\n");
|
||||
|
||||
for (i = 0; i < t->rows; i++){
|
||||
guint32 cols [3];
|
||||
|
||||
expand (t, i, cols, CSIZE (cols));
|
||||
fprintf (output, "%d: 0x%04x %d %s\n",
|
||||
i,
|
||||
cols [0], cols [1],
|
||||
mono_metadata_string_heap (m, cols [2]));
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
extern FILE *output;
|
||||
|
||||
void dump_table_typeref (metadata_t *m);
|
||||
void dump_table_typedef (metadata_t *m);
|
||||
void dump_table_assemblyref (metadata_t *m);
|
||||
void dump_table_param (metadata_t *m);
|
|
@ -0,0 +1,569 @@
|
|||
/*
|
||||
* get.c: Functions to get stringified values from the metadata tables.
|
||||
*
|
||||
* Author:
|
||||
* Miguel de Icaza (miguel@ximian.com)
|
||||
*
|
||||
* (C) 2001 Ximian, Inc.
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include "meta.h"
|
||||
#include "util.h"
|
||||
#include "get.h"
|
||||
|
||||
/**
|
||||
* expand:
|
||||
* @t: table to extract information from.
|
||||
* @idx: index in table.
|
||||
* @res: array of @res_size cols to store the results in
|
||||
*
|
||||
* This decompresses the metadata element @idx in table @t
|
||||
* into the guint32 @res array that has res_size elements
|
||||
*/
|
||||
void
|
||||
expand (metadata_tableinfo_t *t, int idx, guint32 *res, int res_size)
|
||||
|
||||
{
|
||||
guint32 bitfield = t->size_bitfield;
|
||||
int i, count = meta_table_count (bitfield);
|
||||
char *data = t->base + idx * t->row_size;
|
||||
|
||||
g_assert (res_size == count);
|
||||
|
||||
for (i = 0; i < count; i++){
|
||||
int n = meta_table_size (bitfield, i);
|
||||
|
||||
switch (n){
|
||||
case 1:
|
||||
res [i] = *data; break;
|
||||
case 2:
|
||||
res [i] = read16 (data); break;
|
||||
|
||||
case 4:
|
||||
res [i] = read32 (data); break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
data += n;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
char *
|
||||
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]));
|
||||
}
|
||||
|
||||
char *
|
||||
get_module (metadata_t *m, int idx)
|
||||
{
|
||||
guint32 cols [5];
|
||||
|
||||
/*
|
||||
* There MUST BE only one module in the Module table
|
||||
*/
|
||||
g_assert (idx == 1);
|
||||
|
||||
expand (&m->tables [META_TABLE_MODULEREF], idx - 1, cols, CSIZE (cols));
|
||||
|
||||
return g_strdup (mono_metadata_string_heap (m, cols [6]));
|
||||
}
|
||||
|
||||
char *
|
||||
get_assemblyref (metadata_t *m, int idx)
|
||||
{
|
||||
guint32 cols [9];
|
||||
|
||||
expand (&m->tables [META_TABLE_ASSEMBLYREF], idx - 1, cols, CSIZE (cols));
|
||||
|
||||
return g_strdup (mono_metadata_string_heap (m, cols [6]));
|
||||
}
|
||||
|
||||
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] >> 2;
|
||||
/*
|
||||
* Two bits in Beta2.
|
||||
* ECMA spec claims 3 bits
|
||||
*/
|
||||
table = cols [0] & 3;
|
||||
|
||||
switch (table){
|
||||
case 0: /* Module */
|
||||
x = get_module (m, rs_idx);
|
||||
ret = g_strdup_printf ("TODO:TypeRef-Module [%s] %s.%s", x, s, t);
|
||||
g_free (x);
|
||||
break;
|
||||
|
||||
case 1: /* ModuleRef */
|
||||
ret = g_strdup_printf ("TODO:TypeRef-ModuleRef (%s.%s)", s, t);
|
||||
break;
|
||||
|
||||
case 2: /*
|
||||
* AssemblyRef (ECMA docs claim it is 3, but it looks to
|
||||
* me like it is 2 (tokens are prefixed with 0x23)
|
||||
*/
|
||||
x = get_assemblyref (m, rs_idx);
|
||||
ret = g_strdup_printf ("[%s] %s.%s", x, s, t);
|
||||
g_free (x);
|
||||
break;
|
||||
|
||||
case 4: /* TypeRef */
|
||||
ret = g_strdup_printf ("TODO:TypeRef-TypeRef: TYPEREF! (%s.%s)", s, t);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = g_strdup_printf ("Unknown table in TypeRef %d", table);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_typedef_or_ref:
|
||||
* @m: metadata context
|
||||
* @dor_token: def or ref encoded index
|
||||
*
|
||||
* Low two bits contain table to lookup from
|
||||
* high bits contain the index into the def or ref table
|
||||
*
|
||||
* Returns: a stringified version of the MethodDef or MethodRef
|
||||
* at (dor_token >> 2)
|
||||
*/
|
||||
char *
|
||||
get_typedef_or_ref (metadata_t *m, guint32 dor_token)
|
||||
{
|
||||
char *temp = NULL, *s;
|
||||
int table, idx;
|
||||
|
||||
/*
|
||||
* low 2 bits contain encoding
|
||||
*/
|
||||
table = dor_token & 0x03;
|
||||
idx = dor_token >> 2;
|
||||
|
||||
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 ("%s", temp);
|
||||
break;
|
||||
|
||||
case 2: /* TypeSpec */
|
||||
s = g_strdup_printf ("TODO-TypeSpec: 0x%08x", idx);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_error ("Unhandled encoding for typedef-or-ref coded index");
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
const char *
|
||||
get_encoded_typedef_or_ref (metadata_t *m, const char *ptr, char **result)
|
||||
{
|
||||
guint32 token;
|
||||
|
||||
ptr = get_encoded_value (ptr, &token);
|
||||
|
||||
*result = get_typedef_or_ref (m, token);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_custom_mod:
|
||||
*
|
||||
* Decodes a CustomMod (22.2.7)
|
||||
*
|
||||
* Returns: updated pointer location
|
||||
*/
|
||||
const char *
|
||||
get_custom_mod (metadata_t *m, const char *ptr, char **return_value)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if ((*ptr == ELEMENT_TYPE_CMOD_OPT) ||
|
||||
(*ptr == ELEMENT_TYPE_CMOD_REQD)){
|
||||
ptr++;
|
||||
ptr = get_encoded_typedef_or_ref (m, ptr, &s);
|
||||
|
||||
*return_value = g_strconcat ("CMOD ", s, NULL);
|
||||
g_free (s);
|
||||
} else
|
||||
*return_value = NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
static map_t element_type_map [] = {
|
||||
{ ELEMENT_TYPE_END , "end" },
|
||||
{ ELEMENT_TYPE_VOID , "void" },
|
||||
{ ELEMENT_TYPE_BOOLEAN , "bool" },
|
||||
{ ELEMENT_TYPE_CHAR , "char" },
|
||||
{ ELEMENT_TYPE_I1 , "sbyte" },
|
||||
{ ELEMENT_TYPE_U1 , "byte" },
|
||||
{ ELEMENT_TYPE_I2 , "int16" },
|
||||
{ ELEMENT_TYPE_U2 , "uint16" },
|
||||
{ ELEMENT_TYPE_I4 , "int32" },
|
||||
{ ELEMENT_TYPE_U4 , "uint32" },
|
||||
{ ELEMENT_TYPE_I8 , "int64" },
|
||||
{ ELEMENT_TYPE_U8 , "uint64" },
|
||||
{ ELEMENT_TYPE_R4 , "float32" },
|
||||
{ ELEMENT_TYPE_R8 , "float64" },
|
||||
{ ELEMENT_TYPE_STRING , "string" },
|
||||
{ ELEMENT_TYPE_TYPEDBYREF , "TypedByRef" },
|
||||
{ ELEMENT_TYPE_I , "native int" },
|
||||
{ ELEMENT_TYPE_U , "native unsigned int" },
|
||||
{ ELEMENT_TYPE_OBJECT , "object" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* (22.2.12)
|
||||
*
|
||||
* Returns: the new ptr to continue decoding
|
||||
*/
|
||||
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_SZARRAY: {
|
||||
char *child_type;
|
||||
|
||||
ptr = get_type (m, ptr, &child_type);
|
||||
*result = g_strdup_printf ("%s[]", child_type);
|
||||
g_free (child_type);
|
||||
break;
|
||||
}
|
||||
|
||||
case ELEMENT_TYPE_ARRAY:
|
||||
|
||||
*result = g_strdup ("ARRAY:TODO");
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a stringified representation of a FieldSig (22.2.4)
|
||||
*/
|
||||
char *
|
||||
get_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;
|
||||
char *res;
|
||||
int len;
|
||||
|
||||
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 (m, ptr, &allocated_modifier_string);
|
||||
ptr = get_type (m, ptr, &allocated_type_string);
|
||||
|
||||
res = g_strdup_printf (
|
||||
"%s %s",
|
||||
allocated_modifier_string ? allocated_modifier_string : "",
|
||||
allocated_type_string);
|
||||
|
||||
if (allocated_modifier_string)
|
||||
g_free (allocated_modifier_string);
|
||||
if (allocated_type_string)
|
||||
g_free (allocated_modifier_string);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* decode_literal:
|
||||
* @m: metadata context
|
||||
* @token: token to decode
|
||||
*
|
||||
* decodes the literal indexed by @token.
|
||||
*/
|
||||
char *
|
||||
decode_literal (metadata_t *m, guint32 token)
|
||||
{
|
||||
return g_strdup ("LITERAL_VALUE");
|
||||
}
|
||||
|
||||
/**
|
||||
* get_ret_type:
|
||||
* @m: metadata context
|
||||
* @ptr: location to decode from.
|
||||
* @result: pointer to string where resulting decoded string is stored
|
||||
*
|
||||
* This routine returns in @result the stringified RetType (22.2.11)
|
||||
*
|
||||
* Returns: the new ptr to continue decoding.
|
||||
*/
|
||||
const char *
|
||||
get_ret_type (metadata_t *m, const char *ptr, char **ret_type)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
char *mod = NULL;
|
||||
char *allocated_type_string;
|
||||
|
||||
ptr = get_custom_mod (m, ptr, &mod);
|
||||
if (mod){
|
||||
g_string_append (str, mod);
|
||||
g_string_append_c (str, ' ');
|
||||
g_free (mod);
|
||||
}
|
||||
|
||||
if (*ptr == ELEMENT_TYPE_TYPEDBYREF){
|
||||
/* TODO: what does `typedbyref' mean? */
|
||||
g_string_append (str, "/* FIXME: What does this mean? */ typedbyref ");
|
||||
ptr++;
|
||||
} else if (*ptr == ELEMENT_TYPE_VOID){
|
||||
g_string_append (str, "void");
|
||||
ptr++;
|
||||
} else {
|
||||
if (*ptr == ELEMENT_TYPE_BYREF){
|
||||
g_string_append (str, "[out] ");
|
||||
ptr++;
|
||||
}
|
||||
|
||||
ptr = get_type (m, ptr, &allocated_type_string);
|
||||
g_string_append (str, allocated_type_string);
|
||||
g_free (allocated_type_string);
|
||||
}
|
||||
|
||||
*ret_type = str->str;
|
||||
g_string_free (str, FALSE);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_param:
|
||||
* @m: metadata context
|
||||
* @ptr: location to decode from.
|
||||
* @result: pointer to string where resulting decoded string is stored
|
||||
*
|
||||
* This routine returns in @result the stringified Param (22.2.10)
|
||||
*
|
||||
* Returns: the new ptr to continue decoding.
|
||||
*/
|
||||
const char *
|
||||
get_param (metadata_t *m, const char *ptr, char **retval)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
char *allocated_mod_string, *allocated_type_string;
|
||||
|
||||
ptr = get_custom_mod (m, ptr, &allocated_mod_string);
|
||||
if (allocated_mod_string){
|
||||
g_string_append (str, allocated_mod_string);
|
||||
g_string_append_c (str, ' ');
|
||||
g_free (allocated_mod_string);
|
||||
}
|
||||
|
||||
if (*ptr == ELEMENT_TYPE_TYPEDBYREF){
|
||||
g_string_append (str, "/*FIXME: what does typedbyref mean? */ typedbyref ");
|
||||
ptr++;
|
||||
} else {
|
||||
if (*ptr == ELEMENT_TYPE_BYREF){
|
||||
g_string_append (str, "[out] ");
|
||||
ptr++;
|
||||
}
|
||||
ptr = get_type (m, ptr, &allocated_type_string);
|
||||
g_string_append (str, allocated_type_string);
|
||||
g_free (allocated_type_string);
|
||||
}
|
||||
|
||||
*retval = str->str;
|
||||
g_string_free (str, FALSE);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static map_t param_map [] = {
|
||||
{ PARAM_ATTRIBUTE_IN, "[in] " },
|
||||
{ PARAM_ATTRIBUTE_OUT, "[out] " },
|
||||
{ PARAM_ATTRIBUTE_OPTIONAL, "optional " },
|
||||
{ PARAM_ATTRIBUTE_HAS_DEFAULT, "hasdefault " },
|
||||
{ PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL, "fieldmarshal " },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
char *
|
||||
param_flags (guint32 f)
|
||||
{
|
||||
return g_strdup (flags (f, param_map));
|
||||
}
|
||||
|
||||
static map_t field_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 }
|
||||
};
|
||||
|
||||
/**
|
||||
* field_flags:
|
||||
*
|
||||
* Returns a stringified version of a Field's flags
|
||||
*/
|
||||
char *
|
||||
field_flags (guint32 f)
|
||||
{
|
||||
static char buffer [1024];
|
||||
int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
|
||||
|
||||
buffer [0] = 0;
|
||||
|
||||
strcat (buffer, map (access, field_access_map));
|
||||
strcat (buffer, flags (f, field_flags_map));
|
||||
return g_strdup (buffer);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
/*
|
||||
* These return allocated strings
|
||||
*/
|
||||
char *get_typedef (metadata_t *m, int idx);
|
||||
char *get_module (metadata_t *m, int idx);
|
||||
char *get_assemblyref (metadata_t *m, int idx);
|
||||
char *get_typeref (metadata_t *m, int idx);
|
||||
char *get_typedef_or_ref (metadata_t *m, guint32 dor_token);
|
||||
char *get_field_signature (metadata_t *m, guint32 blob_signature);
|
||||
char *decode_literal (metadata_t *m, guint32 token);
|
||||
char *param_flags (guint32 f);
|
||||
char *field_flags (guint32 f);
|
||||
|
||||
/*
|
||||
* These functions are used during the decoding of streams in the
|
||||
* metadata heaps (a simple parsing).
|
||||
*
|
||||
* They return the `next' location to continue parsing from (ptr is
|
||||
* the starting location).
|
||||
*
|
||||
* Results are returning in the pointer argument.
|
||||
*/
|
||||
const char *get_encoded_typedef_or_ref (metadata_t *m, const char *ptr,
|
||||
char **result);
|
||||
const char *get_encoded_value (const char *_ptr,
|
||||
guint32 *len);
|
||||
const char *get_custom_mod (metadata_t *m, const char *ptr,
|
||||
char **return_value);
|
||||
const char *get_type (metadata_t *m, const char *ptr,
|
||||
char **result);
|
||||
const char *get_ret_type (metadata_t *m, const char *ptr,
|
||||
char **ret_type);
|
||||
const char *get_param (metadata_t *m, const char *ptr,
|
||||
char **retval);
|
||||
|
||||
void expand (metadata_tableinfo_t *t, int idx, guint32 *res, int res_size);
|
|
@ -16,16 +16,10 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <mono/metadata/assembly.h>
|
||||
#include <mono/metadata/cil-coff.h>
|
||||
#include <mono/metadata/endian.h>
|
||||
#include <mono/metadata/typeattr.h>
|
||||
#include <mono/metadata/fieldattr.h>
|
||||
#include <mono/metadata/methodattr.h>
|
||||
#include <mono/metadata/eltype.h>
|
||||
#include <mono/metadata/blobsig.h>
|
||||
#include <mono/metadata/paramattr.h>
|
||||
#include "meta.h"
|
||||
#include "util.h"
|
||||
#include "dump.h"
|
||||
#include "get.h"
|
||||
|
||||
FILE *output;
|
||||
|
||||
|
@ -45,35 +39,6 @@ dump_header_data (MonoAssembly *ass)
|
|||
"// Copyright (C) 2001 Ximian, Inc.\n\n");
|
||||
}
|
||||
|
||||
#define CSIZE(x) (sizeof (x) / 4)
|
||||
static void
|
||||
expand (metadata_tableinfo_t *t, int idx, guint32 *res, int res_size)
|
||||
{
|
||||
guint32 bitfield = t->size_bitfield;
|
||||
int i, count = meta_table_count (bitfield);
|
||||
char *data = t->base + idx * t->row_size;
|
||||
|
||||
g_assert (res_size == count);
|
||||
|
||||
for (i = 0; i < count; i++){
|
||||
int n = meta_table_size (bitfield, i);
|
||||
|
||||
switch (n){
|
||||
case 1:
|
||||
res [i] = *data; break;
|
||||
case 2:
|
||||
res [i] = read16 (data); break;
|
||||
|
||||
case 4:
|
||||
res [i] = read32 (data); break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
data += n;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dis_directive_assembly (metadata_t *m)
|
||||
{
|
||||
|
@ -183,405 +148,6 @@ typedef_flags (guint32 flags)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
static map_t field_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 , "void" },
|
||||
{ ELEMENT_TYPE_BOOLEAN , "bool" },
|
||||
{ ELEMENT_TYPE_CHAR , "char" },
|
||||
{ ELEMENT_TYPE_I1 , "sbyte" },
|
||||
{ ELEMENT_TYPE_U1 , "byte" },
|
||||
{ ELEMENT_TYPE_I2 , "int16" },
|
||||
{ ELEMENT_TYPE_U2 , "uint16" },
|
||||
{ ELEMENT_TYPE_I4 , "int32" },
|
||||
{ ELEMENT_TYPE_U4 , "uint32" },
|
||||
{ ELEMENT_TYPE_I8 , "int64" },
|
||||
{ ELEMENT_TYPE_U8 , "uint64" },
|
||||
{ ELEMENT_TYPE_R4 , "float32" },
|
||||
{ ELEMENT_TYPE_R8 , "float64" },
|
||||
{ ELEMENT_TYPE_STRING , "string" },
|
||||
{ ELEMENT_TYPE_TYPEDBYREF , "TypedByRef" },
|
||||
{ ELEMENT_TYPE_I , "native int" },
|
||||
{ ELEMENT_TYPE_U , "native unsigned int" },
|
||||
{ ELEMENT_TYPE_OBJECT , "object" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* field_flags:
|
||||
*
|
||||
* Returns a stringified version of a Field's flags
|
||||
*/
|
||||
static char *
|
||||
field_flags (guint32 f)
|
||||
{
|
||||
static char buffer [1024];
|
||||
int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
|
||||
|
||||
buffer [0] = 0;
|
||||
|
||||
strcat (buffer, map (access, field_access_map));
|
||||
strcat (buffer, flags (f, field_flags_map));
|
||||
return g_strdup (buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
static char *
|
||||
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 [5];
|
||||
|
||||
/*
|
||||
* There MUST BE only one module in the Module table
|
||||
*/
|
||||
g_assert (idx == 1);
|
||||
|
||||
expand (&m->tables [META_TABLE_MODULEREF], idx - 1, cols, CSIZE (cols));
|
||||
|
||||
return g_strdup (mono_metadata_string_heap (m, cols [6]));
|
||||
}
|
||||
|
||||
static char *
|
||||
get_assemblyref (metadata_t *m, int idx)
|
||||
{
|
||||
guint32 cols [9];
|
||||
|
||||
expand (&m->tables [META_TABLE_ASSEMBLYREF], idx - 1, 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] >> 2;
|
||||
/*
|
||||
* Two bits in Beta2.
|
||||
* ECMA spec claims 3 bits
|
||||
*/
|
||||
table = cols [0] & 3;
|
||||
|
||||
switch (table){
|
||||
case 0: /* Module */
|
||||
x = get_module (m, rs_idx);
|
||||
ret = g_strdup_printf ("TODO:TypeRef-Module [%s] %s.%s", x, s, t);
|
||||
g_free (x);
|
||||
break;
|
||||
|
||||
case 1: /* ModuleRef */
|
||||
ret = g_strdup_printf ("TODO:TypeRef-ModuleRef (%s.%s)", s, t);
|
||||
break;
|
||||
|
||||
case 2: /*
|
||||
* AssemblyRef (ECMA docs claim it is 3, but it looks to
|
||||
* me like it is 2 (tokens are prefixed with 0x23)
|
||||
*/
|
||||
x = get_assemblyref (m, rs_idx);
|
||||
ret = g_strdup_printf ("[%s] %s.%s", x, s, t);
|
||||
g_free (x);
|
||||
break;
|
||||
|
||||
case 4: /* TypeRef */
|
||||
ret = g_strdup_printf ("TODO:TypeRef-TypeRef: TYPEREF! (%s.%s)", s, t);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = g_strdup_printf ("Unknown table in TypeRef %d", table);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_typedef_or_ref (metadata_t *m, guint32 dor_token)
|
||||
{
|
||||
char *temp = NULL, *s;
|
||||
int table, idx;
|
||||
|
||||
/*
|
||||
* low 2 bits contain encoding
|
||||
*/
|
||||
table = dor_token & 0x03;
|
||||
idx = dor_token >> 2;
|
||||
|
||||
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 ("%s", temp);
|
||||
break;
|
||||
|
||||
case 2: /* TypeSpec */
|
||||
s = g_strdup_printf ("TODO-TypeSpec: 0x%08x", idx);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_error ("Unhandled encoding for typedef-or-ref coded index");
|
||||
|
||||
}
|
||||
|
||||
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 = get_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_custom_mod:
|
||||
*
|
||||
* Decodes a CustomMod (22.2.7)
|
||||
*
|
||||
* Returns: updated pointer location
|
||||
*/
|
||||
static const char *
|
||||
get_custom_mod (metadata_t *m, const char *ptr, char **return_value)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if ((*ptr == ELEMENT_TYPE_CMOD_OPT) ||
|
||||
(*ptr == ELEMENT_TYPE_CMOD_REQD)){
|
||||
ptr++;
|
||||
ptr = get_encoded_typedef_or_ref (m, ptr, &s);
|
||||
|
||||
*return_value = g_strconcat ("CMOD ", s, NULL);
|
||||
g_free (s);
|
||||
} else
|
||||
*return_value = NULL;
|
||||
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.
|
||||
* (22.2.12)
|
||||
*
|
||||
* 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_SZARRAY: {
|
||||
char *child_type;
|
||||
|
||||
ptr = get_type (m, ptr, &child_type);
|
||||
*result = g_strdup_printf ("%s[]", child_type);
|
||||
g_free (child_type);
|
||||
break;
|
||||
}
|
||||
|
||||
case ELEMENT_TYPE_ARRAY:
|
||||
|
||||
*result = g_strdup ("ARRAY: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;
|
||||
char *res;
|
||||
int len;
|
||||
|
||||
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 (m, ptr, &allocated_modifier_string);
|
||||
ptr = get_type (m, ptr, &allocated_type_string);
|
||||
|
||||
res = g_strdup_printf (
|
||||
"%s %s",
|
||||
allocated_modifier_string ? allocated_modifier_string : "",
|
||||
allocated_type_string);
|
||||
|
||||
if (allocated_modifier_string)
|
||||
g_free (allocated_modifier_string);
|
||||
if (allocated_type_string)
|
||||
g_free (allocated_modifier_string);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -606,7 +172,7 @@ dis_field_list (metadata_t *m, guint32 start, guint32 end)
|
|||
char *sig, *flags;
|
||||
|
||||
expand (t, i, cols, CSIZE (cols));
|
||||
sig = field_signature (m, cols [2]);
|
||||
sig = get_field_signature (m, cols [2]);
|
||||
flags = field_flags (cols [0]);
|
||||
|
||||
if (cols [0] & FIELD_ATTRIBUTE_LITERAL){
|
||||
|
@ -714,83 +280,15 @@ method_impl_flags (guint32 f)
|
|||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_ret_type:
|
||||
* @m: metadata context
|
||||
* @ptr: location to decode from.
|
||||
* @result: pointer to string where resulting decoded string is stored
|
||||
*
|
||||
* This routine returns in @result the stringified RetType (22.2.11)
|
||||
*
|
||||
* Returns: the new ptr to continue decoding.
|
||||
*/
|
||||
static const char *
|
||||
get_ret_type (metadata_t *m, const char *ptr, char **ret_type)
|
||||
static void
|
||||
dis_code (metadata_t *m, cli_image_info_t *ii, guint32 rva)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
char *mod = NULL;
|
||||
char *allocated_type_string;
|
||||
const char *ptr = cli_rva_map (ii, rva);
|
||||
|
||||
if (rva == 0)
|
||||
return;
|
||||
|
||||
ptr = get_custom_mod (m, ptr, &mod);
|
||||
if (mod){
|
||||
g_string_append (str, mod);
|
||||
g_string_append_c (str, ' ');
|
||||
g_free (mod);
|
||||
}
|
||||
|
||||
if (*ptr == ELEMENT_TYPE_TYPEDBYREF){
|
||||
/* TODO: what does `typedbyref' mean? */
|
||||
g_string_append (str, "/* FIXME: What does this mean? */ typedbyref ");
|
||||
ptr++;
|
||||
} else if (*ptr == ELEMENT_TYPE_VOID){
|
||||
g_string_append (str, "void");
|
||||
ptr++;
|
||||
} else {
|
||||
if (*ptr == ELEMENT_TYPE_BYREF){
|
||||
g_string_append (str, "[out] ");
|
||||
ptr++;
|
||||
}
|
||||
|
||||
ptr = get_type (m, ptr, &allocated_type_string);
|
||||
g_string_append (str, allocated_type_string);
|
||||
g_free (allocated_type_string);
|
||||
}
|
||||
|
||||
*ret_type = str->str;
|
||||
g_string_free (str, FALSE);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_param (metadata_t *m, const char *ptr, char **retval)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
char *allocated_mod_string, *allocated_type_string;
|
||||
|
||||
ptr = get_custom_mod (m, ptr, &allocated_mod_string);
|
||||
if (allocated_mod_string){
|
||||
g_string_append (str, allocated_mod_string);
|
||||
g_string_append_c (str, ' ');
|
||||
g_free (allocated_mod_string);
|
||||
}
|
||||
|
||||
if (*ptr == ELEMENT_TYPE_TYPEDBYREF){
|
||||
g_string_append (str, "/*FIXME: what does typedbyref mean? */ typedbyref ");
|
||||
ptr++;
|
||||
} else {
|
||||
if (*ptr == ELEMENT_TYPE_BYREF){
|
||||
g_string_append (str, "[out] ");
|
||||
ptr++;
|
||||
}
|
||||
ptr = get_type (m, ptr, &allocated_type_string);
|
||||
g_string_append (str, allocated_type_string);
|
||||
g_free (allocated_type_string);
|
||||
}
|
||||
|
||||
*retval = str->str;
|
||||
g_string_free (str, FALSE);
|
||||
return ptr;
|
||||
hex_dump (ptr, 0, 64);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -800,6 +298,16 @@ typedef struct {
|
|||
char **param;
|
||||
} MethodSignature;
|
||||
|
||||
/**
|
||||
* parse_method_signature:
|
||||
* @m: metadata context
|
||||
* @blob_signature: pointer to the signature in the Blob heap
|
||||
*
|
||||
* 22.2.1: MethodDefSig.
|
||||
*
|
||||
* Returns the parsed information in the MethodSignature structure
|
||||
* needs to be deallocated with free_method_signature().
|
||||
*/
|
||||
static MethodSignature *
|
||||
parse_method_signature (metadata_t *m, guint32 blob_signature)
|
||||
{
|
||||
|
@ -840,21 +348,6 @@ free_method_signature (MethodSignature *ms)
|
|||
g_free (ms);
|
||||
}
|
||||
|
||||
static map_t param_map [] = {
|
||||
{ PARAM_ATTRIBUTE_IN, "[in] " },
|
||||
{ PARAM_ATTRIBUTE_OUT, "[out] " },
|
||||
{ PARAM_ATTRIBUTE_OPTIONAL, "optional " },
|
||||
{ PARAM_ATTRIBUTE_HAS_DEFAULT, "hasdefault " },
|
||||
{ PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL, "fieldmarshal " },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static char *
|
||||
param_flags (guint32 f)
|
||||
{
|
||||
return g_strdup (map (f, param_map));
|
||||
}
|
||||
|
||||
/**
|
||||
* dis_field_list:
|
||||
* @m: metadata context
|
||||
|
@ -864,7 +357,7 @@ param_flags (guint32 f)
|
|||
* 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_method_list (metadata_t *m, cli_image_info_t *ii, guint32 start, guint32 end)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_METHOD];
|
||||
metadata_tableinfo_t *p = &m->tables [META_TABLE_PARAM];
|
||||
|
@ -921,7 +414,7 @@ dis_method_list (metadata_t *m, guint32 start, guint32 end)
|
|||
|
||||
fprintf (output, " {\n");
|
||||
fprintf (output, " // Method begins at RVA 0x%x\n", cols [0]);
|
||||
fprintf (output, " // Param: %d %d (%d)\n", cols [5], cols_next [5], ms->param_count);
|
||||
dis_code (m, ii, cols [0]);
|
||||
fprintf (output, " }\n\n");
|
||||
free_method_signature (ms);
|
||||
}
|
||||
|
@ -935,7 +428,7 @@ dis_method_list (metadata_t *m, guint32 start, guint32 end)
|
|||
* Disassembles the type whose index in the TypeDef table is @n.
|
||||
*/
|
||||
static void
|
||||
dis_type (metadata_t *m, int n)
|
||||
dis_type (metadata_t *m, cli_image_info_t *ii, int n)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
|
||||
guint32 cols [6];
|
||||
|
@ -966,84 +459,11 @@ dis_type (metadata_t *m, int n)
|
|||
dis_field_list (m, cols [4] - 1, cols_next [4] - 1);
|
||||
fprintf (output, "\n");
|
||||
if (cols [4] != cols_next [5])
|
||||
dis_method_list (m, cols [5] - 1, cols_next [5] - 1);
|
||||
dis_method_list (m, ii, cols [5] - 1, cols_next [5] - 1);
|
||||
|
||||
fprintf (output, " }\n}\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_table_typeref (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEREF];
|
||||
int i;
|
||||
|
||||
fprintf (output, "Typeref Table\n");
|
||||
|
||||
for (i = 1; i <= t->rows; i++){
|
||||
char *s = get_typeref (m, i);
|
||||
|
||||
fprintf (output, "%d: %s\n", i, s);
|
||||
g_free (s);
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_table_typedef (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
|
||||
int i;
|
||||
|
||||
fprintf (output, "Typedef Table\n");
|
||||
|
||||
for (i = 1; i <= t->rows; i++){
|
||||
char *s = get_typedef (m, i);
|
||||
|
||||
fprintf (output, "%d: %s\n", i, s);
|
||||
g_free (s);
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_table_assemblyref (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_ASSEMBLYREF];
|
||||
int i;
|
||||
|
||||
fprintf (output, "AssemblyRef Table\n");
|
||||
|
||||
for (i = 0; i < t->rows; i++){
|
||||
guint32 cols [9];
|
||||
|
||||
expand (t, i, cols, CSIZE (cols));
|
||||
fprintf (output, "%d: %d.%d.%d.%d %s\n", i,
|
||||
cols [0], cols [1], cols [2], cols [3],
|
||||
mono_metadata_string_heap (m, cols [6]));
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_table_param (metadata_t *m)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_PARAM];
|
||||
int i;
|
||||
|
||||
fprintf (output, "Param Table\n");
|
||||
|
||||
for (i = 0; i < t->rows; i++){
|
||||
guint32 cols [3];
|
||||
|
||||
expand (t, i, cols, CSIZE (cols));
|
||||
fprintf (output, "%d: 0x%04x %d %s\n",
|
||||
i,
|
||||
cols [0], cols [1],
|
||||
mono_metadata_string_heap (m, cols [2]));
|
||||
}
|
||||
fprintf (output, "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* dis_types:
|
||||
* @m: metadata context
|
||||
|
@ -1051,13 +471,13 @@ dump_table_param (metadata_t *m)
|
|||
* disassembles all types in the @m context
|
||||
*/
|
||||
static void
|
||||
dis_types (metadata_t *m)
|
||||
dis_types (metadata_t *m, cli_image_info_t *ii)
|
||||
{
|
||||
metadata_tableinfo_t *t = &m->tables [META_TABLE_TYPEDEF];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < t->rows; i++)
|
||||
dis_type (m, i);
|
||||
dis_type (m, ii, i);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1106,7 +526,7 @@ disassemble_file (const char *file)
|
|||
|
||||
dis_directive_assemblyref (m);
|
||||
dis_directive_assembly (m);
|
||||
dis_types (m);
|
||||
dis_types (m, ii);
|
||||
}
|
||||
|
||||
mono_assembly_close (ass);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#include <mono/metadata/assembly.h>
|
||||
#include <mono/metadata/cil-coff.h>
|
||||
#include <mono/metadata/endian.h>
|
||||
#include <mono/metadata/typeattr.h>
|
||||
#include <mono/metadata/fieldattr.h>
|
||||
#include <mono/metadata/methodattr.h>
|
||||
#include <mono/metadata/eltype.h>
|
||||
#include <mono/metadata/blobsig.h>
|
||||
#include <mono/metadata/paramattr.h>
|
|
@ -79,3 +79,4 @@ hex_dump (const char *buffer, int base, int count)
|
|||
}
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,3 +8,4 @@ const char *map (guint32 code, map_t *table);
|
|||
const char *flags (guint32 code, map_t *table);
|
||||
void hex_dump (const char *buffer, int base, int count);
|
||||
|
||||
#define CSIZE(x) (sizeof (x) / 4)
|
||||
|
|
Loading…
Reference in New Issue