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