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