2002-03-13 Martin Baulig <martin@gnome.org>
[mono.git] / mono / jit / debug-stabs.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <mono/metadata/class.h>
4 #include <mono/metadata/tabledefs.h>
5 #include <mono/metadata/tokentype.h>
6 #include <mono/jit/codegen.h>
7 #include <mono/jit/dwarf2.h>
8 #include <mono/jit/debug.h>
9
10 #include "debug-private.h"
11
12 typedef struct {
13         char *name;
14         char *spec;
15 } BaseTypes;
16
17 /*
18  * Not 64 bit clean.
19  * Note: same order of MonoTypeEnum.
20  */
21 static BaseTypes
22 base_types[] = {
23         {"", NULL},
24         {"Void", "(0,1)"},
25         {"Boolean", ";0;255;"},
26         {"Char", ";0;65535;"},
27         {"SByte", ";-128;127;"},
28         {"Byte", ";0;255;"},
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*/
38         {"", }, /*ptr*/
39         {"", }, /*byref*/
40         {"", }, /*valuetype*/
41         {"Class", "(0,44)=*(0,45)=xsMonoObject:"}, /*class*/
42         {"", }, /*unused*/
43         {"Array", }, /*array*/
44         {"", }, /*typedbyref*/
45         {"", }, /*unused*/
46         {"", }, /*unused*/
47         {"IntPtr", ";0020000000000;0017777777777;"},
48         {"UIntPtr", ";0000000000000;0037777777777;"},
49         {"", }, /*unused*/
50         {"FnPtr", "*(0,1)"}, /*fnptr*/
51         {"Object", "(0,47)=*(0,48)=xsMonoObject:"}, /*object*/
52         {"SzArray", "(0,50)=*(0,51))=xsMonoArray:"}, /*szarray*/
53         {NULL, NULL}
54 };
55
56 void
57 mono_debug_open_assembly_stabs (AssemblyDebugInfo* info)
58 {
59 }
60
61 void
62 mono_debug_close_assembly_stabs (AssemblyDebugInfo* info)
63 {
64 }
65
66 static void
67 write_method_stabs (AssemblyDebugInfo *info, DebugMethodInfo *minfo)
68 {
69         int i;
70         MonoMethod *method = minfo->method;
71         MonoClass *klass = method->klass;
72         MonoMethodSignature *sig = method->signature;
73         char **names = g_new (char*, sig->param_count);
74
75         /*
76          * We need to output all the basic info, if we change filename...
77          * fprintf (info->f, ".stabs \"%s.il\",100,0,0,0\n", klass->image->assembly_name);
78          */
79         fprintf (info->f, ".stabs \"%s:F(0,%d)\",36,0,%d,%p\n", minfo->name, sig->ret->type,
80                  minfo->start_line, minfo->code_start);
81
82         /* params */
83         mono_method_get_param_names (method, (const char **)names);
84         if (sig->hasthis)
85                 fprintf (info->f, ".stabs \"this:p(0,%d)=(0,%d)\",160,0,%d,%d\n",
86                          info->next_idx++, klass->byval_arg.type, minfo->start_line, 8); /* FIXME */
87         for (i = 0; i < minfo->num_params; i++) {
88                 int stack_offset = minfo->params [i].offset;
89
90                 fprintf (info->f, ".stabs \"%s:p(0,%d)=(0,%d)\",160,0,%d,%d\n",
91                          names [i], info->next_idx++, sig->params [i]->type,
92                          minfo->start_line, stack_offset);
93         }
94
95         /* local vars */
96         for (i = 0; i < minfo->num_locals; ++i) {
97                 MonoMethodHeader *header = ((MonoMethodNormal*)method)->header;
98                 int stack_offset = minfo->locals [i].offset;
99
100                 fprintf (info->f, ".stabs \"local_%d:(0,%d)=(0,%d)\",128,0,%d,%d\n",
101                          i, info->next_idx++, header->locals [i]->type, minfo->start_line, stack_offset);
102         }
103
104         fprintf (info->f, ".stabn 68,0,%d,%d\n", minfo->start_line, 0);
105
106         for (i = 1; i < minfo->line_numbers->len; i++) {
107                 DebugLineNumberInfo *lni = g_ptr_array_index (minfo->line_numbers, i);
108
109                 fprintf (info->f, ".stabn 68,0,%d,%d\n", lni->line, lni->address - minfo->code_start);
110         }
111
112         /* end of function */
113         fprintf (info->f, ".stabs \"\",36,0,0,%d\n", minfo->code_size);
114
115         g_free (names);
116         fflush (info->f);
117 }
118
119 static void
120 get_enumvalue (MonoClass *klass, int index, char *buf)
121 {
122         guint32 const_cols [MONO_CONSTANT_SIZE];
123         const char *ptr;
124         guint32 crow = mono_metadata_get_constant_index (klass->image, MONO_TOKEN_FIELD_DEF | (index + 1));
125
126         if (!crow) {
127                 buf [0] = '0';
128                 buf [1] = 0;
129                 return;
130         }
131         mono_metadata_decode_row (&klass->image->tables [MONO_TABLE_CONSTANT], crow-1, const_cols, MONO_CONSTANT_SIZE);
132         ptr = mono_metadata_blob_heap (klass->image, const_cols [MONO_CONSTANT_VALUE]);
133         switch (const_cols [MONO_CONSTANT_TYPE]) {
134         case MONO_TYPE_U4:
135         case MONO_TYPE_I4:
136                 /* FIXME: add other types... */
137         default:
138                 g_snprintf (buf, 64, "%d", *(gint32*)ptr);
139         }
140 }
141
142 static void
143 write_method_func (gpointer key, gpointer value, gpointer user_data)
144 {
145         write_method_stabs (user_data, value);
146 }
147
148 void
149 mono_debug_write_assembly_stabs (AssemblyDebugInfo* info)
150 {
151         int i;
152         for (i = 0; base_types [i].name; ++i) {
153                 if (! base_types [i].spec)
154                         continue;
155                 fprintf (info->f, ".stabs \"%s:t(0,%d)=", base_types [i].name, i);
156                 if (base_types [i].spec [0] == ';') {
157                         fprintf (info->f, "r(0,%d)%s\"", i, base_types [i].spec);
158                 } else {
159                         fprintf (info->f, "%s\"", base_types [i].spec);
160                 }
161                 fprintf (info->f, ",128,0,0,0\n");
162         }
163
164         g_hash_table_foreach (info->methods, write_method_func, info);
165 }