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