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