Remove the local buffer from dbg_printf().
[libfirm] / ir / debug / debugger.c
1 /*
2  * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief     Helper function for integrated debug support
23  * @author    Michael Beck
24  * @date      2005
25  */
26 #include "config.h"
27
28 #ifdef DEBUG_libfirm
29
30 #ifdef _WIN32
31 #define WIN32_LEAN_AND_MEAN
32 #include <windows.h>
33 #endif
34
35 #include "debugger.h"
36
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <signal.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <time.h>
43
44 #include <ctype.h>
45
46 #include "set.h"
47 #include "ident.h"
48 #include "irhooks.h"
49 #include "irgraph_t.h"
50 #include "entity_t.h"
51 #include "irprintf.h"
52 #include "irdump.h"
53 #include "iredges_t.h"
54 #include "debug.h"
55 #include "error.h"
56 #include "util.h"
57
58 #ifdef _WIN32
59 /* Break into the debugger. The Win32 way. */
60 void firm_debug_break(void)
61 {
62         DebugBreak();
63 }
64 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
65 /* Break into the debugger. The ia32/x86_64 way under GCC. */
66 void firm_debug_break(void)
67 {
68         __asm__ __volatile__("int3");
69 }
70 #else
71 /* Break into the debugger. Poor Unix way. */
72 void firm_debug_break(void)
73 {
74         raise(SIGINT);
75 }
76 #endif /* _WIN32 */
77
78 /** supported breakpoint kinds */
79 typedef enum {
80         BP_NR    = 'n',   /**< break on node number. */
81         BP_IDENT = 'i'    /**< break on ident. */
82 } bp_kind;
83
84 /**
85  * Reasons for node number breakpoints.
86  */
87 typedef enum bp_reasons_t {
88         BP_ON_NEW_THING,   /**< break if node, entity or type with number is created */
89         BP_ON_REPLACE,     /**< break if node with number is replaced */
90         BP_ON_LOWER,       /**< break if node with number is lowered */
91         BP_ON_REMIRG,      /**< break if an IRG is removed */
92         BP_ON_NEW_ENT,     /**< break if a new entity is created */
93         BP_MAX_REASON
94 } bp_reasons_t;
95
96 /** A breakpoint. */
97 typedef struct breakpoint {
98         bp_kind      kind;        /**< the kind of this break point */
99         unsigned     bpnr;        /**< break point number */
100         int          active;      /**< non-zero, if this break point is active */
101         bp_reasons_t reason;      /**< reason for the breakpoint */
102         struct breakpoint *next; /**< link to the next one */
103 } breakpoint;
104
105 /** A number breakpoint. */
106 typedef struct {
107         breakpoint   bp;       /**< the breakpoint data */
108         long         nr;       /**< the node number */
109 } bp_nr_t;
110
111 /** Calculate the hash value for a node breakpoint. */
112 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
113
114 /** An ident breakpoint. */
115 typedef struct {
116         breakpoint   bp;       /**< the breakpoint data */
117         ident        *id;      /**< the ident */
118 } bp_ident_t;
119
120 /** Calculate the hash value for an ident breakpoint. */
121 #define HASH_IDENT_BP(key) (hash_ptr((key).id) ^ (key).bp.reason)
122
123 /** The set containing the breakpoints on node numbers. */
124 static set *bp_numbers;
125
126 /** The set containing the breakpoints on idents. */
127 static set *bp_idents;
128
129 /**< the list of all breakpoints */
130 static breakpoint *bp_list;
131
132 /** number of the current break point */
133 static unsigned bp_num = 0;
134
135 /** set if break on init command was issued. */
136 static int break_on_init = 0;
137
138 /** the hook entries for the Firm debugger module. */
139 static hook_entry_t debugger_hooks[hook_last];
140
141 /** number of active breakpoints to maintain hooks. */
142 static unsigned num_active_bp[BP_MAX_REASON];
143
144 /**
145  * The debug message buffer
146  */
147 static char firm_dbg_msg_buf[2048];
148
149 /**
150  * If set, the debug extension writes all output to the
151  * firm_dbg_msg_buf buffer
152  */
153 static int redir_output = 0;
154
155 /**
156  * Is set to one, if the debug extension is active
157  */
158 static int is_active = 0;
159
160 /** hook the hook h with function fkt. */
161 #define HOOK(h, fkt) \
162 do {                                      \
163         debugger_hooks[h].hook._##h = fkt;    \
164         register_hook(h, &debugger_hooks[h]); \
165 } while (0)
166
167 /** unhook the hook h */
168 #define UNHOOK(h) \
169 do {                                        \
170         unregister_hook(h, &debugger_hooks[h]); \
171         debugger_hooks[h].hook._##h = NULL;     \
172 } while (0)
173
174 /** returns non-zero if a entry hook h is used */
175 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
176
177 /* some macros needed to create the info string */
178 #define _DBG_VERSION(major, minor)  #major "." #minor
179 #define DBG_VERSION(major, minor)   _DBG_VERSION(major, minor)
180 #define API_VERSION(major, minor)   "API:" DBG_VERSION(major, minor)
181
182 /* the API version: change if needed */
183 #define FIRM_DBG_MAJOR  1
184 #define FIRM_DBG_MINOR  0
185
186 /** for automatic detection of the debug extension */
187 static const char __attribute__((used)) firm_debug_info_string[] =
188         API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
189
190 int firm_debug_active(void)
191 {
192         return is_active;
193 }
194
195 /**
196  * Reset the debug text buffer.
197  */
198 static void reset_dbg_buf(void)
199 {
200         firm_dbg_msg_buf[0] = '\0';
201 }
202
203 const char *firm_debug_text(void)
204 {
205         firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
206         return firm_dbg_msg_buf;
207 }
208
209 /**
210  * debug output
211  */
212 static void dbg_printf(const char *fmt, ...)
213 {
214         if (fmt[0] != '+')
215                 reset_dbg_buf();
216         else
217                 ++fmt;
218
219         va_list args;
220         va_start(args, fmt);
221         if (redir_output) {
222                 size_t const cur = strlen(firm_dbg_msg_buf);
223                 ir_vsnprintf(firm_dbg_msg_buf + cur, sizeof(firm_dbg_msg_buf) - cur, fmt, args);
224         } else {
225                 ir_vprintf(fmt, args);
226         }
227         va_end(args);
228 }
229
230 /**
231  * A new node is created.
232  *
233  * @param ctx   the hook context
234  * @param irg   the IR graph on which the node is created
235  * @param node  the new IR node that was created
236  */
237 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
238 {
239         bp_nr_t key, *elem;
240         (void) ctx;
241         (void) irg;
242
243         key.nr        = get_irn_node_nr(node);
244         key.bp.reason = BP_ON_NEW_THING;
245
246         elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
247         if (elem && elem->bp.active) {
248                 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
249                 firm_debug_break();
250         }
251 }
252
253 /**
254  * A node is replaced.
255  *
256  * @param ctx   the hook context
257  * @param old   the IR node the is replaced
258  * @param nw    the new IR node that will replace old
259  */
260 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
261 {
262         bp_nr_t key, *elem;
263         (void) ctx;
264
265         key.nr        = get_irn_node_nr(old);
266         key.bp.reason = BP_ON_REPLACE;
267
268         elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
269         if (elem && elem->bp.active) {
270                 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
271                 firm_debug_break();
272         }
273 }
274
275 /**
276  * A new node is lowered.
277  *
278  * @param ctx   the hook context
279  * @param node  the new IR node that will be lowered
280  */
281 static void dbg_lower(void *ctx, ir_node *node)
282 {
283         bp_nr_t key, *elem;
284         (void) ctx;
285
286         key.nr        = get_irn_node_nr(node);
287         key.bp.reason = BP_ON_LOWER;
288
289         elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
290         if (elem && elem->bp.active) {
291                 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
292                 firm_debug_break();
293         }
294 }
295
296 /**
297  * A graph will be deleted.
298  *
299  * @param ctx   the hook context
300  * @param irg   the IR graph that will be deleted
301  */
302 static void dbg_free_graph(void *ctx, ir_graph *irg)
303 {
304         (void) ctx;
305         {
306                 bp_nr_t key, *elem;
307                 key.nr        = get_irg_graph_nr(irg);
308                 key.bp.reason = BP_ON_REMIRG;
309
310                 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
311                 if (elem && elem->bp.active) {
312                         ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
313                         firm_debug_break();
314                 }
315         }
316         {
317                 bp_ident_t key, *elem;
318                 ir_entity *ent = get_irg_entity(irg);
319
320                 if (! ent)
321                         return;
322
323                 key.id        = get_entity_ident(ent);
324                 key.bp.reason = BP_ON_REMIRG;
325
326                 elem = (bp_ident_t*)set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
327                 if (elem && elem->bp.active) {
328                         dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
329                         firm_debug_break();
330                 }
331         }
332 }
333
334 /**
335  * An entity was created.
336  *
337  * @param ctx   the hook context
338  * @param ent   the newly created entity
339  */
340 static void dbg_new_entity(void *ctx, ir_entity *ent)
341 {
342         (void) ctx;
343         {
344                 bp_ident_t key, *elem;
345
346                 key.id        = get_entity_ident(ent);
347                 key.bp.reason = BP_ON_NEW_ENT;
348
349                 elem = (bp_ident_t*)set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
350                 if (elem && elem->bp.active) {
351                         ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
352                         firm_debug_break();
353                 }
354         }
355         {
356                 bp_nr_t key, *elem;
357
358                 key.nr        = get_entity_nr(ent);
359                 key.bp.reason = BP_ON_NEW_THING;
360
361                 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
362                 if (elem && elem->bp.active) {
363                         dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
364                         firm_debug_break();
365                 }
366         }
367 }
368
369 /**
370  * A type was created.
371  *
372  * @param ctx   the hook context
373  * @param tp    the newly created type
374  */
375 static void dbg_new_type(void *ctx, ir_type *tp)
376 {
377         (void) ctx;
378         {
379                 bp_nr_t key, *elem;
380
381                 key.nr        = get_type_nr(tp);
382                 key.bp.reason = BP_ON_NEW_THING;
383
384                 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
385                 if (elem && elem->bp.active) {
386                         ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
387                         firm_debug_break();
388                 }
389         }
390 }
391
392 /**
393  * Return the reason string.
394  */
395 static const char *reason_str(bp_reasons_t reason)
396 {
397         switch (reason) {
398         case BP_ON_NEW_THING: return "node, entity or type creation";
399         case BP_ON_REPLACE:   return "node replace";
400         case BP_ON_LOWER:     return "node lowering";
401         case BP_ON_REMIRG:    return "removing IRG";
402         case BP_ON_NEW_ENT:   return "entity creation";
403         case BP_MAX_REASON:   break;
404         }
405         panic("unsupported reason");
406 }
407
408 /**
409  * Compare two number breakpoints.
410  */
411 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
412 {
413         const bp_nr_t *e1 = (const bp_nr_t*)elt;
414         const bp_nr_t *e2 = (const bp_nr_t*)key;
415         (void) size;
416
417         return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
418 }
419
420 /**
421  * Compare two ident breakpoints.
422  */
423 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
424 {
425         const bp_ident_t *e1 = (const bp_ident_t*)elt;
426         const bp_ident_t *e2 = (const bp_ident_t*)key;
427         (void) size;
428
429         return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
430 }
431
432 /**
433  * Update the hooks.
434  */
435 static void update_hooks(breakpoint *bp)
436 {
437 #define CASE_ON(a, hook, handler)  case a: if (! IS_HOOKED(hook)) HOOK(hook, handler); break
438 #define CASE_OFF(a, hook) case a: if (IS_HOOKED(hook)) UNHOOK(hook); break
439
440         if (bp->active)
441                 ++num_active_bp[bp->reason];
442         else
443                 --num_active_bp[bp->reason];
444
445         if (num_active_bp[bp->reason] > 0) {
446                 /* register the hooks on demand */
447                 switch (bp->reason) {
448                 CASE_ON(BP_ON_REPLACE, hook_replace,    dbg_replace);
449                 CASE_ON(BP_ON_LOWER,   hook_lower,      dbg_lower);
450                 CASE_ON(BP_ON_REMIRG,  hook_free_graph, dbg_free_graph);
451                 CASE_ON(BP_ON_NEW_ENT, hook_new_entity, dbg_new_entity);
452                 case BP_ON_NEW_THING:
453                         if (!IS_HOOKED(hook_new_node))
454                                 HOOK(hook_new_node, dbg_new_node);
455                         if (!IS_HOOKED(hook_new_type))
456                                 HOOK(hook_new_type, dbg_new_type);
457                         if (!IS_HOOKED(hook_new_entity))
458                                 HOOK(hook_new_entity, dbg_new_entity);
459                         break;
460                 default:
461                         break;
462                 }
463         }
464         else {
465                 /* unregister the hook on demand */
466                 switch (bp->reason) {
467                 CASE_OFF(BP_ON_REPLACE,  hook_replace);
468                 CASE_OFF(BP_ON_LOWER,    hook_lower);
469                 CASE_OFF(BP_ON_REMIRG,   hook_free_graph);
470                 CASE_OFF(BP_ON_NEW_ENT,  hook_new_entity);
471                 case BP_ON_NEW_THING:
472                         if (IS_HOOKED(hook_new_node))
473                                 UNHOOK(hook_new_node);
474                         if (IS_HOOKED(hook_new_type))
475                                 UNHOOK(hook_new_type);
476                         if (IS_HOOKED(hook_new_entity))
477                                 UNHOOK(hook_new_entity);
478                         break;
479                 default:
480                         break;
481                 }
482         }
483 #undef CASE_ON
484 #undef CASE_OFF
485 }
486
487 /**
488  * Break if nr is reached.
489  */
490 static void break_on_nr(long nr, bp_reasons_t reason)
491 {
492         bp_nr_t key, *elem;
493
494         key.bp.kind   = BP_NR;
495         key.bp.bpnr   = 0;
496         key.bp.active = 1;
497         key.bp.reason = reason;
498         key.nr        = nr;
499
500         elem = (bp_nr_t*)set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
501
502         if (elem->bp.bpnr == 0) {
503                 /* new break point */
504                 elem->bp.bpnr = ++bp_num;
505                 elem->bp.next = bp_list;
506                 bp_list = &elem->bp;
507
508                 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
509
510                 update_hooks(&elem->bp);
511         }
512 }
513
514 /**
515  * Break if ident name is reached.
516  */
517 static void break_on_ident(const char *name, bp_reasons_t reason)
518 {
519         bp_ident_t key, *elem;
520
521         key.bp.kind   = BP_IDENT;
522         key.bp.bpnr   = 0;
523         key.bp.active = 1;
524         key.bp.reason = reason;
525         key.id        = new_id_from_str(name);
526
527         elem = (bp_ident_t*)set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
528
529         if (elem->bp.bpnr == 0) {
530                 /* new break point */
531                 elem->bp.bpnr = ++bp_num;
532                 elem->bp.next = bp_list;
533                 bp_list = &elem->bp;
534
535                 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
536
537                 update_hooks(&elem->bp);
538         }
539 }
540
541 /**
542  * Sets/resets the active flag of breakpoint bp.
543  */
544 static void bp_activate(unsigned bp, int active)
545 {
546         breakpoint *p;
547
548         for (p = bp_list; p; p = p->next) {
549                 if (p->bpnr == bp) {
550                         if (p->active != active) {
551                                 p->active = active;
552                                 update_hooks(p);
553                         }
554
555                         dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
556                         return;
557                 }
558         }
559         dbg_printf("Error: Firm BP %u not exists.\n", bp);
560 }
561
562
563 /**
564  * Show a list of supported commands
565  */
566 static void show_commands(void)
567 {
568         dbg_printf("Internal Firm debugger extension commands:\n"
569                 "init                  break after initialization\n"
570                 "create nr             break if node nr was created\n"
571                 "replace nr            break if node nr is replaced by another node\n"
572                 "lower nr              break before node nr is lowered\n"
573                 "remirg nr|name        break if the irg of nr or entity name is deleted\n"
574                 "newent nr|name        break if the entity nr or name was created\n"
575                 "newtype nr|name       break if the type nr or name was created\n"
576                 "bp                    show all breakpoints\n"
577                 "enable nr             enable breakpoint nr\n"
578                 "disable nr            disable breakpoint nr\n"
579                 "showtype nr|name      show content of the type nr or name\n"
580                 "showent nr|name       show content of the entity nr or name\n"
581                 "setmask name msk      sets the debug module name to mask msk\n"
582                 "setlvl  name lvl      sets the debug module name to level lvl\n"
583                 "setoutfile name file  redirects debug output of module name to file\n"
584                 "irgname name          prints address and graph number of a method given by its name\n"
585                 "irgldname ldname      prints address and graph number of a method given by its ldname\n"
586                 "randnodenr            randomize initial node number\n"
587                 "help                  list all commands\n"
588                 );
589 }
590
591 /**
592  * Shows all Firm breakpoints.
593  */
594 static void show_bp(void)
595 {
596         breakpoint *p;
597         bp_nr_t  *node_p;
598         bp_ident_t *ident_p;
599         int have_one = 0;
600
601         dbg_printf("Firm Breakpoints:");
602         for (p = bp_list; p; p = p->next) {
603                 have_one = 1;
604                 dbg_printf("+\n  BP %u: ", p->bpnr);
605
606                 switch (p->kind) {
607                 case BP_NR:
608                         node_p = (bp_nr_t *)p;
609                         dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
610                         break;
611
612                 case BP_IDENT:
613                         ident_p = (bp_ident_t *)p;
614                         dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
615                         break;
616                 }
617
618                 dbg_printf(p->active ? "+enabled" : "+disabled");
619         }
620         dbg_printf(have_one ? "+\n" : "+ NONE\n");
621 }
622
623 /**
624  * firm_dbg_register() expects that the name is stored persistent.
625  * So we need this little helper function
626  */
627 static firm_dbg_module_t *dbg_register(const char *name)
628 {
629         ident *id = new_id_from_str(name);
630
631         return firm_dbg_register(get_id_str(id));
632 }
633
634 /**
635  * Sets the debug mask of module name to lvl
636  */
637 static void set_dbg_level(const char *name, unsigned lvl)
638 {
639         firm_dbg_module_t *module = dbg_register(name);
640
641         if (firm_dbg_get_mask(module) != lvl) {
642                 firm_dbg_set_mask(module, lvl);
643
644                 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
645         }
646 }
647
648 /**
649  * Redirects the debug output of module name to fname
650  */
651 static void set_dbg_outfile(const char *name, const char *fname)
652 {
653         firm_dbg_module_t *module = dbg_register(name);
654         FILE *f = fopen(fname, "w");
655
656         if (! f) {
657                 perror(fname);
658                 return;
659         }
660
661         firm_dbg_set_file(module, f);
662         dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
663 }
664
665 /**
666  * Show info about a firm thing.
667  */
668 static void show_firm_object(void *firm_thing)
669 {
670         FILE *f = stdout;
671
672         if (firm_thing == NULL) {
673                 fprintf(f, "<NULL>\n");
674                 return;
675         }
676         switch (get_kind(firm_thing)) {
677         case k_BAD:
678                 fprintf(f, "BAD: (%p)\n", firm_thing);
679                 break;
680         case k_entity:
681                 dump_entity_to_file(f, (ir_entity*)firm_thing);
682                 break;
683         case k_type:
684                 dump_type_to_file(f, (ir_type*)firm_thing);
685                 break;
686         case k_ir_graph:
687         case k_ir_node:
688         case k_ir_mode:
689         case k_ir_op:
690         case k_tarval:
691         case k_ir_loop:
692         case k_ir_compound_graph_path:
693         case k_ir_prog:
694                 fprintf(f, "NIY\n");
695                 break;
696         default:
697                 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
698         }
699 }
700
701 /**
702  * Find a firm type by its number.
703  */
704 static ir_type *find_type_nr(long nr)
705 {
706         int i, n = get_irp_n_types();
707         ir_type *tp;
708
709         for (i = 0; i < n; ++i) {
710                 tp = get_irp_type(i);
711                 if (get_type_nr(tp) == nr)
712                         return tp;
713         }
714         tp = get_glob_type();
715         if (get_type_nr(tp) == nr)
716                 return tp;
717         return NULL;
718 }
719
720 /**
721  * Find a firm type by its name.
722  */
723 static ir_type *find_type_name(const char *name)
724 {
725         int i, n = get_irp_n_types();
726         ir_type *tp;
727
728         for (i = 0; i < n; ++i) {
729                 tp = get_irp_type(i);
730                 if (!is_compound_type(tp))
731                         continue;
732
733                 if (strcmp(get_compound_name(tp), name) == 0)
734                         return tp;
735         }
736         tp = get_glob_type();
737         if (strcmp(get_compound_name(tp), name) == 0)
738                 return tp;
739         return NULL;
740 }
741
742 /** The environment for the entity search functions. */
743 typedef struct find_env {
744         union {
745                 long        nr;   /**< the number that is searched for */
746                 const char *name; /**< the name that is searched for */
747         } u;
748         ir_entity *res;     /**< the result */
749 } find_env_t;
750
751 /**
752  * Type-walker: Find an entity with given number.
753  */
754 static void check_ent_nr(type_or_ent tore, void *ctx)
755 {
756         find_env_t *env = (find_env_t*)ctx;
757
758         if (is_entity(tore.ent)) {
759                 if (get_entity_nr(tore.ent) == env->u.nr) {
760                         env->res = tore.ent;
761                 }
762         }
763 }
764
765 /**
766  * Type-walker: Find an entity with given name.
767  */
768 static void check_ent_name(type_or_ent tore, void *ctx)
769 {
770         find_env_t *env = (find_env_t*)ctx;
771
772         if (is_entity(tore.ent))
773                 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
774                         env->res = tore.ent;
775                 }
776 }
777
778 /**
779  * Find a firm entity by its number.
780  */
781 static ir_entity *find_entity_nr(long nr)
782 {
783         find_env_t env;
784
785         env.u.nr = nr;
786         env.res  = NULL;
787         type_walk(check_ent_nr, NULL, &env);
788         return env.res;
789 }
790
791 /**
792  * Find a firm entity by its name.
793  */
794 static ir_entity *find_entity_name(const char *name)
795 {
796         find_env_t env;
797
798         env.u.name = name;
799         env.res    = NULL;
800         type_walk(check_ent_name, NULL, &env);
801         return env.res;
802 }
803
804 /**
805  * Search methods for a name.
806  */
807 static void show_by_name(type_or_ent tore, void *env)
808 {
809         ident *id = (ident *)env;
810
811         if (is_entity(tore.ent)) {
812                 ir_entity *ent = tore.ent;
813
814                 if (is_method_entity(ent)) {
815                         if (get_entity_ident(ent) == id) {
816                                 ir_type *owner = get_entity_owner(ent);
817                                 ir_graph *irg = get_entity_irg(ent);
818
819                                 if (owner != get_glob_type()) {
820                                         printf("%s::%s", get_compound_name(owner), get_id_str(id));
821                                 } else {
822                                         printf("%s", get_id_str(id));
823                                 }
824                                 if (irg)
825                                         printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
826                                 else
827                                         printf(" NULL\n");
828                         }
829                 }
830         }
831 }
832
833 /**
834  * Search methods for a ldname.
835  */
836 static void show_by_ldname(type_or_ent tore, void *env)
837 {
838         ident *id = (ident *)env;
839
840         if (is_entity(tore.ent)) {
841                 ir_entity *ent = tore.ent;
842
843                 if (is_method_entity(ent)) {
844                         if (get_entity_ld_ident(ent) == id) {
845                                 ir_type *owner = get_entity_owner(ent);
846                                 ir_graph *irg = get_entity_irg(ent);
847
848                                 if (owner != get_glob_type()) {
849                                         printf("%s::%s", get_compound_name(owner), get_id_str(id));
850                                 } else {
851                                         printf("%s", get_id_str(id));
852                                 }
853                                 if (irg)
854                                         printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
855                                 else
856                                         printf(" NULL\n");
857                         }
858                 }
859         }
860 }
861
862 /**
863  * prints the address and graph number of all irgs with given name
864  */
865 static void irg_name(const char *name)
866 {
867         ident *id = new_id_from_str(name);
868
869         type_walk(show_by_name, NULL, (void *)id);
870 }
871
872 /**
873  * prints the address and graph number of all irgs with given ld_name
874  */
875 static void irg_ld_name(const char *name)
876 {
877         ident *id = new_id_from_str(name);
878
879         type_walk(show_by_ldname, NULL, (void *)id);
880 }
881
882 enum tokens {
883         first_token = 256,
884         tok_bp = first_token,
885         tok_create,
886         tok_disable,
887         tok_dumpfilter,
888         tok_enable,
889         tok_help,
890         tok_init,
891         tok_irgldname,
892         tok_irgname,
893         tok_lower,
894         tok_newent,
895         tok_remirg,
896         tok_replace,
897         tok_setlvl,
898         tok_setmask,
899         tok_setoutfile,
900         tok_showent,
901         tok_showtype,
902         tok_randnodenr,
903         tok_identifier,
904         tok_number,
905         tok_eof,
906         tok_error
907 };
908
909 static const char *reserved[] = {
910         "bp",
911         "create",
912         "disable",
913         "dumpfilter",
914         "enable",
915         "help",
916         "init",
917         "irgldname",
918         "irgname",
919         "lower",
920         "newent",
921         "remirg",
922         "replace",
923         "setlvl",
924         "setmask",
925         "setoutfile",
926         "showent",
927         "showtype",
928         "randnodenr",
929 };
930
931 /**
932  * The Lexer data.
933  */
934 static struct lexer {
935         int has_token;        /**< set if a token is cached. */
936         unsigned cur_token;   /**< current token. */
937         unsigned number;      /**< current token attribute. */
938         const char *s;        /**< current token attribute. */
939         size_t len;           /**< current token attribute. */
940
941         const char *curr_pos;
942         const char *end_pos;
943         const char *tok_start;
944 } lexer;
945
946 /**
947  * Initialize the lexer.
948  */
949 static void init_lexer(const char *input)
950 {
951         lexer.has_token = 0;
952         lexer.curr_pos  = input;
953         lexer.end_pos   = input + strlen(input);
954 }
955
956
957 /**
958  * Get the next char from the input.
959  */
960 static char next_char(void)
961 {
962         if (lexer.curr_pos >= lexer.end_pos)
963                 return '\0';
964         return *lexer.curr_pos++;
965 }
966
967 #define unput()    if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
968
969 #undef MIN
970 #define MIN(a, b) (a) < (b) ? (a) : (b)
971
972 /**
973  * The lexer.
974  */
975 static unsigned get_token(void)
976 {
977         char c;
978         size_t i;
979
980         /* skip white space */
981         do {
982                 c = next_char();
983         } while (c != '\0' && isspace((unsigned char)c));
984
985         lexer.tok_start = lexer.curr_pos - 1;
986         if (c == '.' || isalpha((unsigned char)c)) {
987                 /* command begins here */
988                 int         len = 0;
989                 const char* tok_start;
990
991                 do {
992                         c = next_char();
993                         ++len;
994                 } while (isgraph((unsigned char)c));
995                 unput();
996
997                 tok_start = lexer.tok_start;
998                 if (*tok_start == '.') {
999                         ++tok_start;
1000                         --len;
1001                 }
1002                 for (i = ARRAY_SIZE(reserved); i-- != 0;) {
1003                         if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
1004                                 return first_token + i;
1005                 }
1006
1007                 /* identifier */
1008                 lexer.s   = lexer.tok_start;
1009                 lexer.len = lexer.curr_pos - lexer.s;
1010                 return tok_identifier;
1011         } else if (isdigit((unsigned char)c) || c == '-') {
1012                 unsigned number = 0;
1013                 unsigned sign   = 0;
1014
1015                 /* we support negative numbers as well, so one can easily set all bits with -1 */
1016                 if (c == '-') {
1017                         sign = 1;
1018                         c    = next_char();
1019                 }
1020
1021                 if (c == '0') {
1022                         c = next_char();
1023
1024                         if (c == 'x' || c == 'X') {
1025                                 for (;;) {
1026                                         c = next_char();
1027
1028                                         if (! isxdigit((unsigned char)c))
1029                                                 break;
1030                                         if (isdigit((unsigned char)c))
1031                                                 number = (number << 4) | (c - '0');
1032                                         else
1033                                                 number = (number << 4) | (toupper((unsigned char)c) - 'A' + 10);
1034                                 }
1035                                 unput();
1036                                 lexer.number = number;
1037                                 return tok_number;
1038                         }
1039                 }
1040                 for (;;) {
1041                         if (! isdigit((unsigned char)c))
1042                                 break;
1043                         number = number * 10 + (c - '0');
1044                         c = next_char();
1045                 }
1046                 unput();
1047                 lexer.number = sign ? 0 - number : number;
1048                 return tok_number;
1049         }
1050         else if (c == '\0')
1051                 return tok_eof;
1052         return c;
1053 }
1054
1055 void firm_debug(const char *cmd)
1056 {
1057         char name[1024], fname[1024];
1058         size_t len;
1059
1060         init_lexer(cmd);
1061
1062         for (;;) {
1063                 unsigned token;
1064
1065                 token = get_token();
1066
1067                 switch (token) {
1068                 case tok_eof:
1069                         goto leave;
1070
1071                 case tok_create:
1072                         token = get_token();
1073                         if (token != tok_number)
1074                                 goto error;
1075                         break_on_nr(lexer.number, BP_ON_NEW_THING);
1076                         break;
1077
1078                 case tok_replace:
1079                         token = get_token();
1080                         if (token != tok_number)
1081                                 goto error;
1082                         break_on_nr(lexer.number, BP_ON_REPLACE);
1083                         break;
1084
1085                 case tok_lower:
1086                         token = get_token();
1087                         if (token != tok_number)
1088                                 goto error;
1089                         break_on_nr(lexer.number, BP_ON_LOWER);
1090                         break;
1091
1092                 case tok_remirg:
1093                         token = get_token();
1094
1095                         if (token == tok_number)
1096                                 break_on_nr(lexer.number, BP_ON_REMIRG);
1097                         else if (token == tok_identifier) {
1098                                 len = MIN(lexer.len, 1023);
1099                                 strncpy(name, lexer.s, len);
1100                                 name[len] = '\0';
1101                                 break_on_ident(name, BP_ON_REMIRG);
1102                         } else
1103                                 goto error;
1104                         break;
1105
1106                 case tok_newent:
1107                         token = get_token();
1108
1109                         if (token == tok_number)
1110                                 break_on_nr(lexer.number, BP_ON_NEW_THING);
1111                         else if (token == tok_identifier) {
1112                                 len = MIN(lexer.len, 1023);
1113                                 strncpy(name, lexer.s, len);
1114                                 name[len] = '\0';
1115                                 break_on_ident(name, BP_ON_NEW_ENT);
1116                         } else
1117                                 goto error;
1118                         break;
1119
1120                 case tok_showtype:
1121                         token = get_token();
1122
1123                         if (token == tok_number)
1124                                 show_firm_object(find_type_nr(lexer.number));
1125                         else if (token == tok_identifier) {
1126                                 len = MIN(lexer.len, 1023);
1127                                 strncpy(name, lexer.s, len);
1128                                 name[len] = '\0';
1129                                 show_firm_object(find_type_name(name));
1130                         } else
1131                                 goto error;
1132                         break;
1133
1134                 case tok_showent:
1135                         token = get_token();
1136
1137                         if (token == tok_number)
1138                                 show_firm_object(find_entity_nr(lexer.number));
1139                         else if (token == tok_identifier) {
1140                                 len = MIN(lexer.len, 1023);
1141                                 strncpy(name, lexer.s, len);
1142                                 name[len] = '\0';
1143                                 show_firm_object(find_entity_name(name));
1144                         } else
1145                                 goto error;
1146                         break;
1147
1148                 case tok_init:
1149                         break_on_init = 1;
1150                         break;
1151
1152                 case tok_bp:
1153                         show_bp();
1154                         break;
1155
1156                 case tok_enable:
1157                         token = get_token();
1158                         if (token != tok_number)
1159                                 goto error;
1160                         bp_activate(lexer.number, 1);
1161                         break;
1162
1163                 case tok_disable:
1164                         token = get_token();
1165                         if (token != tok_number)
1166                                 goto error;
1167                         bp_activate(lexer.number, 0);
1168                         break;
1169
1170                 case tok_setmask:
1171                         token = get_token();
1172                         if (token != tok_identifier)
1173                                 goto error;
1174                         len = MIN(lexer.len, 1023);
1175                         strncpy(name, lexer.s, len);
1176                         name[len] = '\0';
1177
1178                         token = get_token();
1179                         if (token != tok_number)
1180                                 goto error;
1181                         set_dbg_level(name, lexer.number);
1182                         break;
1183
1184                 case tok_setlvl:
1185                         token = get_token();
1186                         if (token != tok_identifier)
1187                                 goto error;
1188                         len = MIN(lexer.len, 1023);
1189                         strncpy(name, lexer.s, len);
1190                         name[len] = '\0';
1191
1192                         token = get_token();
1193                         if (token != tok_number)
1194                                 goto error;
1195                         set_dbg_level(name, (1 << lexer.number) - 1);
1196                         break;
1197
1198                 case tok_setoutfile:
1199                         token = get_token();
1200                         if (token != tok_identifier)
1201                                 goto error;
1202                         len = MIN(lexer.len, 1023);
1203                         strncpy(name, lexer.s, len);
1204                         name[len] = '\0';
1205
1206                         token = get_token();
1207                         if (token != tok_identifier)
1208                                 goto error;
1209                         len = MIN(lexer.len, 1023);
1210                         strncpy(fname, lexer.s, len);
1211                         fname[len] = '\0';
1212                         set_dbg_outfile(name, fname);
1213                         break;
1214
1215                 case tok_irgname:
1216                         token = get_token();
1217                         if (token != tok_identifier)
1218                                 goto error;
1219                         len = MIN(lexer.len, 1023);
1220                         strncpy(name, lexer.s, len);
1221                         name[len] = '\0';
1222                         irg_name(name);
1223                         break;
1224
1225                 case tok_randnodenr:
1226                         dbg_printf("Randomizing initial node number\n");
1227                         srand(time(0));
1228                         irp->max_node_nr += rand() % 6666;
1229                         break;
1230
1231                 case tok_irgldname:
1232                         token = get_token();
1233                         if (token != tok_identifier)
1234                                 goto error;
1235                         len = MIN(lexer.len, 1023);
1236                         strncpy(name, lexer.s, len);
1237                         name[len] = '\0';
1238                         irg_ld_name(name);
1239                         break;
1240
1241                 case tok_dumpfilter:
1242                         token = get_token();
1243                         if (token != tok_identifier)
1244                                 goto error;
1245                         len = MIN(lexer.len, 1023);
1246                         strncpy(name, lexer.s, len);
1247                         name[len] = '\0';
1248                         ir_set_dump_filter(name);
1249                         break;
1250
1251                 case tok_help:
1252                         show_commands();
1253                         break;
1254
1255                 case tok_error:
1256                 default:
1257 error:
1258                         printf("Error: before %s\n", lexer.tok_start);
1259                         show_commands();
1260                         goto leave;
1261                 }
1262
1263                 token = get_token();
1264                 if (token == tok_eof)
1265                         break;
1266                 if (token != ';')
1267                         goto error;
1268         }
1269 leave:
1270         ;
1271 }
1272
1273 void firm_init_debugger(void)
1274 {
1275         char *env;
1276
1277         bp_numbers = new_set(cmp_nr_bp, 8);
1278         bp_idents  = new_set(cmp_ident_bp, 8);
1279
1280         env = getenv("FIRMDBG");
1281
1282         is_active = 1;
1283
1284         if (env)
1285                 firm_debug(env);
1286
1287         if (break_on_init)
1288                 firm_debug_break();
1289 }
1290
1291 void firm_finish_debugger(void)
1292 {
1293         del_set(bp_numbers);
1294         del_set(bp_idents);
1295 }
1296
1297 /**
1298  * A gdb helper function to print firm objects.
1299  */
1300 const char *gdb_node_helper(void *firm_object)
1301 {
1302         static char buf[1024];
1303         ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1304         return buf;
1305 }
1306
1307 const char *gdb_tarval_helper(void *tv_object)
1308 {
1309         static char buf[1024];
1310         ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1311         return buf;
1312 }
1313
1314 const char *gdb_out_edge_helper(const ir_node *node)
1315 {
1316         static char buf[4*1024];
1317         char *b = buf;
1318         size_t l;
1319         size_t len = sizeof(buf);
1320         const ir_edge_t *edge;
1321         foreach_out_edge(node, edge) {
1322                 ir_node *n = get_edge_src_irn(edge);
1323
1324                 ir_snprintf(b, len, "%+F  ", n);
1325                 l = strlen(b);
1326                 len -= l;
1327                 b += l;
1328         }
1329
1330         return buf;
1331 }
1332
1333 #else
1334
1335 /* some picky compiler do not allow empty files */
1336 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1337
1338 #endif /* NDEBUG */
1339
1340 /**
1341  * @page debugger   The Firm debugger extension
1342  *
1343  * Firm contains a debugger extension. This allows to set debugger breakpoints
1344  * an various events.
1345  * The extension uses a text interface which can be accessed from most debuggers.
1346  * More than one command can be given separated by ';'.
1347  *
1348  * @section sec_cmd Supported commands
1349  *
1350  * Historically all debugger commands start with a dot.  This isn't needed in newer
1351  * versions, but still supported, ie the commands ".init" and "init" are equal.
1352  * The following commands are currently supported:
1353  *
1354  * @b init
1355  *
1356  * Break immediately after the debugger extension was initialized.
1357  * Typically this command is used in the environment to stop the execution
1358  * of a Firm compiler right after the initialization, like this:
1359  *
1360  * $export FIRMDBG=".init"
1361  *
1362  * @b create nr
1363  *
1364  * Break if a new IR-node with node number nr was created.
1365  * Typically used to find the place where wrong nodes are created.
1366  *
1367  * @b replace nr
1368  *
1369  * Break before IR-node with node number nr is replaced by another node.
1370  *
1371  * @b lower nr
1372  *
1373  * Break before IR-node with node number nr is lowered.
1374  *
1375  * @b remirg nr
1376  *
1377  * Break if the irg with graph number nr is deleted.
1378  *
1379  * @b remirg name
1380  *
1381  * Break if the irg of entity name is deleted.
1382  *
1383  * @b newent nr
1384  *
1385  * Break if the entity with number nr was created.
1386  *
1387  * @b newent name
1388  *
1389  * Break if the entity name was created.
1390  *
1391  * @b newtype nr
1392  *
1393  * Break if the type with number nr was created.
1394  *
1395  * @b newtype name
1396  *
1397  * Break if the type name was created.
1398  *
1399  * @b bp
1400  *
1401  * Show all Firm internal breakpoints.
1402  *
1403  * @b enable nr
1404  *
1405  * Enables breakpoint nr.
1406  *
1407  * @b disable nr
1408  *
1409  * Disables breakpoint nr.
1410  *
1411  * @b showent nr
1412  *
1413  * Show the content of entity nr.
1414  *
1415  * @b showent name
1416  *
1417  * Show the content of entity name.
1418  *
1419  * @b showtype nr
1420  *
1421  * Show the content of type nr.
1422  *
1423  * @b showtype name
1424  *
1425  * Show the content of type name.
1426  *
1427  * @b setmask name msk
1428  *
1429  * Sets the debug module name to mask msk.
1430  *
1431  * @b setlvl name lvl
1432  *
1433  * Sets the debug module name to level lvl.
1434  *
1435  * @b setoutfile name file
1436  *
1437  * Redirects debug output of module name to file.
1438  *
1439  * @b irgname name
1440  *
1441  * Prints address and graph number of a method given by its name.
1442  *
1443  * @b irgldname name
1444  *
1445  * Prints address and graph number of a method given by its linker name.
1446  *
1447  * @b help
1448  *
1449  * List all commands.
1450  *
1451  *
1452  * The Firm debugger extension can be accessed using the function firm_debug().
1453  * The following example shows how to set a creation breakpoint in GDB when
1454  * node 2101 is created.
1455  *
1456  * -# set FIRMDBG="init"
1457  * -# start gdb with your compiler
1458  * -# after gdb breaks, issue
1459  *
1460  * call firm_debug("create 2101")
1461  *
1462  * On the console the following text should be issued:
1463  *
1464  * Firm BP 1: creation of Node 2101
1465  *
1466  *
1467  * @section gdb_macro GDB macro
1468  *
1469  * Add the following to your .gdbinit file:
1470  * @code
1471  #
1472  # define firm "cmd"  Firm debugger extension
1473  #
1474  define firm
1475  call firm_debug($arg0)
1476  end
1477  * @endcode
1478  *
1479  * Then, all Firm debugger extension commands can be accessed in the gdb
1480  * console using the firm prefix, eg.:
1481  *
1482  * firm "create 2101"
1483  *
1484  * firm "help"
1485  */