4 #include <mono/metadata/class.h>
5 #include <mono/metadata/tabledefs.h>
6 #include <mono/metadata/tokentype.h>
7 #include <mono/jit/codegen.h>
8 #include <mono/jit/debug.h>
10 #include "debug-private.h"
19 * Note: same order of MonoTypeEnum.
25 {"Boolean", ";0;255;"},
26 {"Char", ";0;65535;"},
27 {"SByte", ";-128;127;"},
29 {"Int16", ";-32768;32767;"},
30 {"UInt16", ";0;65535;"},
31 {"Int32", ";0020000000000;0017777777777;"},
32 {"UInt32", ";0000000000000;0037777777777;"},
33 {"Int64", ";01000000000000000000000;0777777777777777777777;"},
34 {"UInt64", ";0000000000000;01777777777777777777777;"},
35 {"Single", "r(0,8);4;0;"},
36 {"Double", "r(0,8);8;0;"},
37 {"String", "(0,41)=*(0,42)=xsMonoString:"}, /*string*/
41 {"Class", "(0,44)=*(0,45)=xsMonoObject:"}, /*class*/
43 {"Array", }, /*array*/
44 {"", }, /*typedbyref*/
47 {"IntPtr", ";0020000000000;0017777777777;"},
48 {"UIntPtr", ";0000000000000;0037777777777;"},
50 {"FnPtr", "*(0,1)"}, /*fnptr*/
51 {"Object", "(0,47)=*(0,48)=xsMonoObject:"}, /*object*/
52 {"SzArray", "(0,50)=*(0,51))=xsMonoArray:"}, /*szarray*/
57 write_method_stabs (MonoDebugHandle *debug, MonoDebugMethodInfo *minfo)
60 DebugMethodInfo *priv = minfo->user_data;
61 MonoMethod *method = minfo->method;
62 MonoClass *klass = method->klass;
63 MonoMethodSignature *sig = method->signature;
64 char **names = g_new (char*, sig->param_count);
70 source_file = g_ptr_array_index (debug->source_files, priv->source_file);
72 fprintf (debug->f, ".stabs \"%s\",100,0,0,0\n", source_file);
74 fprintf (debug->f, ".stabs \"%s:F(0,%d)\",36,0,%d,%p\n", priv->name, sig->ret->type,
75 priv->start_line, minfo->jit->code_start);
78 mono_method_get_param_names (method, (const char **)names);
80 fprintf (debug->f, ".stabs \"this:p(0,%d)=(0,%d)\",160,0,%d,%d\n",
81 debug->next_idx++, klass->byval_arg.type, priv->start_line,
82 minfo->jit->this_var->offset);
83 for (i = 0; i < minfo->jit->num_params; i++) {
84 int stack_offset = minfo->jit->params [i].offset;
86 fprintf (debug->f, ".stabs \"%s:p(0,%d)=(0,%d)\",160,0,%d,%d\n",
87 names [i], debug->next_idx++, sig->params [i]->type,
88 priv->start_line, stack_offset);
92 for (i = 0; i < minfo->jit->num_locals; ++i) {
93 MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
94 int stack_offset = minfo->jit->locals [i].offset;
96 fprintf (debug->f, ".stabs \"local_%d:(0,%d)=(0,%d)\",128,0,%d,%d\n",
97 i, debug->next_idx++, header->locals [i]->type, priv->start_line, stack_offset);
100 if (minfo->jit && minfo->jit->line_numbers) {
101 fprintf (debug->f, ".stabn 68,0,%d,%d\n", priv->start_line, 0);
102 fprintf (debug->f, ".stabn 68,0,%d,%d\n", priv->first_line,
103 minfo->jit->prologue_end);
105 for (i = 1; i < minfo->jit->line_numbers->len; i++) {
106 MonoDebugLineNumberEntry lne = g_array_index (
107 minfo->jit->line_numbers, MonoDebugLineNumberEntry, i);
109 fprintf (debug->f, ".stabn 68,0,%d,%d\n", lne.line, lne.address);
112 fprintf (debug->f, ".stabn 68,0,%d,%d\n", priv->last_line,
113 minfo->jit->epilogue_begin);
116 /* end of function */
117 fprintf (debug->f, ".stabs \"\",36,0,0,%d\n", minfo->jit->code_size);
124 get_enumvalue (MonoClass *klass, int idx, char *buf)
126 guint32 const_cols [MONO_CONSTANT_SIZE];
128 guint32 crow = mono_metadata_get_constant_index (klass->image, MONO_TOKEN_FIELD_DEF | (idx + 1));
135 mono_metadata_decode_row (&klass->image->tables [MONO_TABLE_CONSTANT], crow-1, const_cols, MONO_CONSTANT_SIZE);
136 ptr = mono_metadata_blob_heap (klass->image, const_cols [MONO_CONSTANT_VALUE]);
137 switch (const_cols [MONO_CONSTANT_TYPE]) {
140 /* FIXME: add other types... */
142 g_snprintf (buf, 64, "%d", *(gint32*)ptr);
147 write_method_func (gpointer key, gpointer value, gpointer user_data)
149 write_method_stabs (user_data, value);
153 write_method_func_1 (gpointer key, gpointer value, gpointer user_data)
155 AssemblyDebugInfo *info = (AssemblyDebugInfo *) value;
157 g_hash_table_foreach (info->methods, write_method_func, user_data);
161 write_class_stabs (MonoDebugHandle *debug, MonoClass *klass, int idx)
167 /* output enums ...*/
168 if (klass->enumtype) {
169 name = g_strdup_printf ("%s%s%s", klass->name_space, klass->name_space [0]? "_": "", klass->name);
170 fprintf (debug->f, ".stabs \"%s:T%d=e", name, ++debug->next_idx);
172 for (i = 0; i < klass->field.count; ++i) {
173 if (klass->fields [i].type->attrs & FIELD_ATTRIBUTE_LITERAL) {
174 get_enumvalue (klass, klass->field.first + i, buf);
175 fprintf (debug->f, "%s_%s=%s,", klass->name, klass->fields [i].name, buf);
178 fprintf (debug->f, ";\",128,0,0,0\n");
184 write_class (gpointer key, gpointer value, gpointer user_data)
186 write_class_stabs (user_data, key, GPOINTER_TO_INT (value));
190 mono_debug_write_stabs (MonoDebugHandle *debug)
195 if (!(debug->f = fopen (debug->filename, "w"))) {
196 g_warning ("Can't create stabs file `%s': %s", debug->filename, g_strerror (errno));
200 source_file = g_ptr_array_index (debug->source_files, 0);
202 fprintf (debug->f, ".stabs \"%s\",100,0,0,0\n", source_file);
204 for (i = 0; base_types [i].name; ++i) {
205 if (! base_types [i].spec)
207 fprintf (debug->f, ".stabs \"%s:t(0,%d)=", base_types [i].name, i);
208 if (base_types [i].spec [0] == ';') {
209 fprintf (debug->f, "r(0,%d)%s\"", i, base_types [i].spec);
211 fprintf (debug->f, "%s\"", base_types [i].spec);
213 fprintf (debug->f, ",128,0,0,0\n");
216 g_hash_table_foreach (debug->images, write_method_func_1, debug);
218 g_hash_table_foreach (debug->type_hash, write_class, debug);
223 if (!(debug->flags & MONO_DEBUG_FLAGS_DONT_ASSEMBLE)) {
226 /* yes, it's completely unsafe */
227 buf = g_strdup_printf ("as %s -o %s", debug->filename, debug->objfile);