f5cb206dc4436f450a15f741fe74cdad23c9316e
[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     ".help                  list all commands\n"
577   );
578 }  /* show_commands */
579
580 /**
581  * Shows all Firm breakpoints.
582  */
583 static void show_bp(void) {
584   breakpoint *p;
585   bp_nr_t  *node_p;
586   bp_ident_t *ident_p;
587   int have_one = 0;
588
589   dbg_printf("Firm Breakpoints:");
590   for (p = bp_list; p; p = p->next) {
591     have_one = 1;
592     dbg_printf("+\n  BP %u: ", p->bpnr);
593
594     switch (p->kind) {
595     case BP_NR:
596       node_p = (bp_nr_t *)p;
597       dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
598       break;
599
600     case BP_IDENT:
601       ident_p = (bp_ident_t *)p;
602       dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
603       break;
604     }
605
606     dbg_printf(p->active ? "+enabled" : "+disabled");
607   }
608   dbg_printf(have_one ? "+\n" : "+ NONE\n");
609 }  /* show_bp */
610
611 /**
612  * firm_dbg_register() expects that the name is stored persistent.
613  * So we need this little helper function
614  */
615 static firm_dbg_module_t *dbg_register(const char *name) {
616   ident *id = new_id_from_str(name);
617
618   return firm_dbg_register(get_id_str(id));
619 }  /* dbg_register */
620
621 /**
622  * Sets the debug mask of module name to lvl
623  */
624 static void set_dbg_level(const char *name, unsigned lvl)
625 {
626   firm_dbg_module_t *module = dbg_register(name);
627
628   if (firm_dbg_get_mask(module) != lvl) {
629     firm_dbg_set_mask(module, lvl);
630
631     dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
632   }
633 }  /* set_dbg_level */
634
635 /**
636  * Redirects the debug output of module name to fname
637  */
638 static void set_dbg_outfile(const char *name, const char *fname)
639 {
640   firm_dbg_module_t *module = dbg_register(name);
641   FILE *f = fopen(fname, "w");
642
643   if (! f) {
644     perror(fname);
645     return;
646   }
647
648   firm_dbg_set_file(module, f);
649   dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
650 }  /* set_dbg_outfile */
651
652 /**
653  * Show info about a firm thing.
654  */
655 static void show_firm_object(void *firm_thing) {
656   FILE *f = stdout;
657
658   if (firm_thing == NULL) {
659     fprintf(f, "<NULL>\n");
660     return;
661   }
662   switch (get_kind(firm_thing)) {
663   case k_BAD:
664     fprintf(f, "BAD: (%p)\n", firm_thing);
665     break;
666   case k_entity:
667     dump_entity_to_file(f, firm_thing, dump_verbosity_max);
668     break;
669   case k_type:
670     dump_type_to_file(f, firm_thing, dump_verbosity_max);
671     break;
672   case k_ir_graph:
673   case k_ir_node:
674   case k_ir_mode:
675   case k_ir_op:
676   case k_tarval:
677   case k_ir_loop:
678   case k_ir_compound_graph_path:
679   case k_ir_extblk:
680   case k_ir_prog:
681     fprintf(f, "NIY\n");
682     break;
683   default:
684     fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
685   }
686 }  /* show_firm_object */
687
688 /**
689  * Find a firm type by its number.
690  */
691 static ir_type *find_type_nr(long nr) {
692   int i, n = get_irp_n_types();
693   ir_type *tp;
694
695   for (i = 0; i < n; ++i) {
696     tp = get_irp_type(i);
697     if (get_type_nr(tp) == nr)
698       return tp;
699   }
700   tp = get_glob_type();
701   if (get_type_nr(tp) == nr)
702     return tp;
703   return NULL;
704 }  /* find_type_nr */
705
706 /**
707  * Find a firm type by its name.
708  */
709 static ir_type *find_type_name(const char *name) {
710   int i, n = get_irp_n_types();
711   ir_type *tp;
712
713   for (i = 0; i < n; ++i) {
714     tp = get_irp_type(i);
715     if (strcmp(get_type_name(tp), name) == 0)
716       return tp;
717   }
718   tp = get_glob_type();
719   if (strcmp(get_type_name(tp), name) == 0)
720     return tp;
721   return NULL;
722 }  /* find_type_name */
723
724 /** The environment for the entity search functions. */
725 typedef struct find_env {
726   union {
727     long        nr;   /**< the number that is searched for */
728     const char *name; /**< the name that is searched for */
729   } u;
730   entity *res;        /**< the result */
731 } find_env_t;
732
733 /**
734  * Type-walker: Find an entity with given number.
735  */
736 static void check_ent_nr(type_or_ent *tore, void *ctx) {
737   entity *ent = (entity *)tore;
738   find_env_t *env = ctx;
739
740   if (is_entity(ent))
741     if (get_entity_nr(ent) == env->u.nr) {
742       env->res = ent;
743     }
744 }  /* check_ent_nr */
745
746 /**
747  * Type-walker: Find an entity with given name.
748  */
749 static void check_ent_name(type_or_ent *tore, void *ctx) {
750   entity *ent = (entity *)tore;
751   find_env_t *env = ctx;
752
753   if (is_entity(ent))
754     if (strcmp(get_entity_name(ent), env->u.name) == 0) {
755       env->res = ent;
756     }
757 }  /* check_ent_name */
758
759 /**
760  * Find a firm entity by its number.
761  */
762 static entity *find_entity_nr(long nr) {
763   find_env_t env;
764
765   env.u.nr = nr;
766   env.res  = NULL;
767   type_walk(check_ent_nr, NULL, &env);
768   return env.res;
769 }  /* find_entity_nr */
770
771 /**
772  * Find a firm entity by its name.
773  */
774 static entity *find_entity_name(const char *name) {
775   find_env_t env;
776
777   env.u.name = name;
778   env.res    = NULL;
779   type_walk(check_ent_name, NULL, &env);
780   return env.res;
781 }  /* find_entity_name */
782
783 static void irgname(const char *name) {
784   int i;
785   ident *id = new_id_from_str(name);
786
787   for(i = get_irp_n_irgs() - 1; i >= 0; --i) {
788     ir_graph *irg = get_irp_irg(i);
789         entity *ent = get_irg_entity(irg);
790         if(ent && get_entity_ident(ent) == id) {
791       ir_printf("%+F (%p)\n", irg, irg);
792           break;
793         }
794   }
795 }
796
797 /**
798  * High level function to use from debugger interface
799  *
800  * Supported commands:
801  *  .create nr    break if node nr was created
802  *  .help         list all commands
803  */
804 void firm_debug(const char *cmd) {
805   long nr;
806   unsigned bp;
807   char name[1024], fname[1024];
808   unsigned lvl;
809
810   while (isspace(*cmd)) ++cmd;
811
812   if (sscanf(cmd, ".create %ld\n", &nr) == 1) {
813     break_on_nr(nr, BP_ON_NEW_NODE);
814   }
815   else if (sscanf(cmd, ".replace %ld\n", &nr) == 1) {
816     break_on_nr(nr, BP_ON_REPLACE);
817   }
818   else if (sscanf(cmd, ".lower %ld\n", &nr) == 1) {
819     break_on_nr(nr, BP_ON_LOWER);
820   }
821   else if (sscanf(cmd, ".remirg %ld\n", &nr) == 1) {
822     break_on_nr(nr, BP_ON_REMIRG);
823   }
824   else if (sscanf(cmd, ".remirg %s\n", name) == 1) {
825     break_on_ident(name, BP_ON_REMIRG);
826   }
827   else if (sscanf(cmd, ".newent %ld\n", &nr) == 1) {
828     break_on_nr(nr, BP_ON_NEW_ENT);
829   }
830   else if (sscanf(cmd, ".newent %s\n", name) == 1) {
831     break_on_ident(name, BP_ON_NEW_ENT);
832   }
833   else if (sscanf(cmd, ".newtype %ld\n", &nr) == 1) {
834     break_on_nr(nr, BP_ON_NEW_TYPE);
835   }
836   else if (sscanf(cmd, ".newtype %s\n", name) == 1) {
837     break_on_ident(name, BP_ON_NEW_TYPE);
838   }
839   else if (sscanf(cmd, ".showtype %ld\n", &nr) == 1) {
840     show_firm_object(find_type_nr(nr));
841   }
842   else if (sscanf(cmd, ".showtype %s\n", name) == 1) {
843     show_firm_object(find_type_name(name));
844   }
845   else if (sscanf(cmd, ".showent %ld\n", &nr) == 1) {
846     show_firm_object(find_entity_nr(nr));
847   }
848   else if (sscanf(cmd, ".showent %s\n", name) == 1) {
849     show_firm_object(find_entity_name(name));
850   }
851   else if (strcmp(cmd, ".init") == 0)
852     break_on_init = 1;
853   else if (strcmp(cmd, ".bp") == 0)
854     show_bp();
855   else if (sscanf(cmd, ".enable %u", &bp) == 1)
856     bp_activate(bp, 1);
857   else if (sscanf(cmd, ".disable %u", &bp) == 1)
858     bp_activate(bp, 0);
859   else if (sscanf(cmd, ".setmask %s %u\n", name, &lvl) == 2)
860     set_dbg_level(name, lvl);
861   else if (sscanf(cmd, ".setlvl %s %u\n", name, &lvl) == 2)
862     set_dbg_level(name, (1 << lvl) - 1);
863   else if (sscanf(cmd, ".setoutfile %s %s\n", name, fname) == 2)
864     set_dbg_outfile(name, fname);
865   else if (sscanf(cmd, ".irgname %s\n", name) == 1)
866         irgname(name);
867   else {
868     show_commands();
869   }
870 }  /* firm_debug */
871
872 /* creates the debugger tables */
873 void firm_init_debugger(void)
874 {
875   char *env;
876
877   bp_numbers = new_set(cmp_nr_bp, 8);
878   bp_idents  = new_set(cmp_ident_bp, 8);
879
880   env = getenv("FIRMDBG");
881
882   is_active = 1;
883
884   if (env)
885     firm_debug(env);
886
887   if (break_on_init)
888     firm_debug_break();
889 }  /* firm_init_debugger */
890
891 #else
892
893 /* some picky compiler do not allow empty files */
894 static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
895
896 #endif /* NDEBUG */
897
898 /**
899  * @page debugger   The Firm debugger extension
900  *
901  * Firm contains a debugger extension. This allows to set debugger breakpoints
902  * an various events.
903  * The extension uses a text interface which can be accessed from most debuggers.
904  *
905  * @section sec_cmd Supported commands
906  *
907  * The following commands are currently supported:
908  *
909  * @b .init
910  *
911  * Break immediately after the debugger extension was initialized.
912  * Typically this command is used in the environment to stop the execution
913  * of a Firm compiler right after the initialization, like this:
914  *
915  * $export FIRMDBG=".init"
916  *
917  * @b .create nr
918  *
919  * Break if a new IR-node with node number nr was created.
920  * Typically used to find the place where wrong nodes are created.
921  *
922  * @b .replace nr
923  *
924  * Break before IR-node with node number nr is replaced by another node.
925  *
926  * @b .lower nr
927  *
928  * Break before IR-node with node number nr is lowered.
929  *
930  * @b .remirg nr
931  *
932  * Break if the irg with graph number nr is deleted.
933  *
934  * @b .remirg name
935  *
936  * Break if the irg of entity name is deleted.
937  *
938  * @b .newent nr
939  *
940  * Break if the entity with number nr was created.
941  *
942  * @b .newent name
943  *
944  * Break if the entity name was created.
945  *
946  * @b .newtype nr
947  *
948  * Break if the type with number nr was created.
949  *
950  * @b .newtype name
951  *
952  * Break if the type name was created.
953  *
954  * @b .bp
955  *
956  * Show all Firm internal breakpoints.
957  *
958  * @b .enable nr
959  *
960  * Enables breakpoint nr.
961  *
962  * @b .disable nr
963  *
964  * Disables breakpoint nr.
965  *
966  * @b .showent nr
967  *
968  * Show the content of entity nr.
969  *
970  * @b .showent name
971  *
972  * Show the content of entity name.
973  *
974  * @b .showtype nr
975  *
976  * Show the content of type nr.
977  *
978  * @b .showtype name
979  *
980  * Show the content of type name.
981  *
982  * @b .setmask name msk
983  *
984  * Sets the debug module name to mask msk.
985  *
986  * @b .setlvl name lvl
987  *
988  * Sets the debug module name to level lvl.
989  *
990  * @b .setoutfile name file
991  *
992  * Redirects debug output of module name to file.
993  *
994  * @b .help
995  *
996  * List all commands.
997  *
998  *
999  * The Firm debugger extension can be accessed using the function firm_debug().
1000  * The following example shows how to set a creation breakpoint in GDB when
1001  * node 2101 is created.
1002  *
1003  * -# set FIRMDBG=".init"
1004  * -# start gdb with your compiler
1005  * -# after gdb breaks, issue
1006  *
1007  * call firm_debug(".create 2101")
1008  *
1009  * On the console the following text should be issued:
1010  *
1011  * Firm BP 1: creation of Node 2101
1012  *
1013  *
1014  * @section gdb_macro GDB macro
1015  *
1016  * Add the following to your .gdbinit file:
1017  * @code
1018  #
1019  # define firm "cmd"  Firm debugger extension
1020  #
1021  define firm
1022  call firm_debug($arg0)
1023  end
1024  * @endcode
1025  *
1026  * Then, all Firm debugger extension commands can be accessed in the gdb
1027  * console using the firm prefix, eg.:
1028  *
1029  * firm ".create 2101"
1030  *
1031  * firm ".help"
1032  */