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