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