2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Helper function for integrated debug support
23 * @author Michael Beck
34 #define WIN32_LEAN_AND_MEAN
58 #include "irgraph_t.h"
62 #include "iredges_t.h"
67 /* Break into the debugger. The Win32 way. */
68 void firm_debug_break(void) {
71 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
72 /* Break into the debugger. The ia32/x86_64 way under GCC. */
73 void firm_debug_break(void) {
74 __asm__ __volatile__("int3");
77 /* Break into the debugger. Poor Unix way. */
78 void firm_debug_break(void) {
83 /** supported breakpoint kinds */
85 BP_NR = 'n', /**< break on node number. */
86 BP_IDENT = 'i' /**< break on ident. */
90 * Reasons for node number breakpoints.
92 typedef enum _bp_reasons_t {
93 BP_ON_NEW_NODE, /**< break if node with number is created */
94 BP_ON_REPLACE, /**< break if node with number is replaced */
95 BP_ON_LOWER, /**< break if node with number is lowered */
96 BP_ON_REMIRG, /**< break if an IRG is removed */
97 BP_ON_NEW_ENT, /**< break if a new entity is created */
98 BP_ON_NEW_TYPE, /**< break if a new type is created */
103 typedef struct _breakpoint {
104 bp_kind kind; /**< the kind of this break point */
105 unsigned bpnr; /**< break point number */
106 int active; /**< non-zero, if this break point is active */
107 bp_reasons_t reason; /**< reason for the breakpoint */
108 struct _breakpoint *next; /**< link to the next one */
111 /** A number breakpoint. */
113 breakpoint bp; /**< the breakpoint data */
114 long nr; /**< the node number */
117 /** Calculate the hash value for a node breakpoint. */
118 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
120 /** An ident breakpoint. */
122 breakpoint bp; /**< the breakpoint data */
123 ident *id; /**< the ident */
126 /** Calculate the hash value for an ident breakpoint. */
127 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
129 /** The set containing the breakpoints on node numbers. */
130 static set *bp_numbers;
132 /** The set containing the breakpoints on idents. */
133 static set *bp_idents;
135 /**< the list of all breakpoints */
136 static breakpoint *bp_list;
138 /** number of the current break point */
139 static unsigned bp_num = 0;
141 /** set if break on init command was issued. */
142 static int break_on_init = 0;
144 /** the hook entries for the Firm debugger module. */
145 static hook_entry_t debugger_hooks[hook_last];
147 /** number of active breakpoints to maintain hooks. */
148 static unsigned num_active_bp[BP_MAX_REASON];
151 * The debug message buffer
153 static char firm_dbg_msg_buf[2048];
156 * If set, the debug extension writes all output to the
157 * firm_dbg_msg_buf buffer
159 static int redir_output = 0;
162 * Is set to one, if the debug extension is active
164 static int is_active = 0;
166 /** hook the hook h with function fkt. */
167 #define HOOK(h, fkt) \
169 debugger_hooks[h].hook._##h = fkt; \
170 register_hook(h, &debugger_hooks[h]); \
173 /** unhook the hook h */
176 unregister_hook(h, &debugger_hooks[h]); \
177 debugger_hooks[h].hook._##h = NULL; \
180 /** returns non-zero if a entry hook h is used */
181 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
183 /* some macros needed to create the info string */
184 #define _DBG_VERSION(major, minor) #major "." #minor
185 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
186 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
188 /* the API version: change if needed */
189 #define FIRM_DBG_MAJOR 1
190 #define FIRM_DBG_MINOR 0
192 /** for automatic detection of the debug extension */
193 static const char firm_debug_info_string[] =
194 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
197 * Returns non-zero, if the debug extension is active
199 int firm_debug_active(void) {
201 } /* firm_debug_active */
204 * Reset the debug text buffer.
206 static void reset_dbg_buf(void) {
207 firm_dbg_msg_buf[0] = '\0';
208 } /* reset_dbg_buf */
211 * Add text to the debug text buffer.
213 static void add_to_dbg_buf(const char *buf) {
214 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
215 } /* add_to_dbg_buf */
218 * Return the content of the debug text buffer.
220 * To be called from the debugger.
222 const char *firm_debug_text(void) {
223 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
224 return firm_dbg_msg_buf;
225 } /* firm_debug_text */
230 static void dbg_printf(const char *fmt, ...)
242 ir_vsnprintf(buf, sizeof(buf), fmt, args);
252 * A new node is created.
254 * @param ctx the hook context
255 * @param irg the IR graph on which the node is created
256 * @param node the new IR node that was created
258 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
264 key.nr = get_irn_node_nr(node);
265 key.bp.reason = BP_ON_NEW_NODE;
267 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
268 if (elem && elem->bp.active) {
269 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
275 * A node is replaced.
277 * @param ctx the hook context
278 * @param old the IR node the is replaced
279 * @param nw the new IR node that will replace old
281 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
286 key.nr = get_irn_node_nr(old);
287 key.bp.reason = BP_ON_REPLACE;
289 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
290 if (elem && elem->bp.active) {
291 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
297 * A new node is lowered.
299 * @param ctx the hook context
300 * @param node the new IR node that will be lowered
302 static void dbg_lower(void *ctx, ir_node *node)
307 key.nr = get_irn_node_nr(node);
308 key.bp.reason = BP_ON_LOWER;
310 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
311 if (elem && elem->bp.active) {
312 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
318 * A graph will be deleted.
320 * @param ctx the hook context
321 * @param irg the IR graph that will be deleted
323 static void dbg_free_graph(void *ctx, ir_graph *irg)
328 key.nr = get_irg_graph_nr(irg);
329 key.bp.reason = BP_ON_REMIRG;
331 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
332 if (elem && elem->bp.active) {
333 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
338 bp_ident_t key, *elem;
339 ir_entity *ent = get_irg_entity(irg);
344 key.id = get_entity_ident(ent);
345 key.bp.reason = BP_ON_REMIRG;
347 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
348 if (elem && elem->bp.active) {
349 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
353 } /* dbg_free_graph */
356 * An entity was created.
358 * @param ctx the hook context
359 * @param ent the newly created entity
361 static void dbg_new_entity(void *ctx, ir_entity *ent)
365 bp_ident_t key, *elem;
367 key.id = get_entity_ident(ent);
368 key.bp.reason = BP_ON_NEW_ENT;
370 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
371 if (elem && elem->bp.active) {
372 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
379 key.nr = get_entity_nr(ent);
380 key.bp.reason = BP_ON_NEW_ENT;
382 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
383 if (elem && elem->bp.active) {
384 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
388 } /* dbg_new_entity */
391 * A type was created.
393 * @param ctx the hook context
394 * @param tp the newly created type
396 static void dbg_new_type(void *ctx, ir_type *tp)
402 key.nr = get_type_nr(tp);
403 key.bp.reason = BP_ON_NEW_TYPE;
405 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
406 if (elem && elem->bp.active) {
407 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
412 bp_ident_t key, *elem;
414 key.id = get_type_ident(tp);
415 key.bp.reason = BP_ON_NEW_TYPE;
417 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
418 if (elem && elem->bp.active) {
419 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
426 * Return the reason string.
428 static const char *reason_str(bp_reasons_t reason)
431 case BP_ON_NEW_NODE: return "node creation";
432 case BP_ON_REPLACE: return "node replace";
433 case BP_ON_LOWER: return "node lowering";
434 case BP_ON_REMIRG: return "removing IRG";
435 case BP_ON_NEW_ENT: return "entity creation";
436 case BP_ON_NEW_TYPE: return "type creation";
437 case BP_MAX_REASON: break;
439 panic("unsupported reason");
443 * Compare two number breakpoints.
445 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
447 const bp_nr_t *e1 = elt;
448 const bp_nr_t *e2 = key;
451 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
455 * Compare two ident breakpoints.
457 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
459 const bp_ident_t *e1 = elt;
460 const bp_ident_t *e2 = key;
463 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
469 static void update_hooks(breakpoint *bp)
471 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
472 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
475 ++num_active_bp[bp->reason];
477 --num_active_bp[bp->reason];
479 if (num_active_bp[bp->reason] > 0) {
480 /* register the hooks on demand */
481 switch (bp->reason) {
482 CASE_ON(BP_ON_NEW_NODE, new_node);
483 CASE_ON(BP_ON_REPLACE, replace);
484 CASE_ON(BP_ON_LOWER, lower);
485 CASE_ON(BP_ON_REMIRG, free_graph);
486 CASE_ON(BP_ON_NEW_ENT, new_entity);
487 CASE_ON(BP_ON_NEW_TYPE, new_type);
493 /* unregister the hook on demand */
494 switch (bp->reason) {
495 CASE_OFF(BP_ON_NEW_NODE, new_node);
496 CASE_OFF(BP_ON_REPLACE, replace);
497 CASE_OFF(BP_ON_LOWER, lower);
498 CASE_OFF(BP_ON_REMIRG, free_graph);
499 CASE_OFF(BP_ON_NEW_ENT, new_entity);
500 CASE_OFF(BP_ON_NEW_TYPE, new_type);
510 * Break if nr is reached.
512 static void break_on_nr(long nr, bp_reasons_t reason)
519 key.bp.reason = reason;
522 elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
524 if (elem->bp.bpnr == 0) {
525 /* new break point */
526 elem->bp.bpnr = ++bp_num;
527 elem->bp.next = bp_list;
530 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
532 update_hooks(&elem->bp);
537 * Break if ident name is reached.
539 static void break_on_ident(const char *name, bp_reasons_t reason) {
540 bp_ident_t key, *elem;
542 key.bp.kind = BP_IDENT;
545 key.bp.reason = reason;
546 key.id = new_id_from_str(name);
548 elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
550 if (elem->bp.bpnr == 0) {
551 /* new break point */
552 elem->bp.bpnr = ++bp_num;
553 elem->bp.next = bp_list;
556 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
558 update_hooks(&elem->bp);
560 } /* break_on_ident */
563 * Sets/resets the active flag of breakpoint bp.
565 static void bp_activate(unsigned bp, int active)
569 for (p = bp_list; p; p = p->next) {
571 if (p->active != active) {
576 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
580 dbg_printf("Error: Firm BP %u not exists.\n", bp);
585 * Show a list of supported commands
587 static void show_commands(void) {
588 dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
589 "init break after initialization\n"
590 "create nr break if node nr was created\n"
591 "replace nr break if node nr is replaced by another node\n"
592 "lower nr break before node nr is lowered\n"
593 "remirg nr|name break if the irg of nr or entity name is deleted\n"
594 "newent nr|name break if the entity nr or name was created\n"
595 "newtype nr|name break if the type nr or name was created\n"
596 "bp show all breakpoints\n"
597 "enable nr enable breakpoint nr\n"
598 "disable nr disable breakpoint nr\n"
599 "showtype nr|name show content of the type nr or name\n"
600 "showent nr|name show content of the entity nr or name\n"
601 "setmask name msk sets the debug module name to mask msk\n"
602 "setlvl name lvl sets the debug module name to level lvl\n"
603 "setoutfile name file redirects debug output of module name to file\n"
604 "irgname name prints address and graph number of a method given by its name\n"
605 "irgldname ldname prints address and graph number of a method given by its ldname\n"
606 "help list all commands\n"
608 } /* show_commands */
611 * Shows all Firm breakpoints.
613 static void show_bp(void) {
619 dbg_printf("Firm Breakpoints:");
620 for (p = bp_list; p; p = p->next) {
622 dbg_printf("+\n BP %u: ", p->bpnr);
626 node_p = (bp_nr_t *)p;
627 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
631 ident_p = (bp_ident_t *)p;
632 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
636 dbg_printf(p->active ? "+enabled" : "+disabled");
638 dbg_printf(have_one ? "+\n" : "+ NONE\n");
642 * firm_dbg_register() expects that the name is stored persistent.
643 * So we need this little helper function
645 static firm_dbg_module_t *dbg_register(const char *name) {
646 ident *id = new_id_from_str(name);
648 return firm_dbg_register(get_id_str(id));
652 * Sets the debug mask of module name to lvl
654 static void set_dbg_level(const char *name, unsigned lvl)
656 firm_dbg_module_t *module = dbg_register(name);
658 if (firm_dbg_get_mask(module) != lvl) {
659 firm_dbg_set_mask(module, lvl);
661 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
663 } /* set_dbg_level */
666 * Redirects the debug output of module name to fname
668 static void set_dbg_outfile(const char *name, const char *fname)
670 firm_dbg_module_t *module = dbg_register(name);
671 FILE *f = fopen(fname, "w");
678 firm_dbg_set_file(module, f);
679 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
680 } /* set_dbg_outfile */
683 * Show info about a firm thing.
685 static void show_firm_object(void *firm_thing) {
688 if (firm_thing == NULL) {
689 fprintf(f, "<NULL>\n");
692 switch (get_kind(firm_thing)) {
694 fprintf(f, "BAD: (%p)\n", firm_thing);
697 dump_entity_to_file(f, firm_thing, dump_verbosity_max);
700 dump_type_to_file(f, firm_thing, dump_verbosity_max);
708 case k_ir_compound_graph_path:
714 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
716 } /* show_firm_object */
719 * Find a firm type by its number.
721 static ir_type *find_type_nr(long nr) {
722 int i, n = get_irp_n_types();
725 for (i = 0; i < n; ++i) {
726 tp = get_irp_type(i);
727 if (get_type_nr(tp) == nr)
730 tp = get_glob_type();
731 if (get_type_nr(tp) == nr)
737 * Find a firm type by its name.
739 static ir_type *find_type_name(const char *name) {
740 int i, n = get_irp_n_types();
743 for (i = 0; i < n; ++i) {
744 tp = get_irp_type(i);
745 if (strcmp(get_type_name(tp), name) == 0)
748 tp = get_glob_type();
749 if (strcmp(get_type_name(tp), name) == 0)
752 } /* find_type_name */
754 /** The environment for the entity search functions. */
755 typedef struct find_env {
757 long nr; /**< the number that is searched for */
758 const char *name; /**< the name that is searched for */
760 ir_entity *res; /**< the result */
764 * Type-walker: Find an entity with given number.
766 static void check_ent_nr(type_or_ent tore, void *ctx) {
767 find_env_t *env = ctx;
769 if (is_entity(tore.ent)) {
770 if (get_entity_nr(tore.ent) == env->u.nr) {
777 * Type-walker: Find an entity with given name.
779 static void check_ent_name(type_or_ent tore, void *ctx) {
780 find_env_t *env = ctx;
782 if (is_entity(tore.ent))
783 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
786 } /* check_ent_name */
789 * Find a firm entity by its number.
791 static ir_entity *find_entity_nr(long nr) {
796 type_walk(check_ent_nr, NULL, &env);
798 } /* find_entity_nr */
801 * Find a firm entity by its name.
803 static ir_entity *find_entity_name(const char *name) {
808 type_walk(check_ent_name, NULL, &env);
810 } /* find_entity_name */
813 * Search methods for a name.
815 static void show_by_name(type_or_ent tore, void *env) {
816 ident *id = (ident *)env;
818 if (is_entity(tore.ent)) {
819 ir_entity *ent = tore.ent;
821 if (is_method_entity(ent)) {
822 if (get_entity_ident(ent) == id) {
823 ir_type *owner = get_entity_owner(ent);
824 ir_graph *irg = get_entity_irg(ent);
826 if (owner != get_glob_type()) {
827 printf("%s::%s", get_type_name(owner), get_id_str(id));
829 printf("%s", get_id_str(id));
832 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
841 * Search methods for a ldname.
843 static void show_by_ldname(type_or_ent tore, void *env) {
844 ident *id = (ident *)env;
846 if (is_entity(tore.ent)) {
847 ir_entity *ent = tore.ent;
849 if (is_method_entity(ent)) {
850 if (get_entity_ld_ident(ent) == id) {
851 ir_type *owner = get_entity_owner(ent);
852 ir_graph *irg = get_entity_irg(ent);
854 if (owner != get_glob_type()) {
855 printf("%s::%s", get_type_name(owner), get_id_str(id));
857 printf("%s", get_id_str(id));
860 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
866 } /* show_by_ldname */
869 * prints the address and graph number of all irgs with given name
871 static void irg_name(const char *name) {
872 ident *id = new_id_from_str(name);
874 type_walk(show_by_name, NULL, (void *)id);
878 * prints the address and graph number of all irgs with given ld_name
880 static void irg_ld_name(const char *name) {
881 ident *id = new_id_from_str(name);
883 type_walk(show_by_ldname, NULL, (void *)id);
911 static const char *reserved[] = {
935 static struct lexer {
936 int has_token; /**< set if a token is cached. */
937 unsigned cur_token; /**< current token. */
938 unsigned number; /**< current token attribute. */
939 const char *s; /**< current token attribute. */
940 unsigned len; /**< current token attribute. */
942 const char *curr_pos;
944 const char *tok_start;
948 * Initialize the lexer.
950 static void init_lexer(const char *input) {
952 lexer.curr_pos = input;
953 lexer.end_pos = input + strlen(input);
958 * Get the next char from the input.
960 static char next_char(void) {
961 if (lexer.curr_pos >= lexer.end_pos)
963 return *lexer.curr_pos++;
966 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
969 #define MIN(a, b) (a) < (b) ? (a) : (b)
974 static unsigned get_token(void) {
978 /* skip white space */
981 } while (c != '\0' && isspace(c));
983 lexer.tok_start = lexer.curr_pos - 1;
984 if (c == '.' || isalpha(c)) {
985 /* command begins here */
987 const char* tok_start;
992 } while (isgraph(c));
995 tok_start = lexer.tok_start;
996 if (*tok_start == '.') {
1000 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
1001 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
1006 lexer.s = lexer.tok_start;
1007 lexer.len = lexer.curr_pos - lexer.s;
1008 return tok_identifier;
1009 } else if (isdigit(c) || c == '-') {
1010 unsigned number = 0;
1013 /* we support negative numbers as well, so one can easily set all bits with -1 */
1022 if (c == 'x' || c == 'X') {
1029 number = (number << 4) | (c - '0');
1031 number = (number << 4) | (toupper(c) - 'A' + 10);
1034 lexer.number = number;
1041 number = number * 10 + (c - '0');
1045 lexer.number = sign ? 0 - number : number;
1054 * High level function to use from debugger interface
1056 * See show_commands() for supported commands.
1058 void firm_debug(const char *cmd) {
1059 char name[1024], fname[1024];
1067 token = get_token();
1074 token = get_token();
1075 if (token != tok_number)
1077 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1081 token = get_token();
1082 if (token != tok_number)
1084 break_on_nr(lexer.number, BP_ON_REPLACE);
1088 token = get_token();
1089 if (token != tok_number)
1091 break_on_nr(lexer.number, BP_ON_LOWER);
1095 token = get_token();
1097 if (token == tok_number)
1098 break_on_nr(lexer.number, BP_ON_REMIRG);
1099 else if (token == tok_identifier) {
1100 len = MIN(lexer.len, 1023);
1101 strncpy(name, lexer.s, len);
1103 break_on_ident(name, BP_ON_REMIRG);
1109 token = get_token();
1111 if (token == tok_number)
1112 break_on_nr(lexer.number, BP_ON_NEW_ENT);
1113 else if (token == tok_identifier) {
1114 len = MIN(lexer.len, 1023);
1115 strncpy(name, lexer.s, len);
1117 break_on_ident(name, BP_ON_NEW_ENT);
1123 token = get_token();
1125 if (token == tok_number)
1126 break_on_nr(lexer.number, BP_ON_NEW_TYPE);
1127 else if (token == tok_identifier) {
1128 len = MIN(lexer.len, 1023);
1129 strncpy(name, lexer.s, len);
1131 break_on_ident(name, BP_ON_NEW_TYPE);
1137 token = get_token();
1139 if (token == tok_number)
1140 show_firm_object(find_type_nr(lexer.number));
1141 else if (token == tok_identifier) {
1142 len = MIN(lexer.len, 1023);
1143 strncpy(name, lexer.s, len);
1145 show_firm_object(find_type_name(name));
1151 token = get_token();
1153 if (token == tok_number)
1154 show_firm_object(find_entity_nr(lexer.number));
1155 else if (token == tok_identifier) {
1156 len = MIN(lexer.len, 1023);
1157 strncpy(name, lexer.s, len);
1159 show_firm_object(find_entity_name(name));
1173 token = get_token();
1174 if (token != tok_number)
1176 bp_activate(lexer.number, 1);
1180 token = get_token();
1181 if (token != tok_number)
1183 bp_activate(lexer.number, 0);
1187 token = get_token();
1188 if (token != tok_identifier)
1190 len = MIN(lexer.len, 1023);
1191 strncpy(name, lexer.s, len);
1194 token = get_token();
1195 if (token != tok_number)
1197 set_dbg_level(name, lexer.number);
1201 token = get_token();
1202 if (token != tok_identifier)
1204 len = MIN(lexer.len, 1023);
1205 strncpy(name, lexer.s, len);
1208 token = get_token();
1209 if (token != tok_number)
1211 set_dbg_level(name, (1 << lexer.number) - 1);
1214 case tok_setoutfile:
1215 token = get_token();
1216 if (token != tok_identifier)
1218 len = MIN(lexer.len, 1023);
1219 strncpy(name, lexer.s, len);
1222 token = get_token();
1223 if (token != tok_identifier)
1225 len = MIN(lexer.len, 1023);
1226 strncpy(fname, lexer.s, len);
1228 set_dbg_outfile(name, fname);
1231 token = get_token();
1232 if (token != tok_identifier)
1234 len = MIN(lexer.len, 1023);
1235 strncpy(name, lexer.s, len);
1240 token = get_token();
1241 if (token != tok_identifier)
1243 len = MIN(lexer.len, 1023);
1244 strncpy(name, lexer.s, len);
1256 printf("Error: before %s\n", lexer.tok_start);
1261 token = get_token();
1262 if (token == tok_eof)
1271 /* creates the debugger tables */
1272 void firm_init_debugger(void)
1276 bp_numbers = new_set(cmp_nr_bp, 8);
1277 bp_idents = new_set(cmp_ident_bp, 8);
1279 env = getenv("FIRMDBG");
1288 } /* firm_init_debugger */
1291 * A gdb helper function to print firm objects.
1293 const char *gdb_node_helper(void *firm_object) {
1294 static char buf[1024];
1295 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1300 * A gdb helper function to print tarvals.
1302 const char *gdb_tarval_helper(void *tv_object) {
1303 static char buf[1024];
1304 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1308 const char *gdb_out_edge_helper(const ir_node *node) {
1309 static char buf[4*1024];
1312 size_t len = sizeof(buf);
1313 const ir_edge_t *edge;
1314 foreach_out_edge(node, edge) {
1315 ir_node *n = get_edge_src_irn(edge);
1317 ir_snprintf(b, len, "%+F ", n);
1328 /* some picky compiler do not allow empty files */
1329 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1334 * @page debugger The Firm debugger extension
1336 * Firm contains a debugger extension. This allows to set debugger breakpoints
1337 * an various events.
1338 * The extension uses a text interface which can be accessed from most debuggers.
1339 * More than one command can be given separated by ';'.
1341 * @section sec_cmd Supported commands
1343 * Historically all debugger commands start with a dot. This isn't needed in newer
1344 * versions, but still supported, ie the commands ".init" and "init" are equal.
1345 * The following commands are currently supported:
1349 * Break immediately after the debugger extension was initialized.
1350 * Typically this command is used in the environment to stop the execution
1351 * of a Firm compiler right after the initialization, like this:
1353 * $export FIRMDBG=".init"
1357 * Break if a new IR-node with node number nr was created.
1358 * Typically used to find the place where wrong nodes are created.
1362 * Break before IR-node with node number nr is replaced by another node.
1366 * Break before IR-node with node number nr is lowered.
1370 * Break if the irg with graph number nr is deleted.
1374 * Break if the irg of entity name is deleted.
1378 * Break if the entity with number nr was created.
1382 * Break if the entity name was created.
1386 * Break if the type with number nr was created.
1390 * Break if the type name was created.
1394 * Show all Firm internal breakpoints.
1398 * Enables breakpoint nr.
1402 * Disables breakpoint nr.
1406 * Show the content of entity nr.
1410 * Show the content of entity name.
1414 * Show the content of type nr.
1418 * Show the content of type name.
1420 * @b setmask name msk
1422 * Sets the debug module name to mask msk.
1424 * @b setlvl name lvl
1426 * Sets the debug module name to level lvl.
1428 * @b setoutfile name file
1430 * Redirects debug output of module name to file.
1434 * Prints address and graph number of a method given by its name.
1438 * Prints address and graph number of a method given by its linker name.
1442 * List all commands.
1445 * The Firm debugger extension can be accessed using the function firm_debug().
1446 * The following example shows how to set a creation breakpoint in GDB when
1447 * node 2101 is created.
1449 * -# set FIRMDBG="init"
1450 * -# start gdb with your compiler
1451 * -# after gdb breaks, issue
1453 * call firm_debug("create 2101")
1455 * On the console the following text should be issued:
1457 * Firm BP 1: creation of Node 2101
1460 * @section gdb_macro GDB macro
1462 * Add the following to your .gdbinit file:
1465 # define firm "cmd" Firm debugger extension
1468 call firm_debug($arg0)
1472 * Then, all Firm debugger extension commands can be accessed in the gdb
1473 * console using the firm prefix, eg.:
1475 * firm "create 2101"