added initial stabs debugging support
[libfirm] / ir / be / bestabs.c
1 /**
2  * Stabs support.
3  *
4  * @author Michael Beck
5  * @date   11.9.2006
6  * @cvsid  $Id$
7  */
8
9 #ifdef HAVE_CONFIG_H
10 # include "config.h"
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #include "entity.h"
17 #include "xmalloc.h"
18 #include "be_dbgout.h"
19
20 /* stabs types */
21 enum stabs_types {
22         NIL     = 0,
23         N_GSYM  = 32,   /**< global symbol */
24         N_FUN   = 36,   /**< procedure */
25         N_STSYM = 38,   /**< Initialized static variable */
26         N_LCSYM = 40,   /**< uninitialized static var */
27         N_RSYM  = 64,   /**< global register variable */
28         N_SLINE = 68,
29         N_SO    = 100,  /**< name and path of the source file */
30         N_LSYM  = 128,  /**< local symbol */
31         N_PSYM  = 160,  /**< parameters to a function */
32         N_LBRAC = 192,  /**< left brace */
33         N_RBRAC = 224,  /**< right brace */
34 };
35
36 /**
37  * The stabs handle.
38  */
39 typedef struct stabs_handle {
40         dbg_handle base;   /**< the base class */
41         FILE       *f;     /**< the file write to */
42         entity     *cur_ent;
43 } stabs_handle;
44
45 /**
46  * Returns the stabs type number of a Firm type.
47  */
48 static unsigned get_type_number(ir_type *tp) {
49         return 0;
50 }  /* get_type_number */
51
52 /**
53  * begin a new file
54  */
55 static void stabs_begin(dbg_handle *handle, const char *filename) {
56         stabs_handle *h = (stabs_handle *)handle;
57         fprintf(h->f, ".stabs \"%s\",%d,0,0,.Ltext0\n", filename, N_SO);
58 }  /* stabs_begin */
59
60 /**
61  * prints a line number
62  */
63 static void stabs_line(dbg_handle *handle, unsigned lineno, const char *address) {
64         stabs_handle *h = (stabs_handle *)handle;
65         fprintf(h->f, ".stabn %d, 0, %u, %s-%s\n", N_SLINE, lineno, address, get_entity_ld_name(h->cur_ent));
66 }  /* stabs_line */
67
68 /**
69  * prints the stabs for a function
70  */
71 static void stabs_method(dbg_handle *handle, entity *ent) {
72         stabs_handle *h = (stabs_handle *)handle;
73         ir_type *tp;
74         unsigned type_num;
75
76         h->cur_ent = ent;
77
78         tp = get_entity_type(ent);
79         if (get_method_n_ress(tp) > 0)
80                 tp = get_method_res_type(tp, 0);
81         else
82                 tp = NULL;
83         type_num = get_type_number(tp);
84         fprintf(h->f, ".stabs \"%s:%c%u\",%u,0,0,%s\n",
85                 get_entity_name(ent),
86                 get_entity_visibility(ent) == visibility_external_visible ? 'F' : 'f',
87                 type_num,
88                 N_FUN,
89                 get_entity_ld_name(ent));
90 }  /* stabs_method */
91
92 /* close the stabs handler */
93 static void stabs_close(dbg_handle *handle) {
94         stabs_handle *h = (stabs_handle *)handle;
95         free(h);
96 }  /* stabs_close */
97
98 /** The stabs operations. */
99 static const debug_ops stabs_ops = {
100         stabs_close,
101         stabs_begin,
102         stabs_method,
103         stabs_line,
104 };
105
106 /* Opens a stabs handler */
107 dbg_handle *be_stabs_open(FILE *out) {
108         stabs_handle *h = xmalloc(sizeof(*h));
109
110         h->base.ops = &stabs_ops;
111         h->f = out;
112         return &h->base;
113 }  /* stabs_open */
114
115 /** close a debug handler. */
116 void be_dbg_close(dbg_handle *h) {
117         if (h->ops->close)
118                 h->ops->close(h);
119 }  /* be_dbg_close */
120
121 /**
122  * begin a new file
123  */
124 void be_dbg_begin(dbg_handle *h, const char *filename) {
125         if (h->ops->begin)
126                 h->ops->begin(h, filename);
127 }  /* be_dbg_begin */
128
129 /** debug for a function */
130 void be_dbg_method(dbg_handle *h, entity *ent) {
131         if (h->ops->method)
132                 h->ops->method(h, ent);
133 }  /* be_dbg_method */
134
135 /** debug for line number */
136 void be_dbg_line(dbg_handle *h, unsigned lineno, const char *address) {
137         if (h->ops->line)
138                 h->ops->line(h, lineno, address);
139 }  /* be_dbg_line */