96c110bde693f57af887d4691801273cd93585ec
[platform/upstream/nasm.git] / output / outdbg.c
1 /* ----------------------------------------------------------------------- *
2  *   
3  *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
4  *   See the file AUTHORS included with the NASM distribution for
5  *   the specific copyright holders.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following
9  *   conditions are met:
10  *
11  *   * Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17  *     
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * ----------------------------------------------------------------------- */
33
34 /*
35  * outdbg.c     output routines for the Netwide Assembler to produce
36  *              a debugging trace
37  */
38
39 #include "compiler.h"
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <ctype.h>
45 #include <inttypes.h>
46
47 #include "nasm.h"
48 #include "nasmlib.h"
49 #include "output/outform.h"
50
51 #ifdef OF_DBG
52
53 struct Section {
54     struct Section *next;
55     int32_t number;
56     char *name;
57 } *dbgsect;
58
59 FILE *dbgf;
60 efunc dbgef;
61
62 struct ofmt of_dbg;
63 static void dbg_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
64 {
65     (void)eval;
66
67     dbgf = fp;
68     dbgef = errfunc;
69     dbgsect = NULL;
70     (void)ldef;
71     fprintf(fp, "NASM Output format debug dump\n");
72 }
73
74 static void dbg_cleanup(int debuginfo)
75 {
76     (void)debuginfo;
77     of_dbg.current_dfmt->cleanup();
78     while (dbgsect) {
79         struct Section *tmp = dbgsect;
80         dbgsect = dbgsect->next;
81         nasm_free(tmp->name);
82         nasm_free(tmp);
83     }
84 }
85
86 static int32_t dbg_section_names(char *name, int pass, int *bits)
87 {
88     int seg;
89
90     /*
91      * We must have an initial default: let's make it 16.
92      */
93     if (!name)
94         *bits = 16;
95
96     if (!name)
97         fprintf(dbgf, "section_name on init: returning %d\n",
98                 seg = seg_alloc());
99     else {
100         int n = strcspn(name, " \t");
101         char *sname = nasm_strndup(name, n);
102         struct Section *s;
103
104         seg = NO_SEG;
105         for (s = dbgsect; s; s = s->next)
106             if (!strcmp(s->name, sname))
107                 seg = s->number;
108
109         if (seg == NO_SEG) {
110             s = nasm_malloc(sizeof(*s));
111             s->name = sname;
112             s->number = seg = seg_alloc();
113             s->next = dbgsect;
114             dbgsect = s;
115             fprintf(dbgf, "section_name %s (pass %d): returning %d\n",
116                     name, pass, seg);
117         }
118     }
119     return seg;
120 }
121
122 static void dbg_deflabel(char *name, int32_t segment, int64_t offset,
123                          int is_global, char *special)
124 {
125     fprintf(dbgf, "deflabel %s := %08"PRIx32":%016"PRIx64" %s (%d)%s%s\n",
126             name, segment, offset,
127             is_global == 2 ? "common" : is_global ? "global" : "local",
128             is_global, special ? ": " : "", special);
129 }
130
131 static void dbg_out(int32_t segto, const void *data,
132                     enum out_type type, uint64_t size,
133                     int32_t segment, int32_t wrt)
134 {
135     int32_t ldata;
136     int id;
137
138     fprintf(dbgf, "out to %"PRIx32", len = %"PRIu64": ", segto, size);
139
140     switch (type) {
141     case OUT_RESERVE:
142         fprintf(dbgf, "reserved.\n");
143         break;
144     case OUT_RAWDATA:
145         fprintf(dbgf, "raw data = ");
146         while (size--) {
147             id = *(uint8_t *)data;
148             data = (char *)data + 1;
149             fprintf(dbgf, "%02x ", id);
150         }
151         fprintf(dbgf, "\n");
152         break;
153     case OUT_ADDRESS:
154         ldata = *(int64_t *)data;
155         fprintf(dbgf, "addr %08"PRIx32" (seg %08"PRIx32", wrt %08"PRIx32")\n", ldata,
156                 segment, wrt);
157         break;
158     case OUT_REL2ADR:
159         fprintf(dbgf, "rel2adr %04"PRIx16" (seg %08"PRIx32")\n",
160                 (uint16_t)*(int64_t *)data, segment);
161         break;
162     case OUT_REL4ADR:
163         fprintf(dbgf, "rel4adr %08"PRIx32" (seg %08"PRIx32")\n",
164                 (uint32_t)*(int64_t *)data,
165                 segment);
166         break;
167     case OUT_REL8ADR:
168         fprintf(dbgf, "rel8adr %016"PRIx64" (seg %08"PRIx32")\n",
169                 (uint64_t)*(int64_t *)data, segment);
170         break;
171     default:
172         fprintf(dbgf, "unknown\n");
173         break;
174     }
175 }
176
177 static int32_t dbg_segbase(int32_t segment)
178 {
179     return segment;
180 }
181
182 static int dbg_directive(enum directives directive, char *value, int pass)
183 {
184     fprintf(dbgf, "directive [%s] value [%s] (pass %d)\n",
185             directives[directive], value, pass);
186     return 1;
187 }
188
189 static void dbg_filename(char *inname, char *outname, efunc error)
190 {
191     standard_extension(inname, outname, ".dbg", error);
192 }
193
194 static int dbg_set_info(enum geninfo type, char **val)
195 {
196     (void)type;
197     (void)val;
198     return 0;
199 }
200
201 char *types[] = {
202     "unknown", "label", "byte", "word", "dword", "float", "qword", "tbyte"
203 };
204 void dbgdbg_init(struct ofmt *of, void *id, FILE * fp, efunc error)
205 {
206     (void)of;
207     (void)id;
208     (void)fp;
209     (void)error;
210     fprintf(fp, "   With debug info\n");
211 }
212 static void dbgdbg_cleanup(void)
213 {
214 }
215
216 static void dbgdbg_linnum(const char *lnfname, int32_t lineno, int32_t segto)
217 {
218     fprintf(dbgf, "dbglinenum %s(%"PRId32") := %08"PRIx32"\n",
219             lnfname, lineno, segto);
220 }
221 static void dbgdbg_deflabel(char *name, int32_t segment,
222                             int64_t offset, int is_global, char *special)
223 {
224     fprintf(dbgf, "dbglabel %s := %08"PRIx32":%016"PRIx64" %s (%d)%s%s\n",
225             name,
226             segment, offset,
227             is_global == 2 ? "common" : is_global ? "global" : "local",
228             is_global, special ? ": " : "", special);
229 }
230 static void dbgdbg_define(const char *type, const char *params)
231 {
232     fprintf(dbgf, "dbgdirective [%s] value [%s]\n", type, params);
233 }
234 static void dbgdbg_output(int output_type, void *param)
235 {
236     (void)output_type;
237     (void)param;
238 }
239 static void dbgdbg_typevalue(int32_t type)
240 {
241     fprintf(dbgf, "new type: %s(%"PRIX32")\n",
242             types[TYM_TYPE(type) >> 3], TYM_ELEMENTS(type));
243 }
244 static struct dfmt debug_debug_form = {
245     "Trace of all info passed to debug stage",
246     "debug",
247     dbgdbg_init,
248     dbgdbg_linnum,
249     dbgdbg_deflabel,
250     dbgdbg_define,
251     dbgdbg_typevalue,
252     dbgdbg_output,
253     dbgdbg_cleanup,
254 };
255
256 static struct dfmt *debug_debug_arr[3] = {
257     &debug_debug_form,
258     &null_debug_form,
259     NULL
260 };
261
262 struct ofmt of_dbg = {
263     "Trace of all info passed to output stage",
264     "dbg",
265     OFMT_TEXT,
266     debug_debug_arr,
267     &debug_debug_form,
268     NULL,
269     dbg_init,
270     dbg_set_info,
271     dbg_out,
272     dbg_deflabel,
273     dbg_section_names,
274     dbg_segbase,
275     dbg_directive,
276     dbg_filename,
277     dbg_cleanup
278 };
279
280 #endif                          /* OF_DBG */