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
50 #include "irgraph_t.h"
54 #include "iredges_t.h"
59 /* Break into the debugger. The Win32 way. */
60 void firm_debug_break(void) {
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 __asm__ __volatile__("int3");
69 /* Break into the debugger. Poor Unix way. */
70 void firm_debug_break(void) {
75 /** supported breakpoint kinds */
77 BP_NR = 'n', /**< break on node number. */
78 BP_IDENT = 'i' /**< break on ident. */
82 * Reasons for node number breakpoints.
84 typedef enum _bp_reasons_t {
85 BP_ON_NEW_NODE, /**< break if node with number is created */
86 BP_ON_REPLACE, /**< break if node with number is replaced */
87 BP_ON_LOWER, /**< break if node with number is lowered */
88 BP_ON_REMIRG, /**< break if an IRG is removed */
89 BP_ON_NEW_ENT, /**< break if a new entity is created */
90 BP_ON_NEW_TYPE, /**< break if a new type is created */
95 typedef struct _breakpoint {
96 bp_kind kind; /**< the kind of this break point */
97 unsigned bpnr; /**< break point number */
98 int active; /**< non-zero, if this break point is active */
99 bp_reasons_t reason; /**< reason for the breakpoint */
100 struct _breakpoint *next; /**< link to the next one */
103 /** A number breakpoint. */
105 breakpoint bp; /**< the breakpoint data */
106 long nr; /**< the node number */
109 /** Calculate the hash value for a node breakpoint. */
110 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
112 /** An ident breakpoint. */
114 breakpoint bp; /**< the breakpoint data */
115 ident *id; /**< the ident */
118 /** Calculate the hash value for an ident breakpoint. */
119 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
121 /** The set containing the breakpoints on node numbers. */
122 static set *bp_numbers;
124 /** The set containing the breakpoints on idents. */
125 static set *bp_idents;
127 /**< the list of all breakpoints */
128 static breakpoint *bp_list;
130 /** number of the current break point */
131 static unsigned bp_num = 0;
133 /** set if break on init command was issued. */
134 static int break_on_init = 0;
136 /** the hook entries for the Firm debugger module. */
137 static hook_entry_t debugger_hooks[hook_last];
139 /** number of active breakpoints to maintain hooks. */
140 static unsigned num_active_bp[BP_MAX_REASON];
143 * The debug message buffer
145 static char firm_dbg_msg_buf[2048];
148 * If set, the debug extension writes all output to the
149 * firm_dbg_msg_buf buffer
151 static int redir_output = 0;
154 * Is set to one, if the debug extension is active
156 static int is_active = 0;
158 /** hook the hook h with function fkt. */
159 #define HOOK(h, fkt) \
161 debugger_hooks[h].hook._##h = fkt; \
162 register_hook(h, &debugger_hooks[h]); \
165 /** unhook the hook h */
168 unregister_hook(h, &debugger_hooks[h]); \
169 debugger_hooks[h].hook._##h = NULL; \
172 /** returns non-zero if a entry hook h is used */
173 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
175 /* some macros needed to create the info string */
176 #define _DBG_VERSION(major, minor) #major "." #minor
177 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
178 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
180 /* the API version: change if needed */
181 #define FIRM_DBG_MAJOR 1
182 #define FIRM_DBG_MINOR 0
184 /** for automatic detection of the debug extension */
185 static const char firm_debug_info_string[] =
186 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
189 * Returns non-zero, if the debug extension is active
191 int firm_debug_active(void) {
193 } /* firm_debug_active */
196 * Reset the debug text buffer.
198 static void reset_dbg_buf(void) {
199 firm_dbg_msg_buf[0] = '\0';
200 } /* reset_dbg_buf */
203 * Add text to the debug text buffer.
205 static void add_to_dbg_buf(const char *buf) {
206 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
207 } /* add_to_dbg_buf */
210 * Return the content of the debug text buffer.
212 * To be called from the debugger.
214 const char *firm_debug_text(void) {
215 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
216 return firm_dbg_msg_buf;
217 } /* firm_debug_text */
222 static void dbg_printf(const char *fmt, ...)
234 ir_vsnprintf(buf, sizeof(buf), fmt, args);
244 * A new node is created.
246 * @param ctx the hook context
247 * @param irg the IR graph on which the node is created
248 * @param node the new IR node that was created
250 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
256 key.nr = get_irn_node_nr(node);
257 key.bp.reason = BP_ON_NEW_NODE;
259 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
260 if (elem && elem->bp.active) {
261 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
267 * A node is replaced.
269 * @param ctx the hook context
270 * @param old the IR node the is replaced
271 * @param nw the new IR node that will replace old
273 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
278 key.nr = get_irn_node_nr(old);
279 key.bp.reason = BP_ON_REPLACE;
281 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
282 if (elem && elem->bp.active) {
283 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
289 * A new node is lowered.
291 * @param ctx the hook context
292 * @param node the new IR node that will be lowered
294 static void dbg_lower(void *ctx, ir_node *node)
299 key.nr = get_irn_node_nr(node);
300 key.bp.reason = BP_ON_LOWER;
302 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
303 if (elem && elem->bp.active) {
304 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
310 * A graph will be deleted.
312 * @param ctx the hook context
313 * @param irg the IR graph that will be deleted
315 static void dbg_free_graph(void *ctx, ir_graph *irg)
320 key.nr = get_irg_graph_nr(irg);
321 key.bp.reason = BP_ON_REMIRG;
323 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
324 if (elem && elem->bp.active) {
325 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
330 bp_ident_t key, *elem;
331 ir_entity *ent = get_irg_entity(irg);
336 key.id = get_entity_ident(ent);
337 key.bp.reason = BP_ON_REMIRG;
339 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
340 if (elem && elem->bp.active) {
341 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
345 } /* dbg_free_graph */
348 * An entity was created.
350 * @param ctx the hook context
351 * @param ent the newly created entity
353 static void dbg_new_entity(void *ctx, ir_entity *ent)
357 bp_ident_t key, *elem;
359 key.id = get_entity_ident(ent);
360 key.bp.reason = BP_ON_NEW_ENT;
362 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
363 if (elem && elem->bp.active) {
364 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
371 key.nr = get_entity_nr(ent);
372 key.bp.reason = BP_ON_NEW_ENT;
374 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
375 if (elem && elem->bp.active) {
376 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
380 } /* dbg_new_entity */
383 * A type was created.
385 * @param ctx the hook context
386 * @param tp the newly created type
388 static void dbg_new_type(void *ctx, ir_type *tp)
394 key.nr = get_type_nr(tp);
395 key.bp.reason = BP_ON_NEW_TYPE;
397 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
398 if (elem && elem->bp.active) {
399 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
404 bp_ident_t key, *elem;
406 key.id = get_type_ident(tp);
407 key.bp.reason = BP_ON_NEW_TYPE;
409 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
410 if (elem && elem->bp.active) {
411 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
418 * Return the reason string.
420 static const char *reason_str(bp_reasons_t reason)
423 case BP_ON_NEW_NODE: return "node creation";
424 case BP_ON_REPLACE: return "node replace";
425 case BP_ON_LOWER: return "node lowering";
426 case BP_ON_REMIRG: return "removing IRG";
427 case BP_ON_NEW_ENT: return "entity creation";
428 case BP_ON_NEW_TYPE: return "type creation";
429 case BP_MAX_REASON: break;
431 panic("unsupported reason");
435 * Compare two number breakpoints.
437 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
439 const bp_nr_t *e1 = elt;
440 const bp_nr_t *e2 = key;
443 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
447 * Compare two ident breakpoints.
449 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
451 const bp_ident_t *e1 = elt;
452 const bp_ident_t *e2 = key;
455 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
461 static void update_hooks(breakpoint *bp)
463 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
464 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
467 ++num_active_bp[bp->reason];
469 --num_active_bp[bp->reason];
471 if (num_active_bp[bp->reason] > 0) {
472 /* register the hooks on demand */
473 switch (bp->reason) {
474 CASE_ON(BP_ON_NEW_NODE, new_node);
475 CASE_ON(BP_ON_REPLACE, replace);
476 CASE_ON(BP_ON_LOWER, lower);
477 CASE_ON(BP_ON_REMIRG, free_graph);
478 CASE_ON(BP_ON_NEW_ENT, new_entity);
479 CASE_ON(BP_ON_NEW_TYPE, new_type);
485 /* unregister the hook on demand */
486 switch (bp->reason) {
487 CASE_OFF(BP_ON_NEW_NODE, new_node);
488 CASE_OFF(BP_ON_REPLACE, replace);
489 CASE_OFF(BP_ON_LOWER, lower);
490 CASE_OFF(BP_ON_REMIRG, free_graph);
491 CASE_OFF(BP_ON_NEW_ENT, new_entity);
492 CASE_OFF(BP_ON_NEW_TYPE, new_type);
502 * Break if nr is reached.
504 static void break_on_nr(long nr, bp_reasons_t reason)
511 key.bp.reason = reason;
514 elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
516 if (elem->bp.bpnr == 0) {
517 /* new break point */
518 elem->bp.bpnr = ++bp_num;
519 elem->bp.next = bp_list;
522 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
524 update_hooks(&elem->bp);
529 * Break if ident name is reached.
531 static void break_on_ident(const char *name, bp_reasons_t reason) {
532 bp_ident_t key, *elem;
534 key.bp.kind = BP_IDENT;
537 key.bp.reason = reason;
538 key.id = new_id_from_str(name);
540 elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
542 if (elem->bp.bpnr == 0) {
543 /* new break point */
544 elem->bp.bpnr = ++bp_num;
545 elem->bp.next = bp_list;
548 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
550 update_hooks(&elem->bp);
552 } /* break_on_ident */
555 * Sets/resets the active flag of breakpoint bp.
557 static void bp_activate(unsigned bp, int active)
561 for (p = bp_list; p; p = p->next) {
563 if (p->active != active) {
568 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
572 dbg_printf("Error: Firm BP %u not exists.\n", bp);
577 * Show a list of supported commands
579 static void show_commands(void) {
580 dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
581 "init break after initialization\n"
582 "create nr break if node nr was created\n"
583 "replace nr break if node nr is replaced by another node\n"
584 "lower nr break before node nr is lowered\n"
585 "remirg nr|name break if the irg of nr or entity name is deleted\n"
586 "newent nr|name break if the entity nr or name was created\n"
587 "newtype nr|name break if the type nr or name was created\n"
588 "bp show all breakpoints\n"
589 "enable nr enable breakpoint nr\n"
590 "disable nr disable breakpoint nr\n"
591 "showtype nr|name show content of the type nr or name\n"
592 "showent nr|name show content of the entity nr or name\n"
593 "setmask name msk sets the debug module name to mask msk\n"
594 "setlvl name lvl sets the debug module name to level lvl\n"
595 "setoutfile name file redirects debug output of module name to file\n"
596 "irgname name prints address and graph number of a method given by its name\n"
597 "irgldname ldname prints address and graph number of a method given by its ldname\n"
598 "help list all commands\n"
600 } /* show_commands */
603 * Shows all Firm breakpoints.
605 static void show_bp(void) {
611 dbg_printf("Firm Breakpoints:");
612 for (p = bp_list; p; p = p->next) {
614 dbg_printf("+\n BP %u: ", p->bpnr);
618 node_p = (bp_nr_t *)p;
619 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
623 ident_p = (bp_ident_t *)p;
624 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
628 dbg_printf(p->active ? "+enabled" : "+disabled");
630 dbg_printf(have_one ? "+\n" : "+ NONE\n");
634 * firm_dbg_register() expects that the name is stored persistent.
635 * So we need this little helper function
637 static firm_dbg_module_t *dbg_register(const char *name) {
638 ident *id = new_id_from_str(name);
640 return firm_dbg_register(get_id_str(id));
644 * Sets the debug mask of module name to lvl
646 static void set_dbg_level(const char *name, unsigned lvl)
648 firm_dbg_module_t *module = dbg_register(name);
650 if (firm_dbg_get_mask(module) != lvl) {
651 firm_dbg_set_mask(module, lvl);
653 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
655 } /* set_dbg_level */
658 * Redirects the debug output of module name to fname
660 static void set_dbg_outfile(const char *name, const char *fname)
662 firm_dbg_module_t *module = dbg_register(name);
663 FILE *f = fopen(fname, "w");
670 firm_dbg_set_file(module, f);
671 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
672 } /* set_dbg_outfile */
675 * Show info about a firm thing.
677 static void show_firm_object(void *firm_thing) {
680 if (firm_thing == NULL) {
681 fprintf(f, "<NULL>\n");
684 switch (get_kind(firm_thing)) {
686 fprintf(f, "BAD: (%p)\n", firm_thing);
689 dump_entity_to_file(f, firm_thing, dump_verbosity_max);
692 dump_type_to_file(f, firm_thing, dump_verbosity_max);
700 case k_ir_compound_graph_path:
706 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
708 } /* show_firm_object */
711 * Find a firm type by its number.
713 static ir_type *find_type_nr(long nr) {
714 int i, n = get_irp_n_types();
717 for (i = 0; i < n; ++i) {
718 tp = get_irp_type(i);
719 if (get_type_nr(tp) == nr)
722 tp = get_glob_type();
723 if (get_type_nr(tp) == nr)
729 * Find a firm type by its name.
731 static ir_type *find_type_name(const char *name) {
732 int i, n = get_irp_n_types();
735 for (i = 0; i < n; ++i) {
736 tp = get_irp_type(i);
737 if (strcmp(get_type_name(tp), name) == 0)
740 tp = get_glob_type();
741 if (strcmp(get_type_name(tp), name) == 0)
744 } /* find_type_name */
746 /** The environment for the entity search functions. */
747 typedef struct find_env {
749 long nr; /**< the number that is searched for */
750 const char *name; /**< the name that is searched for */
752 ir_entity *res; /**< the result */
756 * Type-walker: Find an entity with given number.
758 static void check_ent_nr(type_or_ent tore, void *ctx) {
759 find_env_t *env = ctx;
761 if (is_entity(tore.ent)) {
762 if (get_entity_nr(tore.ent) == env->u.nr) {
769 * Type-walker: Find an entity with given name.
771 static void check_ent_name(type_or_ent tore, void *ctx) {
772 find_env_t *env = ctx;
774 if (is_entity(tore.ent))
775 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
778 } /* check_ent_name */
781 * Find a firm entity by its number.
783 static ir_entity *find_entity_nr(long nr) {
788 type_walk(check_ent_nr, NULL, &env);
790 } /* find_entity_nr */
793 * Find a firm entity by its name.
795 static ir_entity *find_entity_name(const char *name) {
800 type_walk(check_ent_name, NULL, &env);
802 } /* find_entity_name */
805 * Search methods for a name.
807 static void show_by_name(type_or_ent tore, void *env) {
808 ident *id = (ident *)env;
810 if (is_entity(tore.ent)) {
811 ir_entity *ent = tore.ent;
813 if (is_method_entity(ent)) {
814 if (get_entity_ident(ent) == id) {
815 ir_type *owner = get_entity_owner(ent);
816 ir_graph *irg = get_entity_irg(ent);
818 if (owner != get_glob_type()) {
819 printf("%s::%s", get_type_name(owner), get_id_str(id));
821 printf("%s", get_id_str(id));
824 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
833 * Search methods for a ldname.
835 static void show_by_ldname(type_or_ent tore, void *env) {
836 ident *id = (ident *)env;
838 if (is_entity(tore.ent)) {
839 ir_entity *ent = tore.ent;
841 if (is_method_entity(ent)) {
842 if (get_entity_ld_ident(ent) == id) {
843 ir_type *owner = get_entity_owner(ent);
844 ir_graph *irg = get_entity_irg(ent);
846 if (owner != get_glob_type()) {
847 printf("%s::%s", get_type_name(owner), get_id_str(id));
849 printf("%s", get_id_str(id));
852 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
858 } /* show_by_ldname */
861 * prints the address and graph number of all irgs with given name
863 static void irg_name(const char *name) {
864 ident *id = new_id_from_str(name);
866 type_walk(show_by_name, NULL, (void *)id);
870 * prints the address and graph number of all irgs with given ld_name
872 static void irg_ld_name(const char *name) {
873 ident *id = new_id_from_str(name);
875 type_walk(show_by_ldname, NULL, (void *)id);
903 static const char *reserved[] = {
927 static struct lexer {
928 int has_token; /**< set if a token is cached. */
929 unsigned cur_token; /**< current token. */
930 unsigned number; /**< current token attribute. */
931 const char *s; /**< current token attribute. */
932 unsigned len; /**< current token attribute. */
934 const char *curr_pos;
936 const char *tok_start;
940 * Initialize the lexer.
942 static void init_lexer(const char *input) {
944 lexer.curr_pos = input;
945 lexer.end_pos = input + strlen(input);
950 * Get the next char from the input.
952 static char next_char(void) {
953 if (lexer.curr_pos >= lexer.end_pos)
955 return *lexer.curr_pos++;
958 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
961 #define MIN(a, b) (a) < (b) ? (a) : (b)
966 static unsigned get_token(void) {
970 /* skip white space */
973 } while (c != '\0' && isspace(c));
975 lexer.tok_start = lexer.curr_pos - 1;
976 if (c == '.' || isalpha(c)) {
977 /* command begins here */
979 const char* tok_start;
984 } while (isgraph(c));
987 tok_start = lexer.tok_start;
988 if (*tok_start == '.') {
992 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
993 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
998 lexer.s = lexer.tok_start;
999 lexer.len = lexer.curr_pos - lexer.s;
1000 return tok_identifier;
1001 } else if (isdigit(c) || c == '-') {
1002 unsigned number = 0;
1005 /* we support negative numbers as well, so one can easily set all bits with -1 */
1014 if (c == 'x' || c == 'X') {
1021 number = (number << 4) | (c - '0');
1023 number = (number << 4) | (toupper(c) - 'A' + 10);
1026 lexer.number = number;
1033 number = number * 10 + (c - '0');
1037 lexer.number = sign ? 0 - number : number;
1046 * High level function to use from debugger interface
1048 * See show_commands() for supported commands.
1050 void firm_debug(const char *cmd) {
1051 char name[1024], fname[1024];
1059 token = get_token();
1066 token = get_token();
1067 if (token != tok_number)
1069 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1073 token = get_token();
1074 if (token != tok_number)
1076 break_on_nr(lexer.number, BP_ON_REPLACE);
1080 token = get_token();
1081 if (token != tok_number)
1083 break_on_nr(lexer.number, BP_ON_LOWER);
1087 token = get_token();
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);
1095 break_on_ident(name, BP_ON_REMIRG);
1101 token = get_token();
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);
1109 break_on_ident(name, BP_ON_NEW_ENT);
1115 token = get_token();
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);
1123 break_on_ident(name, BP_ON_NEW_TYPE);
1129 token = get_token();
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);
1137 show_firm_object(find_type_name(name));
1143 token = get_token();
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);
1151 show_firm_object(find_entity_name(name));
1165 token = get_token();
1166 if (token != tok_number)
1168 bp_activate(lexer.number, 1);
1172 token = get_token();
1173 if (token != tok_number)
1175 bp_activate(lexer.number, 0);
1179 token = get_token();
1180 if (token != tok_identifier)
1182 len = MIN(lexer.len, 1023);
1183 strncpy(name, lexer.s, len);
1186 token = get_token();
1187 if (token != tok_number)
1189 set_dbg_level(name, lexer.number);
1193 token = get_token();
1194 if (token != tok_identifier)
1196 len = MIN(lexer.len, 1023);
1197 strncpy(name, lexer.s, len);
1200 token = get_token();
1201 if (token != tok_number)
1203 set_dbg_level(name, (1 << lexer.number) - 1);
1206 case tok_setoutfile:
1207 token = get_token();
1208 if (token != tok_identifier)
1210 len = MIN(lexer.len, 1023);
1211 strncpy(name, lexer.s, len);
1214 token = get_token();
1215 if (token != tok_identifier)
1217 len = MIN(lexer.len, 1023);
1218 strncpy(fname, lexer.s, len);
1220 set_dbg_outfile(name, fname);
1223 token = get_token();
1224 if (token != tok_identifier)
1226 len = MIN(lexer.len, 1023);
1227 strncpy(name, lexer.s, len);
1232 token = get_token();
1233 if (token != tok_identifier)
1235 len = MIN(lexer.len, 1023);
1236 strncpy(name, lexer.s, len);
1248 printf("Error: before %s\n", lexer.tok_start);
1253 token = get_token();
1254 if (token == tok_eof)
1263 /* creates the debugger tables */
1264 void firm_init_debugger(void)
1268 bp_numbers = new_set(cmp_nr_bp, 8);
1269 bp_idents = new_set(cmp_ident_bp, 8);
1271 env = getenv("FIRMDBG");
1280 } /* firm_init_debugger */
1283 * A gdb helper function to print firm objects.
1285 const char *gdb_node_helper(void *firm_object) {
1286 static char buf[1024];
1287 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1292 * A gdb helper function to print tarvals.
1294 const char *gdb_tarval_helper(void *tv_object) {
1295 static char buf[1024];
1296 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1300 const char *gdb_out_edge_helper(const ir_node *node) {
1301 static char buf[4*1024];
1304 size_t len = sizeof(buf);
1305 const ir_edge_t *edge;
1306 foreach_out_edge(node, edge) {
1307 ir_node *n = get_edge_src_irn(edge);
1309 ir_snprintf(b, len, "%+F ", n);
1320 /* some picky compiler do not allow empty files */
1321 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1326 * @page debugger The Firm debugger extension
1328 * Firm contains a debugger extension. This allows to set debugger breakpoints
1329 * an various events.
1330 * The extension uses a text interface which can be accessed from most debuggers.
1331 * More than one command can be given separated by ';'.
1333 * @section sec_cmd Supported commands
1335 * Historically all debugger commands start with a dot. This isn't needed in newer
1336 * versions, but still supported, ie the commands ".init" and "init" are equal.
1337 * The following commands are currently supported:
1341 * Break immediately after the debugger extension was initialized.
1342 * Typically this command is used in the environment to stop the execution
1343 * of a Firm compiler right after the initialization, like this:
1345 * $export FIRMDBG=".init"
1349 * Break if a new IR-node with node number nr was created.
1350 * Typically used to find the place where wrong nodes are created.
1354 * Break before IR-node with node number nr is replaced by another node.
1358 * Break before IR-node with node number nr is lowered.
1362 * Break if the irg with graph number nr is deleted.
1366 * Break if the irg of entity name is deleted.
1370 * Break if the entity with number nr was created.
1374 * Break if the entity name was created.
1378 * Break if the type with number nr was created.
1382 * Break if the type name was created.
1386 * Show all Firm internal breakpoints.
1390 * Enables breakpoint nr.
1394 * Disables breakpoint nr.
1398 * Show the content of entity nr.
1402 * Show the content of entity name.
1406 * Show the content of type nr.
1410 * Show the content of type name.
1412 * @b setmask name msk
1414 * Sets the debug module name to mask msk.
1416 * @b setlvl name lvl
1418 * Sets the debug module name to level lvl.
1420 * @b setoutfile name file
1422 * Redirects debug output of module name to file.
1426 * Prints address and graph number of a method given by its name.
1430 * Prints address and graph number of a method given by its linker name.
1434 * List all commands.
1437 * The Firm debugger extension can be accessed using the function firm_debug().
1438 * The following example shows how to set a creation breakpoint in GDB when
1439 * node 2101 is created.
1441 * -# set FIRMDBG="init"
1442 * -# start gdb with your compiler
1443 * -# after gdb breaks, issue
1445 * call firm_debug("create 2101")
1447 * On the console the following text should be issued:
1449 * Firm BP 1: creation of Node 2101
1452 * @section gdb_macro GDB macro
1454 * Add the following to your .gdbinit file:
1457 # define firm "cmd" Firm debugger extension
1460 call firm_debug($arg0)
1464 * Then, all Firm debugger extension commands can be accessed in the gdb
1465 * console using the firm prefix, eg.:
1467 * firm "create 2101"