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