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