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
52 #include "irgraph_t.h"
56 #include "iredges_t.h"
61 /* Break into the debugger. The Win32 way. */
62 void firm_debug_break(void) {
65 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
66 /* Break into the debugger. The ia32/x86_64 way under GCC. */
67 void firm_debug_break(void) {
68 __asm__ __volatile__("int3");
71 /* Break into the debugger. Poor Unix way. */
72 void firm_debug_break(void) {
77 /** supported breakpoint kinds */
79 BP_NR = 'n', /**< break on node number. */
80 BP_IDENT = 'i' /**< break on ident. */
84 * Reasons for node number breakpoints.
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 */
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 */
105 /** A number breakpoint. */
107 breakpoint bp; /**< the breakpoint data */
108 long nr; /**< the node number */
111 /** Calculate the hash value for a node breakpoint. */
112 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
114 /** An ident breakpoint. */
116 breakpoint bp; /**< the breakpoint data */
117 ident *id; /**< the ident */
120 /** Calculate the hash value for an ident breakpoint. */
121 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
123 /** The set containing the breakpoints on node numbers. */
124 static set *bp_numbers;
126 /** The set containing the breakpoints on idents. */
127 static set *bp_idents;
129 /**< the list of all breakpoints */
130 static breakpoint *bp_list;
132 /** number of the current break point */
133 static unsigned bp_num = 0;
135 /** set if break on init command was issued. */
136 static int break_on_init = 0;
138 /** the hook entries for the Firm debugger module. */
139 static hook_entry_t debugger_hooks[hook_last];
141 /** number of active breakpoints to maintain hooks. */
142 static unsigned num_active_bp[BP_MAX_REASON];
145 * The debug message buffer
147 static char firm_dbg_msg_buf[2048];
150 * If set, the debug extension writes all output to the
151 * firm_dbg_msg_buf buffer
153 static int redir_output = 0;
156 * Is set to one, if the debug extension is active
158 static int is_active = 0;
160 /** hook the hook h with function fkt. */
161 #define HOOK(h, fkt) \
163 debugger_hooks[h].hook._##h = fkt; \
164 register_hook(h, &debugger_hooks[h]); \
167 /** unhook the hook h */
170 unregister_hook(h, &debugger_hooks[h]); \
171 debugger_hooks[h].hook._##h = NULL; \
174 /** returns non-zero if a entry hook h is used */
175 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
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)
182 /* the API version: change if needed */
183 #define FIRM_DBG_MAJOR 1
184 #define FIRM_DBG_MINOR 0
186 /** for automatic detection of the debug extension */
187 static const char firm_debug_info_string[] =
188 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
191 * Returns non-zero, if the debug extension is active
193 int firm_debug_active(void) {
195 } /* firm_debug_active */
198 * Reset the debug text buffer.
200 static void reset_dbg_buf(void) {
201 firm_dbg_msg_buf[0] = '\0';
202 } /* reset_dbg_buf */
205 * Add text to the debug text buffer.
207 static void add_to_dbg_buf(const char *buf) {
208 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
209 } /* add_to_dbg_buf */
212 * Return the content of the debug text buffer.
214 * To be called from the debugger.
216 const char *firm_debug_text(void) {
217 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
218 return firm_dbg_msg_buf;
219 } /* firm_debug_text */
224 static void dbg_printf(const char *fmt, ...)
236 ir_vsnprintf(buf, sizeof(buf), fmt, args);
246 * A new node is created.
248 * @param ctx the hook context
249 * @param irg the IR graph on which the node is created
250 * @param node the new IR node that was created
252 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
258 key.nr = get_irn_node_nr(node);
259 key.bp.reason = BP_ON_NEW_NODE;
261 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
262 if (elem && elem->bp.active) {
263 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
269 * A node is replaced.
271 * @param ctx the hook context
272 * @param old the IR node the is replaced
273 * @param nw the new IR node that will replace old
275 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
280 key.nr = get_irn_node_nr(old);
281 key.bp.reason = BP_ON_REPLACE;
283 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
284 if (elem && elem->bp.active) {
285 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
291 * A new node is lowered.
293 * @param ctx the hook context
294 * @param node the new IR node that will be lowered
296 static void dbg_lower(void *ctx, ir_node *node)
301 key.nr = get_irn_node_nr(node);
302 key.bp.reason = BP_ON_LOWER;
304 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
305 if (elem && elem->bp.active) {
306 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
312 * A graph will be deleted.
314 * @param ctx the hook context
315 * @param irg the IR graph that will be deleted
317 static void dbg_free_graph(void *ctx, ir_graph *irg)
322 key.nr = get_irg_graph_nr(irg);
323 key.bp.reason = BP_ON_REMIRG;
325 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
326 if (elem && elem->bp.active) {
327 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
332 bp_ident_t key, *elem;
333 ir_entity *ent = get_irg_entity(irg);
338 key.id = get_entity_ident(ent);
339 key.bp.reason = BP_ON_REMIRG;
341 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
342 if (elem && elem->bp.active) {
343 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
347 } /* dbg_free_graph */
350 * An entity was created.
352 * @param ctx the hook context
353 * @param ent the newly created entity
355 static void dbg_new_entity(void *ctx, ir_entity *ent)
359 bp_ident_t key, *elem;
361 key.id = get_entity_ident(ent);
362 key.bp.reason = BP_ON_NEW_ENT;
364 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
365 if (elem && elem->bp.active) {
366 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
373 key.nr = get_entity_nr(ent);
374 key.bp.reason = BP_ON_NEW_ENT;
376 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
377 if (elem && elem->bp.active) {
378 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
382 } /* dbg_new_entity */
385 * A type was created.
387 * @param ctx the hook context
388 * @param tp the newly created type
390 static void dbg_new_type(void *ctx, ir_type *tp)
396 key.nr = get_type_nr(tp);
397 key.bp.reason = BP_ON_NEW_TYPE;
399 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
400 if (elem && elem->bp.active) {
401 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
406 bp_ident_t key, *elem;
408 key.id = get_type_ident(tp);
409 key.bp.reason = BP_ON_NEW_TYPE;
411 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
412 if (elem && elem->bp.active) {
413 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
420 * Return the reason string.
422 static const char *reason_str(bp_reasons_t reason)
425 case BP_ON_NEW_NODE: return "node creation";
426 case BP_ON_REPLACE: return "node replace";
427 case BP_ON_LOWER: return "node lowering";
428 case BP_ON_REMIRG: return "removing IRG";
429 case BP_ON_NEW_ENT: return "entity creation";
430 case BP_ON_NEW_TYPE: return "type creation";
431 case BP_MAX_REASON: break;
433 panic("unsupported reason");
437 * Compare two number breakpoints.
439 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
441 const bp_nr_t *e1 = elt;
442 const bp_nr_t *e2 = key;
445 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
449 * Compare two ident breakpoints.
451 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
453 const bp_ident_t *e1 = elt;
454 const bp_ident_t *e2 = key;
457 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
463 static void update_hooks(breakpoint *bp)
465 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
466 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
469 ++num_active_bp[bp->reason];
471 --num_active_bp[bp->reason];
473 if (num_active_bp[bp->reason] > 0) {
474 /* register the hooks on demand */
475 switch (bp->reason) {
476 CASE_ON(BP_ON_NEW_NODE, new_node);
477 CASE_ON(BP_ON_REPLACE, replace);
478 CASE_ON(BP_ON_LOWER, lower);
479 CASE_ON(BP_ON_REMIRG, free_graph);
480 CASE_ON(BP_ON_NEW_ENT, new_entity);
481 CASE_ON(BP_ON_NEW_TYPE, new_type);
487 /* unregister the hook on demand */
488 switch (bp->reason) {
489 CASE_OFF(BP_ON_NEW_NODE, new_node);
490 CASE_OFF(BP_ON_REPLACE, replace);
491 CASE_OFF(BP_ON_LOWER, lower);
492 CASE_OFF(BP_ON_REMIRG, free_graph);
493 CASE_OFF(BP_ON_NEW_ENT, new_entity);
494 CASE_OFF(BP_ON_NEW_TYPE, new_type);
504 * Break if nr is reached.
506 static void break_on_nr(long nr, bp_reasons_t reason)
513 key.bp.reason = reason;
516 elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
518 if (elem->bp.bpnr == 0) {
519 /* new break point */
520 elem->bp.bpnr = ++bp_num;
521 elem->bp.next = bp_list;
524 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
526 update_hooks(&elem->bp);
531 * Break if ident name is reached.
533 static void break_on_ident(const char *name, bp_reasons_t reason) {
534 bp_ident_t key, *elem;
536 key.bp.kind = BP_IDENT;
539 key.bp.reason = reason;
540 key.id = new_id_from_str(name);
542 elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
544 if (elem->bp.bpnr == 0) {
545 /* new break point */
546 elem->bp.bpnr = ++bp_num;
547 elem->bp.next = bp_list;
550 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
552 update_hooks(&elem->bp);
554 } /* break_on_ident */
557 * Sets/resets the active flag of breakpoint bp.
559 static void bp_activate(unsigned bp, int active)
563 for (p = bp_list; p; p = p->next) {
565 if (p->active != active) {
570 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
574 dbg_printf("Error: Firm BP %u not exists.\n", bp);
579 * Show a list of supported commands
581 static void show_commands(void) {
582 dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
583 "init break after initialization\n"
584 "create nr break if node nr was created\n"
585 "replace nr break if node nr is replaced by another node\n"
586 "lower nr break before node nr is lowered\n"
587 "remirg nr|name break if the irg of nr or entity name is deleted\n"
588 "newent nr|name break if the entity nr or name was created\n"
589 "newtype nr|name break if the type nr or name was created\n"
590 "bp show all breakpoints\n"
591 "enable nr enable breakpoint nr\n"
592 "disable nr disable breakpoint nr\n"
593 "showtype nr|name show content of the type nr or name\n"
594 "showent nr|name show content of the entity nr or name\n"
595 "setmask name msk sets the debug module name to mask msk\n"
596 "setlvl name lvl sets the debug module name to level lvl\n"
597 "setoutfile name file redirects debug output of module name to file\n"
598 "irgname name prints address and graph number of a method given by its name\n"
599 "irgldname ldname prints address and graph number of a method given by its ldname\n"
600 "help list all commands\n"
602 } /* show_commands */
605 * Shows all Firm breakpoints.
607 static void show_bp(void) {
613 dbg_printf("Firm Breakpoints:");
614 for (p = bp_list; p; p = p->next) {
616 dbg_printf("+\n BP %u: ", p->bpnr);
620 node_p = (bp_nr_t *)p;
621 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
625 ident_p = (bp_ident_t *)p;
626 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
630 dbg_printf(p->active ? "+enabled" : "+disabled");
632 dbg_printf(have_one ? "+\n" : "+ NONE\n");
636 * firm_dbg_register() expects that the name is stored persistent.
637 * So we need this little helper function
639 static firm_dbg_module_t *dbg_register(const char *name) {
640 ident *id = new_id_from_str(name);
642 return firm_dbg_register(get_id_str(id));
646 * Sets the debug mask of module name to lvl
648 static void set_dbg_level(const char *name, unsigned lvl)
650 firm_dbg_module_t *module = dbg_register(name);
652 if (firm_dbg_get_mask(module) != lvl) {
653 firm_dbg_set_mask(module, lvl);
655 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
657 } /* set_dbg_level */
660 * Redirects the debug output of module name to fname
662 static void set_dbg_outfile(const char *name, const char *fname)
664 firm_dbg_module_t *module = dbg_register(name);
665 FILE *f = fopen(fname, "w");
672 firm_dbg_set_file(module, f);
673 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
674 } /* set_dbg_outfile */
677 * Show info about a firm thing.
679 static void show_firm_object(void *firm_thing) {
682 if (firm_thing == NULL) {
683 fprintf(f, "<NULL>\n");
686 switch (get_kind(firm_thing)) {
688 fprintf(f, "BAD: (%p)\n", firm_thing);
691 dump_entity_to_file(f, firm_thing, dump_verbosity_max);
694 dump_type_to_file(f, firm_thing, dump_verbosity_max);
702 case k_ir_compound_graph_path:
708 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
710 } /* show_firm_object */
713 * Find a firm type by its number.
715 static ir_type *find_type_nr(long nr) {
716 int i, n = get_irp_n_types();
719 for (i = 0; i < n; ++i) {
720 tp = get_irp_type(i);
721 if (get_type_nr(tp) == nr)
724 tp = get_glob_type();
725 if (get_type_nr(tp) == nr)
731 * Find a firm type by its name.
733 static ir_type *find_type_name(const char *name) {
734 int i, n = get_irp_n_types();
737 for (i = 0; i < n; ++i) {
738 tp = get_irp_type(i);
739 if (strcmp(get_type_name(tp), name) == 0)
742 tp = get_glob_type();
743 if (strcmp(get_type_name(tp), name) == 0)
746 } /* find_type_name */
748 /** The environment for the entity search functions. */
749 typedef struct find_env {
751 long nr; /**< the number that is searched for */
752 const char *name; /**< the name that is searched for */
754 ir_entity *res; /**< the result */
758 * Type-walker: Find an entity with given number.
760 static void check_ent_nr(type_or_ent tore, void *ctx) {
761 find_env_t *env = ctx;
763 if (is_entity(tore.ent)) {
764 if (get_entity_nr(tore.ent) == env->u.nr) {
771 * Type-walker: Find an entity with given name.
773 static void check_ent_name(type_or_ent tore, void *ctx) {
774 find_env_t *env = ctx;
776 if (is_entity(tore.ent))
777 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
780 } /* check_ent_name */
783 * Find a firm entity by its number.
785 static ir_entity *find_entity_nr(long nr) {
790 type_walk(check_ent_nr, NULL, &env);
792 } /* find_entity_nr */
795 * Find a firm entity by its name.
797 static ir_entity *find_entity_name(const char *name) {
802 type_walk(check_ent_name, NULL, &env);
804 } /* find_entity_name */
807 * Search methods for a name.
809 static void show_by_name(type_or_ent tore, void *env) {
810 ident *id = (ident *)env;
812 if (is_entity(tore.ent)) {
813 ir_entity *ent = tore.ent;
815 if (is_method_entity(ent)) {
816 if (get_entity_ident(ent) == id) {
817 ir_type *owner = get_entity_owner(ent);
818 ir_graph *irg = get_entity_irg(ent);
820 if (owner != get_glob_type()) {
821 printf("%s::%s", get_type_name(owner), get_id_str(id));
823 printf("%s", get_id_str(id));
826 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
835 * Search methods for a ldname.
837 static void show_by_ldname(type_or_ent tore, void *env) {
838 ident *id = (ident *)env;
840 if (is_entity(tore.ent)) {
841 ir_entity *ent = tore.ent;
843 if (is_method_entity(ent)) {
844 if (get_entity_ld_ident(ent) == id) {
845 ir_type *owner = get_entity_owner(ent);
846 ir_graph *irg = get_entity_irg(ent);
848 if (owner != get_glob_type()) {
849 printf("%s::%s", get_type_name(owner), get_id_str(id));
851 printf("%s", get_id_str(id));
854 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
860 } /* show_by_ldname */
863 * prints the address and graph number of all irgs with given name
865 static void irg_name(const char *name) {
866 ident *id = new_id_from_str(name);
868 type_walk(show_by_name, NULL, (void *)id);
872 * prints the address and graph number of all irgs with given ld_name
874 static void irg_ld_name(const char *name) {
875 ident *id = new_id_from_str(name);
877 type_walk(show_by_ldname, NULL, (void *)id);
905 static const char *reserved[] = {
929 static struct lexer {
930 int has_token; /**< set if a token is cached. */
931 unsigned cur_token; /**< current token. */
932 unsigned number; /**< current token attribute. */
933 const char *s; /**< current token attribute. */
934 unsigned len; /**< current token attribute. */
936 const char *curr_pos;
938 const char *tok_start;
942 * Initialize the lexer.
944 static void init_lexer(const char *input) {
946 lexer.curr_pos = input;
947 lexer.end_pos = input + strlen(input);
952 * Get the next char from the input.
954 static char next_char(void) {
955 if (lexer.curr_pos >= lexer.end_pos)
957 return *lexer.curr_pos++;
960 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
963 #define MIN(a, b) (a) < (b) ? (a) : (b)
968 static unsigned get_token(void) {
972 /* skip white space */
975 } while (c != '\0' && isspace(c));
977 lexer.tok_start = lexer.curr_pos - 1;
978 if (c == '.' || isalpha(c)) {
979 /* command begins here */
981 const char* tok_start;
986 } while (isgraph(c));
989 tok_start = lexer.tok_start;
990 if (*tok_start == '.') {
994 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
995 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
1000 lexer.s = lexer.tok_start;
1001 lexer.len = lexer.curr_pos - lexer.s;
1002 return tok_identifier;
1003 } else if (isdigit(c) || c == '-') {
1004 unsigned number = 0;
1007 /* we support negative numbers as well, so one can easily set all bits with -1 */
1016 if (c == 'x' || c == 'X') {
1023 number = (number << 4) | (c - '0');
1025 number = (number << 4) | (toupper(c) - 'A' + 10);
1028 lexer.number = number;
1035 number = number * 10 + (c - '0');
1039 lexer.number = sign ? 0 - number : number;
1048 * High level function to use from debugger interface
1050 * See show_commands() for supported commands.
1052 void firm_debug(const char *cmd) {
1053 char name[1024], fname[1024];
1061 token = get_token();
1068 token = get_token();
1069 if (token != tok_number)
1071 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1075 token = get_token();
1076 if (token != tok_number)
1078 break_on_nr(lexer.number, BP_ON_REPLACE);
1082 token = get_token();
1083 if (token != tok_number)
1085 break_on_nr(lexer.number, BP_ON_LOWER);
1089 token = get_token();
1091 if (token == tok_number)
1092 break_on_nr(lexer.number, BP_ON_REMIRG);
1093 else if (token == tok_identifier) {
1094 len = MIN(lexer.len, 1023);
1095 strncpy(name, lexer.s, len);
1097 break_on_ident(name, BP_ON_REMIRG);
1103 token = get_token();
1105 if (token == tok_number)
1106 break_on_nr(lexer.number, BP_ON_NEW_ENT);
1107 else if (token == tok_identifier) {
1108 len = MIN(lexer.len, 1023);
1109 strncpy(name, lexer.s, len);
1111 break_on_ident(name, BP_ON_NEW_ENT);
1117 token = get_token();
1119 if (token == tok_number)
1120 break_on_nr(lexer.number, BP_ON_NEW_TYPE);
1121 else if (token == tok_identifier) {
1122 len = MIN(lexer.len, 1023);
1123 strncpy(name, lexer.s, len);
1125 break_on_ident(name, BP_ON_NEW_TYPE);
1131 token = get_token();
1133 if (token == tok_number)
1134 show_firm_object(find_type_nr(lexer.number));
1135 else if (token == tok_identifier) {
1136 len = MIN(lexer.len, 1023);
1137 strncpy(name, lexer.s, len);
1139 show_firm_object(find_type_name(name));
1145 token = get_token();
1147 if (token == tok_number)
1148 show_firm_object(find_entity_nr(lexer.number));
1149 else if (token == tok_identifier) {
1150 len = MIN(lexer.len, 1023);
1151 strncpy(name, lexer.s, len);
1153 show_firm_object(find_entity_name(name));
1167 token = get_token();
1168 if (token != tok_number)
1170 bp_activate(lexer.number, 1);
1174 token = get_token();
1175 if (token != tok_number)
1177 bp_activate(lexer.number, 0);
1181 token = get_token();
1182 if (token != tok_identifier)
1184 len = MIN(lexer.len, 1023);
1185 strncpy(name, lexer.s, len);
1188 token = get_token();
1189 if (token != tok_number)
1191 set_dbg_level(name, lexer.number);
1195 token = get_token();
1196 if (token != tok_identifier)
1198 len = MIN(lexer.len, 1023);
1199 strncpy(name, lexer.s, len);
1202 token = get_token();
1203 if (token != tok_number)
1205 set_dbg_level(name, (1 << lexer.number) - 1);
1208 case tok_setoutfile:
1209 token = get_token();
1210 if (token != tok_identifier)
1212 len = MIN(lexer.len, 1023);
1213 strncpy(name, lexer.s, len);
1216 token = get_token();
1217 if (token != tok_identifier)
1219 len = MIN(lexer.len, 1023);
1220 strncpy(fname, lexer.s, len);
1222 set_dbg_outfile(name, fname);
1225 token = get_token();
1226 if (token != tok_identifier)
1228 len = MIN(lexer.len, 1023);
1229 strncpy(name, lexer.s, len);
1234 token = get_token();
1235 if (token != tok_identifier)
1237 len = MIN(lexer.len, 1023);
1238 strncpy(name, lexer.s, len);
1250 printf("Error: before %s\n", lexer.tok_start);
1255 token = get_token();
1256 if (token == tok_eof)
1265 /* creates the debugger tables */
1266 void firm_init_debugger(void)
1270 bp_numbers = new_set(cmp_nr_bp, 8);
1271 bp_idents = new_set(cmp_ident_bp, 8);
1273 env = getenv("FIRMDBG");
1282 } /* firm_init_debugger */
1285 * A gdb helper function to print firm objects.
1287 const char *gdb_node_helper(void *firm_object) {
1288 static char buf[1024];
1289 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1294 * A gdb helper function to print tarvals.
1296 const char *gdb_tarval_helper(void *tv_object) {
1297 static char buf[1024];
1298 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1302 const char *gdb_out_edge_helper(const ir_node *node) {
1303 static char buf[4*1024];
1306 size_t len = sizeof(buf);
1307 const ir_edge_t *edge;
1308 foreach_out_edge(node, edge) {
1309 ir_node *n = get_edge_src_irn(edge);
1311 ir_snprintf(b, len, "%+F ", n);
1322 /* some picky compiler do not allow empty files */
1323 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1328 * @page debugger The Firm debugger extension
1330 * Firm contains a debugger extension. This allows to set debugger breakpoints
1331 * an various events.
1332 * The extension uses a text interface which can be accessed from most debuggers.
1333 * More than one command can be given separated by ';'.
1335 * @section sec_cmd Supported commands
1337 * Historically all debugger commands start with a dot. This isn't needed in newer
1338 * versions, but still supported, ie the commands ".init" and "init" are equal.
1339 * The following commands are currently supported:
1343 * Break immediately after the debugger extension was initialized.
1344 * Typically this command is used in the environment to stop the execution
1345 * of a Firm compiler right after the initialization, like this:
1347 * $export FIRMDBG=".init"
1351 * Break if a new IR-node with node number nr was created.
1352 * Typically used to find the place where wrong nodes are created.
1356 * Break before IR-node with node number nr is replaced by another node.
1360 * Break before IR-node with node number nr is lowered.
1364 * Break if the irg with graph number nr is deleted.
1368 * Break if the irg of entity name is deleted.
1372 * Break if the entity with number nr was created.
1376 * Break if the entity name was created.
1380 * Break if the type with number nr was created.
1384 * Break if the type name was created.
1388 * Show all Firm internal breakpoints.
1392 * Enables breakpoint nr.
1396 * Disables breakpoint nr.
1400 * Show the content of entity nr.
1404 * Show the content of entity name.
1408 * Show the content of type nr.
1412 * Show the content of type name.
1414 * @b setmask name msk
1416 * Sets the debug module name to mask msk.
1418 * @b setlvl name lvl
1420 * Sets the debug module name to level lvl.
1422 * @b setoutfile name file
1424 * Redirects debug output of module name to file.
1428 * Prints address and graph number of a method given by its name.
1432 * Prints address and graph number of a method given by its linker name.
1436 * List all commands.
1439 * The Firm debugger extension can be accessed using the function firm_debug().
1440 * The following example shows how to set a creation breakpoint in GDB when
1441 * node 2101 is created.
1443 * -# set FIRMDBG="init"
1444 * -# start gdb with your compiler
1445 * -# after gdb breaks, issue
1447 * call firm_debug("create 2101")
1449 * On the console the following text should be issued:
1451 * Firm BP 1: creation of Node 2101
1454 * @section gdb_macro GDB macro
1456 * Add the following to your .gdbinit file:
1459 # define firm "cmd" Firm debugger extension
1462 call firm_debug($arg0)
1466 * Then, all Firm debugger extension commands can be accessed in the gdb
1467 * console using the firm prefix, eg.:
1469 * firm "create 2101"