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