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
32 #define WIN32_LEAN_AND_MEAN
56 #include "irgraph_t.h"
60 #include "iredges_t.h"
65 /* Break into the debugger. The Win32 way. */
66 void firm_debug_break(void) {
69 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
70 /* Break into the debugger. The ia32/x86_64 way under GCC. */
71 void firm_debug_break(void) {
72 __asm__ __volatile__("int3");
75 /* Break into the debugger. Poor Unix way. */
76 void firm_debug_break(void) {
81 /** supported breakpoint kinds */
83 BP_NR = 'n', /**< break on node number. */
84 BP_IDENT = 'i' /**< break on ident. */
88 * Reasons for node number breakpoints.
90 typedef enum _bp_reasons_t {
91 BP_ON_NEW_NODE, /**< break if node with number is created */
92 BP_ON_REPLACE, /**< break if node with number is replaced */
93 BP_ON_LOWER, /**< break if node with number is lowered */
94 BP_ON_REMIRG, /**< break if an IRG is removed */
95 BP_ON_NEW_ENT, /**< break if a new entity is created */
96 BP_ON_NEW_TYPE, /**< break if a new type is created */
101 typedef struct _breakpoint {
102 bp_kind kind; /**< the kind of this break point */
103 unsigned bpnr; /**< break point number */
104 int active; /**< non-zero, if this break point is active */
105 bp_reasons_t reason; /**< reason for the breakpoint */
106 struct _breakpoint *next; /**< link to the next one */
109 /** A number breakpoint. */
111 breakpoint bp; /**< the breakpoint data */
112 long nr; /**< the node number */
115 /** Calculate the hash value for a node breakpoint. */
116 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
118 /** An ident breakpoint. */
120 breakpoint bp; /**< the breakpoint data */
121 ident *id; /**< the ident */
124 /** Calculate the hash value for an ident breakpoint. */
125 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
127 /** The set containing the breakpoints on node numbers. */
128 static set *bp_numbers;
130 /** The set containing the breakpoints on idents. */
131 static set *bp_idents;
133 /**< the list of all breakpoints */
134 static breakpoint *bp_list;
136 /** number of the current break point */
137 static unsigned bp_num = 0;
139 /** set if break on init command was issued. */
140 static int break_on_init = 0;
142 /** the hook entries for the Firm debugger module. */
143 static hook_entry_t debugger_hooks[hook_last];
145 /** number of active breakpoints to maintain hooks. */
146 static unsigned num_active_bp[BP_MAX_REASON];
149 * The debug message buffer
151 static char firm_dbg_msg_buf[2048];
154 * If set, the debug extension writes all output to the
155 * firm_dbg_msg_buf buffer
157 static int redir_output = 0;
160 * Is set to one, if the debug extension is active
162 static int is_active = 0;
164 /** hook the hook h with function fkt. */
165 #define HOOK(h, fkt) \
167 debugger_hooks[h].hook._##h = fkt; \
168 register_hook(h, &debugger_hooks[h]); \
171 /** unhook the hook h */
174 unregister_hook(h, &debugger_hooks[h]); \
175 debugger_hooks[h].hook._##h = NULL; \
178 /** returns non-zero if a entry hook h is used */
179 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
181 /* some macros needed to create the info string */
182 #define _DBG_VERSION(major, minor) #major "." #minor
183 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
184 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
186 /* the API version: change if needed */
187 #define FIRM_DBG_MAJOR 1
188 #define FIRM_DBG_MINOR 0
190 /** for automatic detection of the debug extension */
191 static const char firm_debug_info_string[] =
192 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
195 * Returns non-zero, if the debug extension is active
197 int firm_debug_active(void) {
199 } /* firm_debug_active */
202 * Reset the debug text buffer.
204 static void reset_dbg_buf(void) {
205 firm_dbg_msg_buf[0] = '\0';
206 } /* reset_dbg_buf */
209 * Add text to the debug text buffer.
211 static void add_to_dbg_buf(const char *buf) {
212 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
213 } /* add_to_dbg_buf */
216 * Return the content of the debug text buffer.
218 * To be called from the debugger.
220 const char *firm_debug_text(void) {
221 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
222 return firm_dbg_msg_buf;
223 } /* firm_debug_text */
228 static void dbg_printf(const char *fmt, ...)
240 ir_vsnprintf(buf, sizeof(buf), fmt, args);
250 * A new node is created.
252 * @param ctx the hook context
253 * @param irg the IR graph on which the node is created
254 * @param node the new IR node that was created
256 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
262 key.nr = get_irn_node_nr(node);
263 key.bp.reason = BP_ON_NEW_NODE;
265 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
266 if (elem && elem->bp.active) {
267 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
273 * A node is replaced.
275 * @param ctx the hook context
276 * @param old the IR node the is replaced
277 * @param nw the new IR node that will replace old
279 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
284 key.nr = get_irn_node_nr(old);
285 key.bp.reason = BP_ON_REPLACE;
287 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
288 if (elem && elem->bp.active) {
289 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
295 * A new node is lowered.
297 * @param ctx the hook context
298 * @param node the new IR node that will be lowered
300 static void dbg_lower(void *ctx, ir_node *node)
305 key.nr = get_irn_node_nr(node);
306 key.bp.reason = BP_ON_LOWER;
308 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
309 if (elem && elem->bp.active) {
310 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
316 * A graph will be deleted.
318 * @param ctx the hook context
319 * @param irg the IR graph that will be deleted
321 static void dbg_free_graph(void *ctx, ir_graph *irg)
326 key.nr = get_irg_graph_nr(irg);
327 key.bp.reason = BP_ON_REMIRG;
329 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
330 if (elem && elem->bp.active) {
331 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
336 bp_ident_t key, *elem;
337 ir_entity *ent = get_irg_entity(irg);
342 key.id = get_entity_ident(ent);
343 key.bp.reason = BP_ON_REMIRG;
345 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
346 if (elem && elem->bp.active) {
347 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
351 } /* dbg_free_graph */
354 * An entity was created.
356 * @param ctx the hook context
357 * @param ent the newly created entity
359 static void dbg_new_entity(void *ctx, ir_entity *ent)
363 bp_ident_t key, *elem;
365 key.id = get_entity_ident(ent);
366 key.bp.reason = BP_ON_NEW_ENT;
368 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
369 if (elem && elem->bp.active) {
370 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
377 key.nr = get_entity_nr(ent);
378 key.bp.reason = BP_ON_NEW_ENT;
380 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
381 if (elem && elem->bp.active) {
382 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
386 } /* dbg_new_entity */
389 * A type was created.
391 * @param ctx the hook context
392 * @param tp the newly created type
394 static void dbg_new_type(void *ctx, ir_type *tp)
400 key.nr = get_type_nr(tp);
401 key.bp.reason = BP_ON_NEW_TYPE;
403 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
404 if (elem && elem->bp.active) {
405 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
410 bp_ident_t key, *elem;
412 key.id = get_type_ident(tp);
413 key.bp.reason = BP_ON_NEW_TYPE;
415 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
416 if (elem && elem->bp.active) {
417 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
424 * Return the reason string.
426 static const char *reason_str(bp_reasons_t reason)
429 case BP_ON_NEW_NODE: return "node creation";
430 case BP_ON_REPLACE: return "node replace";
431 case BP_ON_LOWER: return "node lowering";
432 case BP_ON_REMIRG: return "removing IRG";
433 case BP_ON_NEW_ENT: return "entity creation";
434 case BP_ON_NEW_TYPE: return "type creation";
435 case BP_MAX_REASON: break;
437 panic("unsupported reason");
441 * Compare two number breakpoints.
443 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
445 const bp_nr_t *e1 = elt;
446 const bp_nr_t *e2 = key;
449 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
453 * Compare two ident breakpoints.
455 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
457 const bp_ident_t *e1 = elt;
458 const bp_ident_t *e2 = key;
461 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
467 static void update_hooks(breakpoint *bp)
469 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
470 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
473 ++num_active_bp[bp->reason];
475 --num_active_bp[bp->reason];
477 if (num_active_bp[bp->reason] > 0) {
478 /* register the hooks on demand */
479 switch (bp->reason) {
480 CASE_ON(BP_ON_NEW_NODE, new_node);
481 CASE_ON(BP_ON_REPLACE, replace);
482 CASE_ON(BP_ON_LOWER, lower);
483 CASE_ON(BP_ON_REMIRG, free_graph);
484 CASE_ON(BP_ON_NEW_ENT, new_entity);
485 CASE_ON(BP_ON_NEW_TYPE, new_type);
491 /* unregister the hook on demand */
492 switch (bp->reason) {
493 CASE_OFF(BP_ON_NEW_NODE, new_node);
494 CASE_OFF(BP_ON_REPLACE, replace);
495 CASE_OFF(BP_ON_LOWER, lower);
496 CASE_OFF(BP_ON_REMIRG, free_graph);
497 CASE_OFF(BP_ON_NEW_ENT, new_entity);
498 CASE_OFF(BP_ON_NEW_TYPE, new_type);
508 * Break if nr is reached.
510 static void break_on_nr(long nr, bp_reasons_t reason)
517 key.bp.reason = reason;
520 elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
522 if (elem->bp.bpnr == 0) {
523 /* new break point */
524 elem->bp.bpnr = ++bp_num;
525 elem->bp.next = bp_list;
528 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
530 update_hooks(&elem->bp);
535 * Break if ident name is reached.
537 static void break_on_ident(const char *name, bp_reasons_t reason) {
538 bp_ident_t key, *elem;
540 key.bp.kind = BP_IDENT;
543 key.bp.reason = reason;
544 key.id = new_id_from_str(name);
546 elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
548 if (elem->bp.bpnr == 0) {
549 /* new break point */
550 elem->bp.bpnr = ++bp_num;
551 elem->bp.next = bp_list;
554 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
556 update_hooks(&elem->bp);
558 } /* break_on_ident */
561 * Sets/resets the active flag of breakpoint bp.
563 static void bp_activate(unsigned bp, int active)
567 for (p = bp_list; p; p = p->next) {
569 if (p->active != active) {
574 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
578 dbg_printf("Error: Firm BP %u not exists.\n", bp);
583 * Show a list of supported commands
585 static void show_commands(void) {
586 dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
587 "init break after initialization\n"
588 "create nr break if node nr was created\n"
589 "replace nr break if node nr is replaced by another node\n"
590 "lower nr break before node nr is lowered\n"
591 "remirg nr|name break if the irg of nr or entity name is deleted\n"
592 "newent nr|name break if the entity nr or name was created\n"
593 "newtype nr|name break if the type nr or name was created\n"
594 "bp show all breakpoints\n"
595 "enable nr enable breakpoint nr\n"
596 "disable nr disable breakpoint nr\n"
597 "showtype nr|name show content of the type nr or name\n"
598 "showent nr|name show content of the entity nr or name\n"
599 "setmask name msk sets the debug module name to mask msk\n"
600 "setlvl name lvl sets the debug module name to level lvl\n"
601 "setoutfile name file redirects debug output of module name to file\n"
602 "irgname name prints address and graph number of a method given by its name\n"
603 "irgldname ldname prints address and graph number of a method given by its ldname\n"
604 "help list all commands\n"
606 } /* show_commands */
609 * Shows all Firm breakpoints.
611 static void show_bp(void) {
617 dbg_printf("Firm Breakpoints:");
618 for (p = bp_list; p; p = p->next) {
620 dbg_printf("+\n BP %u: ", p->bpnr);
624 node_p = (bp_nr_t *)p;
625 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
629 ident_p = (bp_ident_t *)p;
630 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
634 dbg_printf(p->active ? "+enabled" : "+disabled");
636 dbg_printf(have_one ? "+\n" : "+ NONE\n");
640 * firm_dbg_register() expects that the name is stored persistent.
641 * So we need this little helper function
643 static firm_dbg_module_t *dbg_register(const char *name) {
644 ident *id = new_id_from_str(name);
646 return firm_dbg_register(get_id_str(id));
650 * Sets the debug mask of module name to lvl
652 static void set_dbg_level(const char *name, unsigned lvl)
654 firm_dbg_module_t *module = dbg_register(name);
656 if (firm_dbg_get_mask(module) != lvl) {
657 firm_dbg_set_mask(module, lvl);
659 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
661 } /* set_dbg_level */
664 * Redirects the debug output of module name to fname
666 static void set_dbg_outfile(const char *name, const char *fname)
668 firm_dbg_module_t *module = dbg_register(name);
669 FILE *f = fopen(fname, "w");
676 firm_dbg_set_file(module, f);
677 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
678 } /* set_dbg_outfile */
681 * Show info about a firm thing.
683 static void show_firm_object(void *firm_thing) {
686 if (firm_thing == NULL) {
687 fprintf(f, "<NULL>\n");
690 switch (get_kind(firm_thing)) {
692 fprintf(f, "BAD: (%p)\n", firm_thing);
695 dump_entity_to_file(f, firm_thing, dump_verbosity_max);
698 dump_type_to_file(f, firm_thing, dump_verbosity_max);
706 case k_ir_compound_graph_path:
712 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
714 } /* show_firm_object */
717 * Find a firm type by its number.
719 static ir_type *find_type_nr(long nr) {
720 int i, n = get_irp_n_types();
723 for (i = 0; i < n; ++i) {
724 tp = get_irp_type(i);
725 if (get_type_nr(tp) == nr)
728 tp = get_glob_type();
729 if (get_type_nr(tp) == nr)
735 * Find a firm type by its name.
737 static ir_type *find_type_name(const char *name) {
738 int i, n = get_irp_n_types();
741 for (i = 0; i < n; ++i) {
742 tp = get_irp_type(i);
743 if (strcmp(get_type_name(tp), name) == 0)
746 tp = get_glob_type();
747 if (strcmp(get_type_name(tp), name) == 0)
750 } /* find_type_name */
752 /** The environment for the entity search functions. */
753 typedef struct find_env {
755 long nr; /**< the number that is searched for */
756 const char *name; /**< the name that is searched for */
758 ir_entity *res; /**< the result */
762 * Type-walker: Find an entity with given number.
764 static void check_ent_nr(type_or_ent tore, void *ctx) {
765 find_env_t *env = ctx;
767 if (is_entity(tore.ent)) {
768 if (get_entity_nr(tore.ent) == env->u.nr) {
775 * Type-walker: Find an entity with given name.
777 static void check_ent_name(type_or_ent tore, void *ctx) {
778 find_env_t *env = ctx;
780 if (is_entity(tore.ent))
781 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
784 } /* check_ent_name */
787 * Find a firm entity by its number.
789 static ir_entity *find_entity_nr(long nr) {
794 type_walk(check_ent_nr, NULL, &env);
796 } /* find_entity_nr */
799 * Find a firm entity by its name.
801 static ir_entity *find_entity_name(const char *name) {
806 type_walk(check_ent_name, NULL, &env);
808 } /* find_entity_name */
811 * Search methods for a name.
813 static void show_by_name(type_or_ent tore, void *env) {
814 ident *id = (ident *)env;
816 if (is_entity(tore.ent)) {
817 ir_entity *ent = tore.ent;
819 if (is_method_entity(ent)) {
820 if (get_entity_ident(ent) == id) {
821 ir_type *owner = get_entity_owner(ent);
822 ir_graph *irg = get_entity_irg(ent);
824 if (owner != get_glob_type()) {
825 printf("%s::%s", get_type_name(owner), get_id_str(id));
827 printf("%s", get_id_str(id));
830 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
839 * Search methods for a ldname.
841 static void show_by_ldname(type_or_ent tore, void *env) {
842 ident *id = (ident *)env;
844 if (is_entity(tore.ent)) {
845 ir_entity *ent = tore.ent;
847 if (is_method_entity(ent)) {
848 if (get_entity_ld_ident(ent) == id) {
849 ir_type *owner = get_entity_owner(ent);
850 ir_graph *irg = get_entity_irg(ent);
852 if (owner != get_glob_type()) {
853 printf("%s::%s", get_type_name(owner), get_id_str(id));
855 printf("%s", get_id_str(id));
858 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
864 } /* show_by_ldname */
867 * prints the address and graph number of all irgs with given name
869 static void irg_name(const char *name) {
870 ident *id = new_id_from_str(name);
872 type_walk(show_by_name, NULL, (void *)id);
876 * prints the address and graph number of all irgs with given ld_name
878 static void irg_ld_name(const char *name) {
879 ident *id = new_id_from_str(name);
881 type_walk(show_by_ldname, NULL, (void *)id);
909 static const char *reserved[] = {
933 static struct lexer {
934 int has_token; /**< set if a token is cached. */
935 unsigned cur_token; /**< current token. */
936 unsigned number; /**< current token attribute. */
937 const char *s; /**< current token attribute. */
938 unsigned len; /**< current token attribute. */
940 const char *curr_pos;
942 const char *tok_start;
946 * Initialize the lexer.
948 static void init_lexer(const char *input) {
950 lexer.curr_pos = input;
951 lexer.end_pos = input + strlen(input);
956 * Get the next char from the input.
958 static char next_char(void) {
959 if (lexer.curr_pos >= lexer.end_pos)
961 return *lexer.curr_pos++;
964 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
967 #define MIN(a, b) (a) < (b) ? (a) : (b)
972 static unsigned get_token(void) {
976 /* skip white space */
979 } while (c != '\0' && isspace(c));
981 lexer.tok_start = lexer.curr_pos - 1;
982 if (c == '.' || isalpha(c)) {
983 /* command begins here */
985 const char* tok_start;
990 } while (isgraph(c));
993 tok_start = lexer.tok_start;
994 if (*tok_start == '.') {
998 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
999 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
1004 lexer.s = lexer.tok_start;
1005 lexer.len = lexer.curr_pos - lexer.s;
1006 return tok_identifier;
1007 } else if (isdigit(c) || c == '-') {
1008 unsigned number = 0;
1011 /* we support negative numbers as well, so one can easily set all bits with -1 */
1020 if (c == 'x' || c == 'X') {
1027 number = (number << 4) | (c - '0');
1029 number = (number << 4) | (toupper(c) - 'A' + 10);
1032 lexer.number = number;
1039 number = number * 10 + (c - '0');
1043 lexer.number = sign ? 0 - number : number;
1052 * High level function to use from debugger interface
1054 * See show_commands() for supported commands.
1056 void firm_debug(const char *cmd) {
1057 char name[1024], fname[1024];
1065 token = get_token();
1072 token = get_token();
1073 if (token != tok_number)
1075 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1079 token = get_token();
1080 if (token != tok_number)
1082 break_on_nr(lexer.number, BP_ON_REPLACE);
1086 token = get_token();
1087 if (token != tok_number)
1089 break_on_nr(lexer.number, BP_ON_LOWER);
1093 token = get_token();
1095 if (token == tok_number)
1096 break_on_nr(lexer.number, BP_ON_REMIRG);
1097 else if (token == tok_identifier) {
1098 len = MIN(lexer.len, 1023);
1099 strncpy(name, lexer.s, len);
1101 break_on_ident(name, BP_ON_REMIRG);
1107 token = get_token();
1109 if (token == tok_number)
1110 break_on_nr(lexer.number, BP_ON_NEW_ENT);
1111 else if (token == tok_identifier) {
1112 len = MIN(lexer.len, 1023);
1113 strncpy(name, lexer.s, len);
1115 break_on_ident(name, BP_ON_NEW_ENT);
1121 token = get_token();
1123 if (token == tok_number)
1124 break_on_nr(lexer.number, BP_ON_NEW_TYPE);
1125 else if (token == tok_identifier) {
1126 len = MIN(lexer.len, 1023);
1127 strncpy(name, lexer.s, len);
1129 break_on_ident(name, BP_ON_NEW_TYPE);
1135 token = get_token();
1137 if (token == tok_number)
1138 show_firm_object(find_type_nr(lexer.number));
1139 else if (token == tok_identifier) {
1140 len = MIN(lexer.len, 1023);
1141 strncpy(name, lexer.s, len);
1143 show_firm_object(find_type_name(name));
1149 token = get_token();
1151 if (token == tok_number)
1152 show_firm_object(find_entity_nr(lexer.number));
1153 else if (token == tok_identifier) {
1154 len = MIN(lexer.len, 1023);
1155 strncpy(name, lexer.s, len);
1157 show_firm_object(find_entity_name(name));
1171 token = get_token();
1172 if (token != tok_number)
1174 bp_activate(lexer.number, 1);
1178 token = get_token();
1179 if (token != tok_number)
1181 bp_activate(lexer.number, 0);
1185 token = get_token();
1186 if (token != tok_identifier)
1188 len = MIN(lexer.len, 1023);
1189 strncpy(name, lexer.s, len);
1192 token = get_token();
1193 if (token != tok_number)
1195 set_dbg_level(name, lexer.number);
1199 token = get_token();
1200 if (token != tok_identifier)
1202 len = MIN(lexer.len, 1023);
1203 strncpy(name, lexer.s, len);
1206 token = get_token();
1207 if (token != tok_number)
1209 set_dbg_level(name, (1 << lexer.number) - 1);
1212 case tok_setoutfile:
1213 token = get_token();
1214 if (token != tok_identifier)
1216 len = MIN(lexer.len, 1023);
1217 strncpy(name, lexer.s, len);
1220 token = get_token();
1221 if (token != tok_identifier)
1223 len = MIN(lexer.len, 1023);
1224 strncpy(fname, lexer.s, len);
1226 set_dbg_outfile(name, fname);
1229 token = get_token();
1230 if (token != tok_identifier)
1232 len = MIN(lexer.len, 1023);
1233 strncpy(name, lexer.s, len);
1238 token = get_token();
1239 if (token != tok_identifier)
1241 len = MIN(lexer.len, 1023);
1242 strncpy(name, lexer.s, len);
1254 printf("Error: before %s\n", lexer.tok_start);
1259 token = get_token();
1260 if (token == tok_eof)
1269 /* creates the debugger tables */
1270 void firm_init_debugger(void)
1274 bp_numbers = new_set(cmp_nr_bp, 8);
1275 bp_idents = new_set(cmp_ident_bp, 8);
1277 env = getenv("FIRMDBG");
1286 } /* firm_init_debugger */
1289 * A gdb helper function to print firm objects.
1291 const char *gdb_node_helper(void *firm_object) {
1292 static char buf[1024];
1293 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1298 * A gdb helper function to print tarvals.
1300 const char *gdb_tarval_helper(void *tv_object) {
1301 static char buf[1024];
1302 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1306 const char *gdb_out_edge_helper(const ir_node *node) {
1307 static char buf[4*1024];
1310 size_t len = sizeof(buf);
1311 const ir_edge_t *edge;
1312 foreach_out_edge(node, edge) {
1313 ir_node *n = get_edge_src_irn(edge);
1315 ir_snprintf(b, len, "%+F ", n);
1326 /* some picky compiler do not allow empty files */
1327 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1332 * @page debugger The Firm debugger extension
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 ';'.
1339 * @section sec_cmd Supported commands
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:
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:
1351 * $export FIRMDBG=".init"
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.
1360 * Break before IR-node with node number nr is replaced by another node.
1364 * Break before IR-node with node number nr is lowered.
1368 * Break if the irg with graph number nr is deleted.
1372 * Break if the irg of entity name is deleted.
1376 * Break if the entity with number nr was created.
1380 * Break if the entity name was created.
1384 * Break if the type with number nr was created.
1388 * Break if the type name was created.
1392 * Show all Firm internal breakpoints.
1396 * Enables breakpoint nr.
1400 * Disables breakpoint nr.
1404 * Show the content of entity nr.
1408 * Show the content of entity name.
1412 * Show the content of type nr.
1416 * Show the content of type name.
1418 * @b setmask name msk
1420 * Sets the debug module name to mask msk.
1422 * @b setlvl name lvl
1424 * Sets the debug module name to level lvl.
1426 * @b setoutfile name file
1428 * Redirects debug output of module name to file.
1432 * Prints address and graph number of a method given by its name.
1436 * Prints address and graph number of a method given by its linker name.
1440 * List all commands.
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.
1447 * -# set FIRMDBG="init"
1448 * -# start gdb with your compiler
1449 * -# after gdb breaks, issue
1451 * call firm_debug("create 2101")
1453 * On the console the following text should be issued:
1455 * Firm BP 1: creation of Node 2101
1458 * @section gdb_macro GDB macro
1460 * Add the following to your .gdbinit file:
1463 # define firm "cmd" Firm debugger extension
1466 call firm_debug($arg0)
1470 * Then, all Firm debugger extension commands can be accessed in the gdb
1471 * console using the firm prefix, eg.:
1473 * firm "create 2101"