* debug.h (MonoDebugFormat): Added MONO_DEBUG_FORMAT_DWARF2_PLUS.
* debug-dwarf2-plus.c: This debugging format reads a symbol file which has
been created by MCS and fills in all machine dependent stuff.
* debug-private.h (DebugMethodInfo): Added `MonoDebugMethodInfo method_info',
removed everything which is already in MonoDebugMethodInfo.
* debug.c (debug_generate_method_lines): Generate the MonoILOffsetInfo array.
(mono_debug_make_symbols): Don't open the file or call as, this is done in the
backend code.
* jit.c (main): Added "--dwarf-plus" command line option to use the new
MONO_DEBUG_FORMAT_DWARF2_PLUS debugging format.
svn path=/trunk/mono/; revision=3260
+2002-03-21 Martin Baulig <martin@gnome.org>
+
+ * debug.h (MonoDebugFormat): Added MONO_DEBUG_FORMAT_DWARF2_PLUS.
+
+ * debug-dwarf2-plus.c: This debugging format reads a symbol file which has
+ been created by MCS and fills in all machine dependent stuff.
+
+ * debug-private.h (DebugMethodInfo): Added `MonoDebugMethodInfo method_info',
+ removed everything which is already in MonoDebugMethodInfo.
+
+ * debug.c (debug_generate_method_lines): Generate the MonoILOffsetInfo array.
+ (mono_debug_make_symbols): Don't open the file or call as, this is done in the
+ backend code.
+
+ * jit.c (main): Added "--dwarf-plus" command line option to use the new
+ MONO_DEBUG_FORMAT_DWARF2_PLUS debugging format.
+
2002-03-21 Dietmar Maurer <dietmar@ximian.com>
* jit.c (usage): new option to specify maximum number of worker threads
debug.c \
debug-stabs.c \
debug-dwarf2.c \
+ debug-dwarf2-plus.c \
jit.c \
trampoline.c \
delegate.c \
--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+#include <mono/metadata/class.h>
+#include <mono/metadata/debug-symfile.h>
+#include <mono/jit/codegen.h>
+#include <mono/jit/debug.h>
+
+#include "debug-private.h"
+
+void
+mono_debug_open_assembly_dwarf2_plus (AssemblyDebugInfo *info)
+{
+}
+
+void
+mono_debug_close_assembly_dwarf2_plus (AssemblyDebugInfo *info)
+{
+}
+
+static MonoDebugMethodInfo *
+method_info_func (MonoDebugSymbolFile *symfile, guint32 token, gpointer user_data)
+{
+ AssemblyDebugInfo *info = user_data;
+ MonoMethod *method;
+ DebugMethodInfo *minfo;
+
+ method = g_hash_table_lookup (info->image->method_cache, GINT_TO_POINTER (token));
+ if (!method)
+ return NULL;
+
+ minfo = g_hash_table_lookup (info->methods, method);
+
+ return (MonoDebugMethodInfo *) minfo;
+}
+
+void
+mono_debug_write_assembly_dwarf2_plus (AssemblyDebugInfo *info)
+{
+ MonoDebugSymbolFile *symfile;
+
+ symfile = mono_debug_open_symbol_file (info->image, info->filename, TRUE);
+ if (!symfile)
+ return;
+
+ mono_debug_update_symbol_file (symfile, method_info_func, info);
+
+ mono_debug_close_symbol_file (symfile);
+}
// Start of statement program
dwarf2_write_dw_lns_advance_line (info->f, minfo->start_line - 1);
- dwarf2_write_dw_lne_set_address (info->f, minfo->code_start);
+ dwarf2_write_dw_lne_set_address (info->f, minfo->method_info.code_start);
dwarf2_write_dw_lns_negate_stmt (info->f);
dwarf2_write_dw_lns_copy (info->f);
st_line = minfo->start_line;
- st_address = minfo->code_start;
+ st_address = minfo->method_info.code_start;
for (i = 1; i < minfo->line_numbers->len; i++) {
DebugLineNumberInfo *lni = g_ptr_array_index (minfo->line_numbers, i);
st_address += addr_inc;
}
- dwarf2_write_dw_lne_set_address (info->f, minfo->code_start + minfo->code_size);
+ dwarf2_write_dw_lne_set_address (info->f,
+ minfo->method_info.code_start +
+ minfo->method_info.code_size);
dwarf2_write_dw_lns_copy (info->f);
dwarf2_write_dw_lne_end_sequence (info->f);
}
MonoType *ret_type = NULL;
gchar **names;
- if (minfo->method->signature->ret->type != MONO_TYPE_VOID)
- ret_type = minfo->method->signature->ret;
+ if (minfo->method_info.method->signature->ret->type != MONO_TYPE_VOID)
+ ret_type = minfo->method_info.method->signature->ret;
// DW_TAG_subprogram
if (ret_type)
dwarf2_write_byte (info->f, ABBREV_SUBPROGRAM);
dwarf2_write_string (info->f, minfo->name);
dwarf2_write_byte (info->f, is_external);
- dwarf2_write_address (info->f, minfo->code_start);
- dwarf2_write_address (info->f, minfo->code_start + minfo->code_size);
+ dwarf2_write_address (info->f, minfo->method_info.code_start);
+ dwarf2_write_address (info->f, minfo->method_info.code_start + minfo->method_info.code_size);
dwarf2_write_byte (info->f, DW_CC_nocall);
if (ret_type) {
MonoClass *klass = mono_class_from_mono_type (ret_type);
dwarf2_write_type_ref (info->f, type_index);
}
- if (minfo->method->signature->hasthis)
- dwarf2_write_parameter (info, minfo, "this", 8, minfo->method->klass);
+ if (minfo->method_info.method->signature->hasthis)
+ dwarf2_write_parameter (info, minfo, "this", 8, minfo->method_info.method->klass);
- names = g_new (char *, minfo->method->signature->param_count);
- mono_method_get_param_names (minfo->method, (const char **) names);
+ names = g_new (char *, minfo->method_info.method->signature->param_count);
+ mono_method_get_param_names (minfo->method_info.method, (const char **) names);
- for (i = 0; i < minfo->method->signature->param_count; i++) {
- MonoType *type = minfo->method->signature->params [i];
+ for (i = 0; i < minfo->method_info.num_params; i++) {
+ MonoType *type = minfo->method_info.method->signature->params [i];
MonoClass *klass = mono_class_from_mono_type (type);
- dwarf2_write_parameter (info, minfo, names [i], minfo->params [i].offset, klass);
+ dwarf2_write_parameter (info, minfo, names [i], minfo->method_info.param_offsets [i], klass);
}
g_free (names);
- for (i = 0; i < minfo->num_locals; i++) {
- MonoMethodHeader *header = ((MonoMethodNormal*) minfo->method)->header;
+ for (i = 0; i < minfo->method_info.num_locals; i++) {
+ MonoMethodHeader *header = ((MonoMethodNormal*) minfo->method_info.method)->header;
MonoClass *klass = mono_class_from_mono_type (header->locals [i]);
char name [BUFSIZ];
sprintf (name, "V_%d", i);
- dwarf2_write_variable (info, minfo, name, minfo->locals [i].offset, klass);
+ dwarf2_write_variable (info, minfo, name, minfo->method_info.local_offsets [i], klass);
}
dwarf2_write_byte (info->f, 0);
mono_debug_write_assembly_dwarf2 (AssemblyDebugInfo *info)
{
gchar *source_file = g_ptr_array_index (info->source_files, 0);
+ char *buf;
+
+ if (!(info->f = fopen (info->filename, "w")))
+ return;
// DWARF 2 Abbreviation table.
dwarf2_write_section_start (info->f, "debug_abbrev");
dwarf2_write_label (info->f, "debug_info_e");
dwarf2_write_section_end (info->f);
+
+ fclose (info->f);
+ info->f = NULL;
+
+ /* yes, it's completely unsafe */
+ buf = g_strdup_printf ("as %s -o /tmp/%s.o", info->filename, info->name);
+ system (buf);
+ g_free (buf);
}
#ifndef __MONO_JIT_DEBUG_PRIVATE_H__
#define __MONO_JIT_DEBUG_PRIVATE_H__
+#include <mono/metadata/debug-symfile.h>
+
#include "debug.h"
typedef struct {
typedef struct _AssemblyDebugInfo AssemblyDebugInfo;
typedef struct {
+ MonoDebugMethodInfo method_info;
gchar *name;
int source_file;
- MonoMethod *method;
guint32 method_number;
guint32 start_line;
guint32 first_line;
- gpointer code_start;
- guint32 code_size;
guint32 frame_start_offset;
GPtrArray *line_numbers;
- guint32 num_params;
- MonoVarInfo *params;
- guint32 num_locals;
- MonoVarInfo *locals;
} DebugMethodInfo;
struct _AssemblyDebugInfo {
GList *info;
};
-guint32 mono_debug_get_type (AssemblyDebugInfo* info, MonoClass *klass);
+guint32 mono_debug_get_type (AssemblyDebugInfo* info, MonoClass *klass);
+
+void mono_debug_open_assembly_stabs (AssemblyDebugInfo *info);
+
+void mono_debug_open_assembly_dwarf2 (AssemblyDebugInfo *info);
+
+void mono_debug_open_assembly_dwarf2_plus (AssemblyDebugInfo *info);
-void mono_debug_open_assembly_stabs (AssemblyDebugInfo *info);
+void mono_debug_write_assembly_stabs (AssemblyDebugInfo *info);
-void mono_debug_open_assembly_dwarf2 (AssemblyDebugInfo *info);
+void mono_debug_write_assembly_dwarf2 (AssemblyDebugInfo *info);
-void mono_debug_write_assembly_stabs (AssemblyDebugInfo *info);
+void mono_debug_write_assembly_dwarf2_plus (AssemblyDebugInfo *info);
-void mono_debug_write_assembly_dwarf2 (AssemblyDebugInfo *info);
+void mono_debug_close_assembly_stabs (AssemblyDebugInfo *info);
-void mono_debug_close_assembly_stabs (AssemblyDebugInfo *info);
+void mono_debug_close_assembly_dwarf2 (AssemblyDebugInfo *info);
-void mono_debug_close_assembly_dwarf2 (AssemblyDebugInfo *info);
+void mono_debug_close_assembly_dwarf2_plus (AssemblyDebugInfo *info);
#endif /* __MONO_JIT_DEBUG_PRIVATE_H__ */
write_method_stabs (AssemblyDebugInfo *info, DebugMethodInfo *minfo)
{
int i;
- MonoMethod *method = minfo->method;
+ MonoMethod *method = minfo->method_info.method;
MonoClass *klass = method->klass;
MonoMethodSignature *sig = method->signature;
char **names = g_new (char*, sig->param_count);
* fprintf (info->f, ".stabs \"%s.il\",100,0,0,0\n", klass->image->assembly_name);
*/
fprintf (info->f, ".stabs \"%s:F(0,%d)\",36,0,%d,%p\n", minfo->name, sig->ret->type,
- minfo->start_line, minfo->code_start);
+ minfo->start_line, minfo->method_info.code_start);
/* params */
mono_method_get_param_names (method, (const char **)names);
if (sig->hasthis)
fprintf (info->f, ".stabs \"this:p(0,%d)=(0,%d)\",160,0,%d,%d\n",
info->next_idx++, klass->byval_arg.type, minfo->start_line, 8); /* FIXME */
- for (i = 0; i < minfo->num_params; i++) {
- int stack_offset = minfo->params [i].offset;
+ for (i = 0; i < minfo->method_info.num_params; i++) {
+ int stack_offset = minfo->method_info.param_offsets [i];
fprintf (info->f, ".stabs \"%s:p(0,%d)=(0,%d)\",160,0,%d,%d\n",
names [i], info->next_idx++, sig->params [i]->type,
}
/* local vars */
- for (i = 0; i < minfo->num_locals; ++i) {
+ for (i = 0; i < minfo->method_info.num_locals; ++i) {
MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
- int stack_offset = minfo->locals [i].offset;
+ int stack_offset = minfo->method_info.local_offsets [i];
fprintf (info->f, ".stabs \"local_%d:(0,%d)=(0,%d)\",128,0,%d,%d\n",
i, info->next_idx++, header->locals [i]->type, minfo->start_line, stack_offset);
for (i = 1; i < minfo->line_numbers->len; i++) {
DebugLineNumberInfo *lni = g_ptr_array_index (minfo->line_numbers, i);
- fprintf (info->f, ".stabn 68,0,%d,%d\n", lni->line, lni->address - minfo->code_start);
+ fprintf (info->f, ".stabn 68,0,%d,%d\n", lni->line,
+ lni->address - minfo->method_info.code_start);
}
/* end of function */
- fprintf (info->f, ".stabs \"\",36,0,0,%d\n", minfo->code_size);
+ fprintf (info->f, ".stabs \"\",36,0,0,%d\n", minfo->method_info.code_size);
g_free (names);
fflush (info->f);
void
mono_debug_write_assembly_stabs (AssemblyDebugInfo* info)
{
+ char *buf;
int i;
+
+ if (!(info->f = fopen (info->filename, "w")))
+ return;
+
for (i = 0; base_types [i].name; ++i) {
if (! base_types [i].spec)
continue;
g_hash_table_foreach (info->methods, write_method_func, info);
g_hash_table_foreach (info->type_hash, write_class, info);
+
+ fclose (info->f);
+ info->f = NULL;
+
+ /* yes, it's completely unsafe */
+ buf = g_strdup_printf ("as %s -o /tmp/%s.o", info->filename, info->name);
+ system (buf);
+ g_free (buf);
}
g_ptr_array_add (minfo->line_numbers, lni);
}
+static void
+record_il_offset (GPtrArray *array, guint32 offset, guint32 address)
+{
+ MonoDebugILOffsetInfo *info = g_new0 (MonoDebugILOffsetInfo, 1);
+
+ info->offset = offset;
+ info->address = address;
+
+ g_ptr_array_add (array, info);
+}
+
static void
debug_generate_method_lines (AssemblyDebugInfo *info, DebugMethodInfo *minfo, MonoFlowGraph* cfg)
{
guint32 st_address, st_line;
+ GPtrArray *il_offsets;
int i;
+ il_offsets = g_ptr_array_new ();
minfo->line_numbers = g_ptr_array_new ();
st_line = minfo->start_line;
st_address = 1;
record_line_number (minfo, cfg->start + st_address, st_line, FALSE);
+ record_il_offset (il_offsets, 0, 0);
/* start lines of basic blocks */
for (i = 0; i < cfg->block_count; ++i) {
st_address += addr_inc;
record_line_number (minfo, cfg->start + st_address, st_line, j == 0);
+
+ if (t->cli_addr != -1)
+ record_il_offset (il_offsets, t->cli_addr, st_address);
}
}
+
+ minfo->method_info.num_il_offsets = il_offsets->len;
+ minfo->method_info.il_offsets = g_new0 (MonoDebugILOffsetInfo, il_offsets->len);
+ for (i = 0; i < il_offsets->len; i++) {
+ MonoDebugILOffsetInfo *il = (MonoDebugILOffsetInfo *) g_ptr_array_index (il_offsets, i);
+
+ minfo->method_info.il_offsets [i] = *il;
+ }
+
+ g_ptr_array_free (il_offsets, TRUE);
}
static void
{
if (minfo->line_numbers)
g_ptr_array_free (minfo->line_numbers, TRUE);
- g_free (minfo->params);
- g_free (minfo->locals);
- g_free (minfo->name);
+ g_free (minfo->method_info.param_offsets);
+ g_free (minfo->method_info.local_offsets);
g_free (minfo);
}
case MONO_DEBUG_FORMAT_DWARF2:
info->filename = g_strdup_printf ("%s-dwarf.s", image->assembly_name);
break;
+ case MONO_DEBUG_FORMAT_DWARF2_PLUS:
+ info->filename = g_strdup_printf ("%s-debug.o", image->assembly_name);
+ break;
}
info->image = image;
info->name = g_strdup (image->assembly_name);
case MONO_DEBUG_FORMAT_DWARF2:
mono_debug_open_assembly_dwarf2 (info);
break;
+ case MONO_DEBUG_FORMAT_DWARF2_PLUS:
+ mono_debug_open_assembly_dwarf2_plus (info);
+ break;
}
info->next_idx = 100;
mono_debug_make_symbols (void)
{
GList *tmp;
- char *buf;
AssemblyDebugInfo* info;
if (!mono_debug_handle)
for (tmp = mono_debug_handle->info; tmp; tmp = tmp->next) {
info = (AssemblyDebugInfo*)tmp->data;
- if (!(info->f = fopen (info->filename, "w")))
- continue;
-
switch (mono_debug_handle->format) {
case MONO_DEBUG_FORMAT_STABS:
mono_debug_write_assembly_stabs (info);
case MONO_DEBUG_FORMAT_DWARF2:
mono_debug_write_assembly_dwarf2 (info);
break;
+ case MONO_DEBUG_FORMAT_DWARF2_PLUS:
+ mono_debug_write_assembly_dwarf2_plus (info);
+ break;
}
-
- fclose (info->f);
- info->f = NULL;
-
- /* yes, it's completely unsafe */
- buf = g_strdup_printf ("as %s -o /tmp/%s.o", info->filename, info->name);
- system (buf);
- g_free (buf);
}
}
case MONO_DEBUG_FORMAT_DWARF2:
mono_debug_close_assembly_dwarf2 (info);
break;
+ case MONO_DEBUG_FORMAT_DWARF2_PLUS:
+ mono_debug_close_assembly_dwarf2_plus (info);
+ break;
}
mono_debug_close_assembly (info);
}
}
- if (g_hash_table_lookup (info->methods, GINT_TO_POINTER (method_number)))
+ if (g_hash_table_lookup (info->methods, method))
return;
/* info->moffsets contains -1 "outside" of functions. */
minfo->name = name;
minfo->start_line = start_line;
minfo->first_line = line;
- minfo->code_start = cfg->start + 1;
- minfo->code_size = cfg->code_size;
+ minfo->method_info.code_start = cfg->start + 1;
+ minfo->method_info.code_size = cfg->code_size;
minfo->method_number = method_number;
- minfo->method = method;
- minfo->num_params = minfo->method->signature->param_count;
- minfo->params = g_new0 (MonoVarInfo, minfo->num_params + 1);
+ minfo->method_info.method = method;
+ minfo->method_info.num_params = method->signature->param_count;
+ minfo->method_info.param_offsets = g_new0 (guint32, minfo->method_info.num_params + 1);
- if (minfo->method->signature->param_count) {
+ for (i = 0; i < minfo->method_info.num_params; i++) {
MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->args_start_index +
- minfo->method->signature->hasthis;
+ method->signature->hasthis;
- memcpy (minfo->params, ptr, sizeof (MonoVarInfo) * minfo->num_params);
+ minfo->method_info.param_offsets [i] = ptr [i].offset;
}
if (!method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
MonoVarInfo *ptr = ((MonoVarInfo *) cfg->varinfo->data) + cfg->locals_start_index;
- minfo->num_locals = header->num_locals;
- minfo->locals = g_new0 (MonoVarInfo, minfo->num_locals + 1);
-
- memcpy (minfo->locals, ptr, sizeof (MonoVarInfo) * minfo->num_locals);
+ minfo->method_info.num_locals = header->num_locals;
+ minfo->method_info.local_offsets = g_new0 (guint32, header->num_locals);
+ for (i = 0; i < minfo->method_info.num_locals; i++)
+ minfo->method_info.local_offsets [i] = ptr [i].offset;
}
debug_generate_method_lines (info, minfo, cfg);
- g_hash_table_insert (info->methods, GINT_TO_POINTER (method_number), minfo);
+ g_hash_table_insert (info->methods, method, minfo);
}
typedef enum {
MONO_DEBUG_FORMAT_STABS,
- MONO_DEBUG_FORMAT_DWARF2
+ MONO_DEBUG_FORMAT_DWARF2,
+ MONO_DEBUG_FORMAT_DWARF2_PLUS
} MonoDebugFormat;
extern MonoDebugHandle *mono_debug_handle;
"--workers n maximum number of worker threads\n"
"--stabs write stabs debug information\n"
"--dwarf write dwarf2 debug information\n"
+ "--dwarf-plus write extended dwarf2 debug information\n"
"--stats print statistics about the jit operations\n"
"--compile cname compile methods in given class (namespace.name[:methodname])\n"
"--ncompile num compile methods num times (default: 1000)\n"
if (mono_debug_handle)
g_error ("You can use either --stabs or --dwarf, but not both.");
mono_debug_handle = mono_debug_open_file ("", MONO_DEBUG_FORMAT_DWARF2);
+ } else if (strcmp (argv [i], "--dwarf-plus") == 0) {
+ if (mono_debug_handle)
+ g_error ("You can use either --stabs or --dwarf, but not both.");
+ mono_debug_handle = mono_debug_open_file ("", MONO_DEBUG_FORMAT_DWARF2_PLUS);
} else if (strcmp (argv [i], "--verbose") == 0) {
verbose = TRUE;;
} else