removed debug output
[libfirm] / ir / debug / debugger.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/debug/debugger.c
4  * Purpose:     Helper function for integerated debug support
5  * Author:      Michael Beck
6  * Modified by:
7  * Created:     2005
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 2001-2006 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15
16 #ifndef NDEBUG
17
18 #ifdef _WIN32
19 #define WIN32_LEAN_AND_MEAN
20 #include <windows.h>
21 #endif
22
23 #ifdef HAVE_STDLIB_H
24 #include <stdlib.h>
25 #endif
26
27 #include <stdio.h>
28 #include <signal.h>
29
30 #ifdef HAVE_STRING_H
31 #include <string.h>
32 #endif
33
34 #include <ctype.h>
35
36 #include "set.h"
37 #include "ident.h"
38 #include "irhooks.h"
39 #include "irgraph_t.h"
40 #include "entity_t.h"
41 #include "irprintf.h"
42 #include "typewalk.h"
43 #include "irdump.h"
44 #include "debug.h"
45
46 #ifdef _WIN32
47 /* Break into the debugger. The Win32 way. */
48 void firm_debug_break(void) {
49   DebugBreak();
50 }
51 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
52 /* Break into the debugger. The ia32/x86_64 way under GCC. */
53 void firm_debug_break(void) {
54   __asm__ __volatile__("int3");
55 }
56 #else
57 /* Break into the debugger. Poor Unix way. */
58 void firm_debug_break(void) {
59   raise(SIGINT);
60 }
61 #endif /* _WIN32 */
62
63 /** supported breakpoint kinds */
64 typedef enum {
65   BP_NR    = 'n',   /**< break on node number. */
66   BP_IDENT = 'i'    /**< break on ident. */
67 } bp_kind;
68
69 /**
70  * Reasons for node number breakpoints.
71  */
72 typedef enum _bp_reasons_t {
73   BP_ON_NEW_NODE,    /**< break if node with number is created */
74   BP_ON_REPLACE,     /**< break if node with number is replaced */
75   BP_ON_LOWER,       /**< break if node with number is lowered */
76   BP_ON_REMIRG,      /**< break if an IRG is removed */
77   BP_ON_NEW_ENT,     /**< break if a new entity is created */
78   BP_ON_NEW_TYPE,    /**< break if a new type is created */
79   BP_MAX_REASON
80 } bp_reasons_t;
81
82 /** A breakpoint. */
83 typedef struct _breakpoint {
84   bp_kind      kind;        /**< the kind of this break point */
85   unsigned     bpnr;        /**< break point number */
86   int          active;      /**< non-zero, if this break point is active */
87   bp_reasons_t reason;      /**< reason for the breakpoint */
88   struct _breakpoint *next; /**< link to the next one */
89 } breakpoint;
90
91 /** A number breakpoint. */
92 typedef struct {
93   breakpoint   bp;       /**< the breakpoint data */
94   long         nr;       /**< the node number */
95 } bp_nr_t;
96
97 /** Calculate the hash value for a node breakpoint. */
98 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
99
100 /** An ident breakpoint. */
101 typedef struct {
102   breakpoint   bp;       /**< the breakpoint data */
103   ident        *id;      /**< the ident */
104 } bp_ident_t;
105
106 /** Calculate the hash value for an ident breakpoint. */
107 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
108
109 /** The set containing the breakpoints on node numbers. */
110 static set *bp_numbers;
111
112 /** The set containing the breakpoints on idents. */
113 static set *bp_idents;
114
115 /**< the list of all breakpoints */
116 static breakpoint *bp_list;
117
118 /** number of the current break point */
119 static unsigned bp_num = 0;
120
121 /** set if break on init command was issued. */
122 static int break_on_init = 0;
123
124 /** the hook entries for the Firm debugger module. */
125 static hook_entry_t debugger_hooks[hook_last];
126
127 /** number of active breakpoints to maintain hooks. */
128 static unsigned num_active_bp[BP_MAX_REASON];
129
130 /**
131  * The debug message buffer
132  */
133 static char firm_dbg_msg_buf[2048];
134
135 /**
136  * If set, the debug extension writes all output to the
137  * firm_dbg_msg_buf buffer
138  */
139 static int redir_output = 0;
140
141 /**
142  * Is set to one, if the debug extension is active
143  */
144 static int is_active = 0;
145
146 /** hook the hook h with function fkt. */
147 #define HOOK(h, fkt) \
148 do {                                    \
149   debugger_hooks[h].hook._##h = fkt;    \
150   register_hook(h, &debugger_hooks[h]); \
151 } while(0)
152
153 /** unhook the hook h */
154 #define UNHOOK(h) \
155 do {                                      \
156   unregister_hook(h, &debugger_hooks[h]); \
157   debugger_hooks[h].hook._##h = NULL;     \
158 } while(0)
159
160 /** returns non-zero if a entry hook h is used */
161 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
162
163 /* some macros needed to create the info string */
164 #define _DBG_VERSION(major, minor)  #major "." #minor
165 #define DBG_VERSION(major, minor)   _DBG_VERSION(major, minor)
166 #define API_VERSION(major, minor)   "API:" DBG_VERSION(major, minor)
167
168 /* the API version: change if needed */
169 #define FIRM_DBG_MAJOR  1
170 #define FIRM_DBG_MINOR  0
171
172 /** for automatic detection of the debug extension */
173 static const char *firm_debug_info_string =
174   API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR)
175   ;
176
177 /**
178  * Returns non-zero, if the debug extension is active
179  */
180 int firm_debug_active(void) {
181   return is_active;
182 }  /* firm_debug_active */
183
184 /**
185  * Reset the debug text buffer.
186  */
187 static void reset_dbg_buf(void) {
188   firm_dbg_msg_buf[0] = '\0';
189 }  /* reset_dbg_buf */
190
191 /**
192  * Add text to the debug text buffer.
193  */
194 static void add_to_dbg_buf(const char *buf) {
195   strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
196 }  /* add_to_dbg_buf */
197
198 /**
199  * Return the content of the debug text buffer.
200  *
201  * To be called from the debugger.
202  */
203 const char *firm_debug_text(void) {
204   firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
205   return firm_dbg_msg_buf;
206 }  /* firm_debug_text */
207
208 /**
209  * debug output
210  */
211 static void dbg_printf(const char *fmt, ...)
212 {
213   char buf[1024];
214
215   va_list args;
216   va_start(args, fmt);
217
218   if (fmt[0] != '+')
219     reset_dbg_buf();
220   else
221     ++fmt;
222
223   ir_vsnprintf(buf, sizeof(buf), fmt, args);
224   va_end(args);
225
226   if (redir_output)
227     add_to_dbg_buf(buf);
228   else
229     puts(buf);
230 }  /* dbg_printf */
231
232 /**
233  * A new node is created.
234  *
235  * @param ctx   the hook context
236  * @param irg   the IR graph on which the node is created
237  * @param node  the new IR node that was created
238  */
239 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
240 {
241   bp_nr_t key, *elem;
242
243   key.nr        = get_irn_node_nr(node);
244   key.bp.reason = BP_ON_NEW_NODE;
245
246   elem = 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 }  /* dbg_new_node */
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
264   key.nr        = get_irn_node_nr(old);
265   key.bp.reason = BP_ON_REPLACE;
266
267   elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
268   if (elem && elem->bp.active) {
269     dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
270     firm_debug_break();
271   }
272 }  /* dbg_replace */
273
274 /**
275  * A new node is lowered.
276  *
277  * @param ctx   the hook context
278  * @param node  the new IR node that will be lowered
279  */
280 static void dbg_lower(void *ctx, ir_node *node)
281 {
282   bp_nr_t key, *elem;
283
284   key.nr        = get_irn_node_nr(node);
285   key.bp.reason = BP_ON_LOWER;
286
287   elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
288   if (elem && elem->bp.active) {
289     dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
290     firm_debug_break();
291   }
292 }  /* dbg_lower */
293
294 /**
295  * A graph will be deleted.
296  *
297  * @param ctx   the hook context
298  * @param irg   the IR graph that will be deleted
299  */
300 static void dbg_free_graph(void *ctx, ir_graph *irg)
301 {
302   {
303     bp_nr_t key, *elem;
304     key.nr        = get_irg_graph_nr(irg);
305     key.bp.reason = BP_ON_REMIRG;
306
307     elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
308     if (elem && elem->bp.active) {
309       ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
310       firm_debug_break();
311     }
312   }
313   {
314     bp_ident_t key, *elem;
315     entity *ent = get_irg_entity(irg);
316
317     if (! ent)
318       return;
319
320     key.id        = get_entity_ident(ent);
321     key.bp.reason = BP_ON_REMIRG;
322
323     elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
324     if (elem && elem->bp.active) {
325       dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
326       firm_debug_break();
327     }
328   }
329 }  /* dbg_free_graph */
330
331 /**
332  * An entity was created.
333  *
334  * @param ctx   the hook context
335  * @param ent   the newly created entity
336  */
337 static void dbg_new_entity(void *ctx, entity *ent)
338 {
339   {
340     bp_ident_t key, *elem;
341
342     key.id        = get_entity_ident(ent);
343     key.bp.reason = BP_ON_NEW_ENT;
344
345     elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
346     if (elem && elem->bp.active) {
347       ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
348       firm_debug_break();
349     }
350   }
351   {
352     bp_nr_t key, *elem;
353
354     key.nr        = get_entity_nr(ent);
355     key.bp.reason = BP_ON_NEW_ENT;
356
357     elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
358     if (elem && elem->bp.active) {
359       dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
360       firm_debug_break();
361     }
362   }
363 }  /* dbg_new_entity */
364
365 /**
366  * A type was created.
367  *
368  * @param ctx   the hook context
369  * @param tp    the newly created type
370  */
371 static void dbg_new_type(void *ctx, ir_type *tp)
372 {
373   {
374     bp_nr_t key, *elem;
375
376     key.nr        = get_type_nr(tp);
377     key.bp.reason = BP_ON_NEW_TYPE;
378
379     elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
380     if (elem && elem->bp.active) {
381       ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
382       firm_debug_break();
383     }
384   }
385   {
386     bp_ident_t key, *elem;
387
388     key.id        = get_type_ident(tp);
389     key.bp.reason = BP_ON_NEW_TYPE;
390
391     elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
392     if (elem && elem->bp.active) {
393       dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
394       firm_debug_break();
395     }
396   }
397 }  /* dbg_new_type */
398
399 /**
400  * Return the reason string.
401  */
402 static const char *reason_str(bp_reasons_t reason)
403 {
404   switch (reason) {
405   case BP_ON_NEW_NODE: return "node creation";
406   case BP_ON_REPLACE:  return "node replace";
407   case BP_ON_LOWER:    return "node lowering";
408   case BP_ON_REMIRG:   return "removing IRG";
409   case BP_ON_NEW_ENT:  return "entity creation";
410   case BP_ON_NEW_TYPE: return "type creation";
411   default:             assert(0);
412   }
413   return "unknown";
414 }  /* reason_str */
415
416 /**
417  * Compare two number breakpoints.
418  */
419 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
420 {
421   const bp_nr_t *e1 = elt;
422   const bp_nr_t *e2 = key;
423
424   return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
425 }  /* cmp_nr_bp */
426
427 /**
428  * Compare two ident breakpoints.
429  */
430 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
431 {
432   const bp_ident_t *e1 = elt;
433   const bp_ident_t *e2 = key;
434
435   return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
436 }  /* cmp_ident_bp */
437
438 /**
439  * Update the hooks.
440  */
441 static void update_hooks(breakpoint *bp)
442 {
443 #define CASE_ON(a, b)  case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
444 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
445
446   if (bp->active)
447     ++num_active_bp[bp->reason];
448   else
449     --num_active_bp[bp->reason];
450
451   if (num_active_bp[bp->reason] > 0) {
452     /* register the hooks on demand */
453     switch (bp->reason) {
454     CASE_ON(BP_ON_NEW_NODE, new_node);
455     CASE_ON(BP_ON_REPLACE, replace);
456     CASE_ON(BP_ON_LOWER, lower);
457     CASE_ON(BP_ON_REMIRG, free_graph);
458     CASE_ON(BP_ON_NEW_ENT, new_entity);
459     CASE_ON(BP_ON_NEW_TYPE, new_type);
460     default:
461       ;
462     }
463   }
464   else {
465     /* unregister the hook on demand */
466     switch (bp->reason) {
467     CASE_OFF(BP_ON_NEW_NODE, new_node);
468     CASE_OFF(BP_ON_REPLACE, replace);
469     CASE_OFF(BP_ON_LOWER, lower);
470     CASE_OFF(BP_ON_REMIRG, free_graph);
471     CASE_OFF(BP_ON_NEW_ENT, new_entity);
472     CASE_OFF(BP_ON_NEW_TYPE, new_type);
473     default:
474       ;
475     }
476   }
477 #undef CASE_ON
478 #undef CASE_OFF
479 }  /* update_hooks */
480
481 /**
482  * Break if nr is reached.
483  */
484 static void break_on_nr(long nr, bp_reasons_t reason)
485 {
486   bp_nr_t key, *elem;
487
488   key.bp.kind   = BP_NR;
489   key.bp.bpnr   = 0;
490   key.bp.active = 1;
491   key.bp.reason = reason;
492   key.nr        = nr;
493
494   elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
495
496   if (elem->bp.bpnr == 0) {
497     /* new break point */
498     elem->bp.bpnr = ++bp_num;
499     elem->bp.next = bp_list;
500     bp_list = &elem->bp;
501
502     dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
503
504     update_hooks(&elem->bp);
505   }
506 }  /* break_on_nr */
507
508 /**
509  * Break if ident name is reached.
510  */
511 static void break_on_ident(const char *name, bp_reasons_t reason) {
512   bp_ident_t key, *elem;
513
514   key.bp.kind   = BP_IDENT;
515   key.bp.bpnr   = 0;
516   key.bp.active = 1;
517   key.bp.reason = reason;
518   key.id        = new_id_from_str(name);
519
520   elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
521
522   if (elem->bp.bpnr == 0) {
523     /* new break point */
524     elem->bp.bpnr = ++bp_num;
525     elem->bp.next = bp_list;
526     bp_list = &elem->bp;
527
528     dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
529
530     update_hooks(&elem->bp);
531   }
532 }  /* break_on_ident */
533
534 /**
535  * Sets/resets the active flag of breakpoint bp.
536  */
537 static void bp_activate(unsigned bp, int active)
538 {
539   breakpoint *p;
540
541   for (p = bp_list; p; p = p->next) {
542     if (p->bpnr == bp) {
543       if (p->active != active) {
544         p->active = active;
545         update_hooks(p);
546       }
547
548       dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
549       return;
550     }
551   }
552   dbg_printf("Error: Firm BP %u not exists.\n", bp);
553 }  /* bp_activate */
554
555
556 /**
557  * Show a list of supported commands
558  */
559 static void show_commands(void) {
560   dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
561     ".init                  break after initialization\n"
562     ".create nr             break if node nr was created\n"
563     ".replace nr            break if node nr is replaced by another node\n"
564     ".lower nr              break before node nr is lowered\n"
565     ".remirg nr|name        break if the irg of nr or entity name is deleted\n"
566     ".newent nr|name        break if the entity nr or name was created\n"
567     ".newtype nr|name       break if the type nr or name was created\n"
568     ".bp                    show all breakpoints\n"
569     ".enable nr             enable breakpoint nr\n"
570     ".disable nr            disable breakpoint nr\n"
571     ".showtype nr|name      show content of the type nr or name\n"
572     ".showent nr|name       show content of the entity nr or name\n"
573     ".setmask name msk      sets the debug module name to mask msk\n"
574     ".setlvl  name lvl      sets the debug module name to level lvl\n"
575     ".setoutfile name file  redirects debug output of module name to file\n"
576     ".irgname name          prints address and graph number of a method given by its name\n"
577     ".irgldname ldname      prints address and graph number of a method given by its ldname\n"
578     ".help                  list all commands\n"
579   );
580 }  /* show_commands */
581
582 /**
583  * Shows all Firm breakpoints.
584  */
585 static void show_bp(void) {
586   breakpoint *p;
587   bp_nr_t  *node_p;
588   bp_ident_t *ident_p;
589   int have_one = 0;
590
591   dbg_printf("Firm Breakpoints:");
592   for (p = bp_list; p; p = p->next) {
593     have_one = 1;
594     dbg_printf("+\n  BP %u: ", p->bpnr);
595
596     switch (p->kind) {
597     case BP_NR:
598       node_p = (bp_nr_t *)p;
599       dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
600       break;
601
602     case BP_IDENT:
603       ident_p = (bp_ident_t *)p;
604       dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
605       break;
606     }
607
608     dbg_printf(p->active ? "+enabled" : "+disabled");
609   }
610   dbg_printf(have_one ? "+\n" : "+ NONE\n");
611 }  /* show_bp */
612
613 /**
614  * firm_dbg_register() expects that the name is stored persistent.
615  * So we need this little helper function
616  */
617 static firm_dbg_module_t *dbg_register(const char *name) {
618   ident *id = new_id_from_str(name);
619
620   return firm_dbg_register(get_id_str(id));
621 }  /* dbg_register */
622
623 /**
624  * Sets the debug mask of module name to lvl
625  */
626 static void set_dbg_level(const char *name, unsigned lvl)
627 {
628   firm_dbg_module_t *module = dbg_register(name);
629
630   if (firm_dbg_get_mask(module) != lvl) {
631     firm_dbg_set_mask(module, lvl);
632
633     dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
634   }
635 }  /* set_dbg_level */
636
637 /**
638  * Redirects the debug output of module name to fname
639  */
640 static void set_dbg_outfile(const char *name, const char *fname)
641 {
642   firm_dbg_module_t *module = dbg_register(name);
643   FILE *f = fopen(fname, "w");
644
645   if (! f) {
646     perror(fname);
647     return;
648   }
649
650   firm_dbg_set_file(module, f);
651   dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
652 }  /* set_dbg_outfile */
653
654 /**
655  * Show info about a firm thing.
656  */
657 static void show_firm_object(void *firm_thing) {
658   FILE *f = stdout;
659
660   if (firm_thing == NULL) {
661     fprintf(f, "<NULL>\n");
662     return;
663   }
664   switch (get_kind(firm_thing)) {
665   case k_BAD:
666     fprintf(f, "BAD: (%p)\n", firm_thing);
667     break;
668   case k_entity:
669     dump_entity_to_file(f, firm_thing, dump_verbosity_max);
670     break;
671   case k_type:
672     dump_type_to_file(f, firm_thing, dump_verbosity_max);
673     break;
674   case k_ir_graph:
675   case k_ir_node:
676   case k_ir_mode:
677   case k_ir_op:
678   case k_tarval:
679   case k_ir_loop:
680   case k_ir_compound_graph_path:
681   case k_ir_extblk:
682   case k_ir_prog:
683     fprintf(f, "NIY\n");
684     break;
685   default:
686     fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
687   }
688 }  /* show_firm_object */
689
690 /**
691  * Find a firm type by its number.
692  */
693 static ir_type *find_type_nr(long nr) {
694   int i, n = get_irp_n_types();
695   ir_type *tp;
696
697   for (i = 0; i < n; ++i) {
698     tp = get_irp_type(i);
699     if (get_type_nr(tp) == nr)
700       return tp;
701   }
702   tp = get_glob_type();
703   if (get_type_nr(tp) == nr)
704     return tp;
705   return NULL;
706 }  /* find_type_nr */
707
708 /**
709  * Find a firm type by its name.
710  */
711 static ir_type *find_type_name(const char *name) {
712   int i, n = get_irp_n_types();
713   ir_type *tp;
714
715   for (i = 0; i < n; ++i) {
716     tp = get_irp_type(i);
717     if (strcmp(get_type_name(tp), name) == 0)
718       return tp;
719   }
720   tp = get_glob_type();
721   if (strcmp(get_type_name(tp), name) == 0)
722     return tp;
723   return NULL;
724 }  /* find_type_name */
725
726 /** The environment for the entity search functions. */
727 typedef struct find_env {
728   union {
729     long        nr;   /**< the number that is searched for */
730     const char *name; /**< the name that is searched for */
731   } u;
732   entity *res;        /**< the result */
733 } find_env_t;
734
735 /**
736  * Type-walker: Find an entity with given number.
737  */
738 static void check_ent_nr(type_or_ent *tore, void *ctx) {
739   entity *ent = (entity *)tore;
740   find_env_t *env = ctx;
741
742   if (is_entity(ent))
743     if (get_entity_nr(ent) == env->u.nr) {
744       env->res = ent;
745     }
746 }  /* check_ent_nr */
747
748 /**
749  * Type-walker: Find an entity with given name.
750  */
751 static void check_ent_name(type_or_ent *tore, void *ctx) {
752   entity *ent = (entity *)tore;
753   find_env_t *env = ctx;
754
755   if (is_entity(ent))
756     if (strcmp(get_entity_name(ent), env->u.name) == 0) {
757       env->res = ent;
758     }
759 }  /* check_ent_name */
760
761 /**
762  * Find a firm entity by its number.
763  */
764 static entity *find_entity_nr(long nr) {
765   find_env_t env;
766
767   env.u.nr = nr;
768   env.res  = NULL;
769   type_walk(check_ent_nr, NULL, &env);
770   return env.res;
771 }  /* find_entity_nr */
772
773 /**
774  * Find a firm entity by its name.
775  */
776 static entity *find_entity_name(const char *name) {
777   find_env_t env;
778
779   env.u.name = name;
780   env.res    = NULL;
781   type_walk(check_ent_name, NULL, &env);
782   return env.res;
783 }  /* find_entity_name */
784
785 /**
786  * Search methods for a name.
787  */
788 static void show_by_name(type_or_ent *tore, void *env) {
789   ident *id = (ident *)env;
790
791   if (is_entity(tore)) {
792     entity *ent = (entity *)tore;
793
794     if (is_method_entity(ent)) {
795       if (get_entity_ident(ent) == id) {
796         ir_type *owner = get_entity_owner(ent);
797         ir_graph *irg = get_entity_irg(ent);
798
799         if (owner != get_glob_type()) {
800           printf("%s::%s", get_type_name(owner), get_id_str(id));
801         } else {
802           printf("%s", get_id_str(id));
803         }
804         if (irg)
805           printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
806         else
807           printf(" NULL\n");
808       }
809     }
810   }
811 }  /* show_by_name */
812
813 /**
814  * Search methods for a ldname.
815  */
816 static void show_by_ldname(type_or_ent *tore, void *env) {
817   ident *id = (ident *)env;
818
819   if (is_entity(tore)) {
820     entity *ent = (entity *)tore;
821
822     if (is_method_entity(ent)) {
823       if (get_entity_ld_ident(ent) == id) {
824         ir_type *owner = get_entity_owner(ent);
825         ir_graph *irg = get_entity_irg(ent);
826
827         if (owner != get_glob_type()) {
828           printf("%s::%s", get_type_name(owner), get_id_str(id));
829         } else {
830           printf("%s", get_id_str(id));
831         }
832         if (irg)
833           printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
834         else
835           printf(" NULL\n");
836       }
837     }
838   }
839 }  /* show_by_ldname */
840
841 /**
842  * prints the address and graph number of all irgs with given name
843  */
844 static void irg_name(const char *name) {
845   ident *id = new_id_from_str(name);
846
847   type_walk(show_by_name, NULL, (void *)id);
848 }  /* irg_name */
849
850 /**
851  * prints the address and graph number of all irgs with given ld_name
852  */
853 static void irg_ld_name(const char *name) {
854   ident *id = new_id_from_str(name);
855
856   type_walk(show_by_ldname, NULL, (void *)id);
857 }  /* irg_ld_name */
858
859 /**
860  * High level function to use from debugger interface
861  *
862  * Supported commands:
863  *  .create nr    break if node nr was created
864  *  .help         list all commands
865  */
866 void firm_debug(const char *cmd) {
867   long nr;
868   unsigned bp;
869   char name[1024], fname[1024];
870   unsigned lvl;
871
872   while (isspace(*cmd)) ++cmd;
873
874   if (sscanf(cmd, ".create %ld\n", &nr) == 1) {
875     break_on_nr(nr, BP_ON_NEW_NODE);
876   }
877   else if (sscanf(cmd, ".replace %ld\n", &nr) == 1) {
878     break_on_nr(nr, BP_ON_REPLACE);
879   }
880   else if (sscanf(cmd, ".lower %ld\n", &nr) == 1) {
881     break_on_nr(nr, BP_ON_LOWER);
882   }
883   else if (sscanf(cmd, ".remirg %ld\n", &nr) == 1) {
884     break_on_nr(nr, BP_ON_REMIRG);
885   }
886   else if (sscanf(cmd, ".remirg %s\n", name) == 1) {
887     break_on_ident(name, BP_ON_REMIRG);
888   }
889   else if (sscanf(cmd, ".newent %ld\n", &nr) == 1) {
890     break_on_nr(nr, BP_ON_NEW_ENT);
891   }
892   else if (sscanf(cmd, ".newent %s\n", name) == 1) {
893     break_on_ident(name, BP_ON_NEW_ENT);
894   }
895   else if (sscanf(cmd, ".newtype %ld\n", &nr) == 1) {
896     break_on_nr(nr, BP_ON_NEW_TYPE);
897   }
898   else if (sscanf(cmd, ".newtype %s\n", name) == 1) {
899     break_on_ident(name, BP_ON_NEW_TYPE);
900   }
901   else if (sscanf(cmd, ".showtype %ld\n", &nr) == 1) {
902     show_firm_object(find_type_nr(nr));
903   }
904   else if (sscanf(cmd, ".showtype %s\n", name) == 1) {
905     show_firm_object(find_type_name(name));
906   }
907   else if (sscanf(cmd, ".showent %ld\n", &nr) == 1) {
908     show_firm_object(find_entity_nr(nr));
909   }
910   else if (sscanf(cmd, ".showent %s\n", name) == 1) {
911     show_firm_object(find_entity_name(name));
912   }
913   else if (strcmp(cmd, ".init") == 0)
914     break_on_init = 1;
915   else if (strcmp(cmd, ".bp") == 0)
916     show_bp();
917   else if (sscanf(cmd, ".enable %u", &bp) == 1)
918     bp_activate(bp, 1);
919   else if (sscanf(cmd, ".disable %u", &bp) == 1)
920     bp_activate(bp, 0);
921   else if (sscanf(cmd, ".setmask %s %u\n", name, &lvl) == 2)
922     set_dbg_level(name, lvl);
923   else if (sscanf(cmd, ".setlvl %s %u\n", name, &lvl) == 2)
924     set_dbg_level(name, (1 << lvl) - 1);
925   else if (sscanf(cmd, ".setoutfile %s %s\n", name, fname) == 2)
926     set_dbg_outfile(name, fname);
927   else if (sscanf(cmd, ".irgname %s\n", name) == 1)
928     irg_name(name);
929   else if (sscanf(cmd, ".irgldname %s\n", name) == 1)
930     irg_ld_name(name);
931   else {
932     show_commands();
933   }
934 }  /* firm_debug */
935
936 /* creates the debugger tables */
937 void firm_init_debugger(void)
938 {
939   char *env;
940
941   bp_numbers = new_set(cmp_nr_bp, 8);
942   bp_idents  = new_set(cmp_ident_bp, 8);
943
944   env = getenv("FIRMDBG");
945
946   is_active = 1;
947
948   if (env)
949     firm_debug(env);
950
951   if (break_on_init)
952     firm_debug_break();
953 }  /* firm_init_debugger */
954
955 #else
956
957 /* some picky compiler do not allow empty files */
958 static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
959
960 #endif /* NDEBUG */
961
962 /**
963  * @page debugger   The Firm debugger extension
964  *
965  * Firm contains a debugger extension. This allows to set debugger breakpoints
966  * an various events.
967  * The extension uses a text interface which can be accessed from most debuggers.
968  *
969  * @section sec_cmd Supported commands
970  *
971  * The following commands are currently supported:
972  *
973  * @b .init
974  *
975  * Break immediately after the debugger extension was initialized.
976  * Typically this command is used in the environment to stop the execution
977  * of a Firm compiler right after the initialization, like this:
978  *
979  * $export FIRMDBG=".init"
980  *
981  * @b .create nr
982  *
983  * Break if a new IR-node with node number nr was created.
984  * Typically used to find the place where wrong nodes are created.
985  *
986  * @b .replace nr
987  *
988  * Break before IR-node with node number nr is replaced by another node.
989  *
990  * @b .lower nr
991  *
992  * Break before IR-node with node number nr is lowered.
993  *
994  * @b .remirg nr
995  *
996  * Break if the irg with graph number nr is deleted.
997  *
998  * @b .remirg name
999  *
1000  * Break if the irg of entity name is deleted.
1001  *
1002  * @b .newent nr
1003  *
1004  * Break if the entity with number nr was created.
1005  *
1006  * @b .newent name
1007  *
1008  * Break if the entity name was created.
1009  *
1010  * @b .newtype nr
1011  *
1012  * Break if the type with number nr was created.
1013  *
1014  * @b .newtype name
1015  *
1016  * Break if the type name was created.
1017  *
1018  * @b .bp
1019  *
1020  * Show all Firm internal breakpoints.
1021  *
1022  * @b .enable nr
1023  *
1024  * Enables breakpoint nr.
1025  *
1026  * @b .disable nr
1027  *
1028  * Disables breakpoint nr.
1029  *
1030  * @b .showent nr
1031  *
1032  * Show the content of entity nr.
1033  *
1034  * @b .showent name
1035  *
1036  * Show the content of entity name.
1037  *
1038  * @b .showtype nr
1039  *
1040  * Show the content of type nr.
1041  *
1042  * @b .showtype name
1043  *
1044  * Show the content of type name.
1045  *
1046  * @b .setmask name msk
1047  *
1048  * Sets the debug module name to mask msk.
1049  *
1050  * @b .setlvl name lvl
1051  *
1052  * Sets the debug module name to level lvl.
1053  *
1054  * @b .setoutfile name file
1055  *
1056  * Redirects debug output of module name to file.
1057  *
1058  * @b .irgname name
1059  *
1060  * Prints address and graph number of a method given by its name.
1061  *
1062  * @b .irgldname name
1063  *
1064  * Prints address and graph number of a method given by its linker name.
1065  *
1066  * @b .help
1067  *
1068  * List all commands.
1069  *
1070  *
1071  * The Firm debugger extension can be accessed using the function firm_debug().
1072  * The following example shows how to set a creation breakpoint in GDB when
1073  * node 2101 is created.
1074  *
1075  * -# set FIRMDBG=".init"
1076  * -# start gdb with your compiler
1077  * -# after gdb breaks, issue
1078  *
1079  * call firm_debug(".create 2101")
1080  *
1081  * On the console the following text should be issued:
1082  *
1083  * Firm BP 1: creation of Node 2101
1084  *
1085  *
1086  * @section gdb_macro GDB macro
1087  *
1088  * Add the following to your .gdbinit file:
1089  * @code
1090  #
1091  # define firm "cmd"  Firm debugger extension
1092  #
1093  define firm
1094  call firm_debug($arg0)
1095  end
1096  * @endcode
1097  *
1098  * Then, all Firm debugger extension commands can be accessed in the gdb
1099  * console using the firm prefix, eg.:
1100  *
1101  * firm ".create 2101"
1102  *
1103  * firm ".help"
1104  */