2 * Copyright (C) 1995-2010 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
31 #define WIN32_LEAN_AND_MEAN
48 #include "irgraph_t.h"
52 #include "iredges_t.h"
57 /* Break into the debugger. The Win32 way. */
58 void firm_debug_break(void)
62 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
63 /* Break into the debugger. The ia32/x86_64 way under GCC. */
64 void firm_debug_break(void)
66 __asm__ __volatile__("int3");
69 /* Break into the debugger. Poor Unix way. */
70 void firm_debug_break(void)
76 /** supported breakpoint kinds */
78 BP_NR = 'n', /**< break on node number. */
79 BP_IDENT = 'i' /**< break on ident. */
83 * Reasons for node number breakpoints.
85 typedef enum bp_reasons_t {
86 BP_ON_NEW_NODE, /**< break if node with number is created */
87 BP_ON_REPLACE, /**< break if node with number is replaced */
88 BP_ON_LOWER, /**< break if node with number is lowered */
89 BP_ON_REMIRG, /**< break if an IRG is removed */
90 BP_ON_NEW_ENT, /**< break if a new entity is created */
91 BP_ON_NEW_TYPE, /**< break if a new type is created */
96 typedef struct breakpoint {
97 bp_kind kind; /**< the kind of this break point */
98 unsigned bpnr; /**< break point number */
99 int active; /**< non-zero, if this break point is active */
100 bp_reasons_t reason; /**< reason for the breakpoint */
101 struct breakpoint *next; /**< link to the next one */
104 /** A number breakpoint. */
106 breakpoint bp; /**< the breakpoint data */
107 long nr; /**< the node number */
110 /** Calculate the hash value for a node breakpoint. */
111 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
113 /** An ident breakpoint. */
115 breakpoint bp; /**< the breakpoint data */
116 ident *id; /**< the ident */
119 /** Calculate the hash value for an ident breakpoint. */
120 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
122 /** The set containing the breakpoints on node numbers. */
123 static set *bp_numbers;
125 /** The set containing the breakpoints on idents. */
126 static set *bp_idents;
128 /**< the list of all breakpoints */
129 static breakpoint *bp_list;
131 /** number of the current break point */
132 static unsigned bp_num = 0;
134 /** set if break on init command was issued. */
135 static int break_on_init = 0;
137 /** the hook entries for the Firm debugger module. */
138 static hook_entry_t debugger_hooks[hook_last];
140 /** number of active breakpoints to maintain hooks. */
141 static unsigned num_active_bp[BP_MAX_REASON];
144 * The debug message buffer
146 static char firm_dbg_msg_buf[2048];
149 * If set, the debug extension writes all output to the
150 * firm_dbg_msg_buf buffer
152 static int redir_output = 0;
155 * Is set to one, if the debug extension is active
157 static int is_active = 0;
159 /** hook the hook h with function fkt. */
160 #define HOOK(h, fkt) \
162 debugger_hooks[h].hook._##h = fkt; \
163 register_hook(h, &debugger_hooks[h]); \
166 /** unhook the hook h */
169 unregister_hook(h, &debugger_hooks[h]); \
170 debugger_hooks[h].hook._##h = NULL; \
173 /** returns non-zero if a entry hook h is used */
174 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
176 /* some macros needed to create the info string */
177 #define _DBG_VERSION(major, minor) #major "." #minor
178 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
179 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
181 /* the API version: change if needed */
182 #define FIRM_DBG_MAJOR 1
183 #define FIRM_DBG_MINOR 0
185 /** for automatic detection of the debug extension */
186 static const char __attribute__((used)) firm_debug_info_string[] =
187 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
189 int firm_debug_active(void)
192 } /* firm_debug_active */
195 * Reset the debug text buffer.
197 static void reset_dbg_buf(void)
199 firm_dbg_msg_buf[0] = '\0';
200 } /* reset_dbg_buf */
202 static void add_to_dbg_buf(const char *buf)
204 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
205 } /* add_to_dbg_buf */
207 const char *firm_debug_text(void)
209 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
210 return firm_dbg_msg_buf;
211 } /* firm_debug_text */
216 static void dbg_printf(const char *fmt, ...)
228 ir_vsnprintf(buf, sizeof(buf), fmt, args);
238 * A new node is created.
240 * @param ctx the hook context
241 * @param irg the IR graph on which the node is created
242 * @param node the new IR node that was created
244 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
250 key.nr = get_irn_node_nr(node);
251 key.bp.reason = BP_ON_NEW_NODE;
253 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
254 if (elem && elem->bp.active) {
255 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
261 * A node is replaced.
263 * @param ctx the hook context
264 * @param old the IR node the is replaced
265 * @param nw the new IR node that will replace old
267 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
272 key.nr = get_irn_node_nr(old);
273 key.bp.reason = BP_ON_REPLACE;
275 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
276 if (elem && elem->bp.active) {
277 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
283 * A new node is lowered.
285 * @param ctx the hook context
286 * @param node the new IR node that will be lowered
288 static void dbg_lower(void *ctx, ir_node *node)
293 key.nr = get_irn_node_nr(node);
294 key.bp.reason = BP_ON_LOWER;
296 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
297 if (elem && elem->bp.active) {
298 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
304 * A graph will be deleted.
306 * @param ctx the hook context
307 * @param irg the IR graph that will be deleted
309 static void dbg_free_graph(void *ctx, ir_graph *irg)
314 key.nr = get_irg_graph_nr(irg);
315 key.bp.reason = BP_ON_REMIRG;
317 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
318 if (elem && elem->bp.active) {
319 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
324 bp_ident_t key, *elem;
325 ir_entity *ent = get_irg_entity(irg);
330 key.id = get_entity_ident(ent);
331 key.bp.reason = BP_ON_REMIRG;
333 elem = (bp_ident_t*)set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
334 if (elem && elem->bp.active) {
335 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
339 } /* dbg_free_graph */
342 * An entity was created.
344 * @param ctx the hook context
345 * @param ent the newly created entity
347 static void dbg_new_entity(void *ctx, ir_entity *ent)
351 bp_ident_t key, *elem;
353 key.id = get_entity_ident(ent);
354 key.bp.reason = BP_ON_NEW_ENT;
356 elem = (bp_ident_t*)set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
357 if (elem && elem->bp.active) {
358 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
365 key.nr = get_entity_nr(ent);
366 key.bp.reason = BP_ON_NEW_ENT;
368 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
369 if (elem && elem->bp.active) {
370 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
374 } /* dbg_new_entity */
377 * A type was created.
379 * @param ctx the hook context
380 * @param tp the newly created type
382 static void dbg_new_type(void *ctx, ir_type *tp)
388 key.nr = get_type_nr(tp);
389 key.bp.reason = BP_ON_NEW_TYPE;
391 elem = (bp_nr_t*)set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
392 if (elem && elem->bp.active) {
393 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
400 * Return the reason string.
402 static const char *reason_str(bp_reasons_t reason)
405 case BP_ON_NEW_NODE: return "node creation";
406 case BP_ON_REPLACE: return "node replace";
407 case BP_ON_LOWER: return "node lowering";
408 case BP_ON_REMIRG: return "removing IRG";
409 case BP_ON_NEW_ENT: return "entity creation";
410 case BP_ON_NEW_TYPE: return "type creation";
411 case BP_MAX_REASON: break;
413 panic("unsupported reason");
417 * Compare two number breakpoints.
419 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
421 const bp_nr_t *e1 = (const bp_nr_t*)elt;
422 const bp_nr_t *e2 = (const bp_nr_t*)key;
425 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
429 * Compare two ident breakpoints.
431 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
433 const bp_ident_t *e1 = (const bp_ident_t*)elt;
434 const bp_ident_t *e2 = (const bp_ident_t*)key;
437 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
443 static void update_hooks(breakpoint *bp)
445 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
446 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
449 ++num_active_bp[bp->reason];
451 --num_active_bp[bp->reason];
453 if (num_active_bp[bp->reason] > 0) {
454 /* register the hooks on demand */
455 switch (bp->reason) {
456 CASE_ON(BP_ON_NEW_NODE, new_node);
457 CASE_ON(BP_ON_REPLACE, replace);
458 CASE_ON(BP_ON_LOWER, lower);
459 CASE_ON(BP_ON_REMIRG, free_graph);
460 CASE_ON(BP_ON_NEW_ENT, new_entity);
461 CASE_ON(BP_ON_NEW_TYPE, new_type);
467 /* unregister the hook on demand */
468 switch (bp->reason) {
469 CASE_OFF(BP_ON_NEW_NODE, new_node);
470 CASE_OFF(BP_ON_REPLACE, replace);
471 CASE_OFF(BP_ON_LOWER, lower);
472 CASE_OFF(BP_ON_REMIRG, free_graph);
473 CASE_OFF(BP_ON_NEW_ENT, new_entity);
474 CASE_OFF(BP_ON_NEW_TYPE, new_type);
484 * Break if nr is reached.
486 static void break_on_nr(long nr, bp_reasons_t reason)
493 key.bp.reason = reason;
496 elem = (bp_nr_t*)set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
498 if (elem->bp.bpnr == 0) {
499 /* new break point */
500 elem->bp.bpnr = ++bp_num;
501 elem->bp.next = bp_list;
504 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
506 update_hooks(&elem->bp);
511 * Break if ident name is reached.
513 static void break_on_ident(const char *name, bp_reasons_t reason)
515 bp_ident_t key, *elem;
517 key.bp.kind = BP_IDENT;
520 key.bp.reason = reason;
521 key.id = new_id_from_str(name);
523 elem = (bp_ident_t*)set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
525 if (elem->bp.bpnr == 0) {
526 /* new break point */
527 elem->bp.bpnr = ++bp_num;
528 elem->bp.next = bp_list;
531 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
533 update_hooks(&elem->bp);
535 } /* break_on_ident */
538 * Sets/resets the active flag of breakpoint bp.
540 static void bp_activate(unsigned bp, int active)
544 for (p = bp_list; p; p = p->next) {
546 if (p->active != active) {
551 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
555 dbg_printf("Error: Firm BP %u not exists.\n", bp);
560 * Show a list of supported commands
562 static void show_commands(void)
564 dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
565 "init break after initialization\n"
566 "create nr break if node nr was created\n"
567 "replace nr break if node nr is replaced by another node\n"
568 "lower nr break before node nr is lowered\n"
569 "remirg nr|name break if the irg of nr or entity name is deleted\n"
570 "newent nr|name break if the entity nr or name was created\n"
571 "newtype nr|name break if the type nr or name was created\n"
572 "bp show all breakpoints\n"
573 "enable nr enable breakpoint nr\n"
574 "disable nr disable breakpoint nr\n"
575 "showtype nr|name show content of the type nr or name\n"
576 "showent nr|name show content of the entity nr or name\n"
577 "setmask name msk sets the debug module name to mask msk\n"
578 "setlvl name lvl sets the debug module name to level lvl\n"
579 "setoutfile name file redirects debug output of module name to file\n"
580 "irgname name prints address and graph number of a method given by its name\n"
581 "irgldname ldname prints address and graph number of a method given by its ldname\n"
582 "help list all commands\n"
584 } /* show_commands */
587 * Shows all Firm breakpoints.
589 static void show_bp(void)
596 dbg_printf("Firm Breakpoints:");
597 for (p = bp_list; p; p = p->next) {
599 dbg_printf("+\n BP %u: ", p->bpnr);
603 node_p = (bp_nr_t *)p;
604 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
608 ident_p = (bp_ident_t *)p;
609 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
613 dbg_printf(p->active ? "+enabled" : "+disabled");
615 dbg_printf(have_one ? "+\n" : "+ NONE\n");
619 * firm_dbg_register() expects that the name is stored persistent.
620 * So we need this little helper function
622 static firm_dbg_module_t *dbg_register(const char *name)
624 ident *id = new_id_from_str(name);
626 return firm_dbg_register(get_id_str(id));
630 * Sets the debug mask of module name to lvl
632 static void set_dbg_level(const char *name, unsigned lvl)
634 firm_dbg_module_t *module = dbg_register(name);
636 if (firm_dbg_get_mask(module) != lvl) {
637 firm_dbg_set_mask(module, lvl);
639 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
641 } /* set_dbg_level */
644 * Redirects the debug output of module name to fname
646 static void set_dbg_outfile(const char *name, const char *fname)
648 firm_dbg_module_t *module = dbg_register(name);
649 FILE *f = fopen(fname, "w");
656 firm_dbg_set_file(module, f);
657 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
658 } /* set_dbg_outfile */
661 * Show info about a firm thing.
663 static void show_firm_object(void *firm_thing)
667 if (firm_thing == NULL) {
668 fprintf(f, "<NULL>\n");
671 switch (get_kind(firm_thing)) {
673 fprintf(f, "BAD: (%p)\n", firm_thing);
676 dump_entity_to_file(f, (ir_entity*)firm_thing);
679 dump_type_to_file(f, (ir_type*)firm_thing);
687 case k_ir_compound_graph_path:
693 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
695 } /* show_firm_object */
698 * Find a firm type by its number.
700 static ir_type *find_type_nr(long nr)
702 int i, n = get_irp_n_types();
705 for (i = 0; i < n; ++i) {
706 tp = get_irp_type(i);
707 if (get_type_nr(tp) == nr)
710 tp = get_glob_type();
711 if (get_type_nr(tp) == nr)
717 * Find a firm type by its name.
719 static ir_type *find_type_name(const char *name)
721 int i, n = get_irp_n_types();
724 for (i = 0; i < n; ++i) {
725 tp = get_irp_type(i);
726 if (!is_compound_type(tp))
729 if (strcmp(get_compound_name(tp), name) == 0)
732 tp = get_glob_type();
733 if (strcmp(get_compound_name(tp), name) == 0)
736 } /* find_type_name */
738 /** The environment for the entity search functions. */
739 typedef struct find_env {
741 long nr; /**< the number that is searched for */
742 const char *name; /**< the name that is searched for */
744 ir_entity *res; /**< the result */
748 * Type-walker: Find an entity with given number.
750 static void check_ent_nr(type_or_ent tore, void *ctx)
752 find_env_t *env = (find_env_t*)ctx;
754 if (is_entity(tore.ent)) {
755 if (get_entity_nr(tore.ent) == env->u.nr) {
762 * Type-walker: Find an entity with given name.
764 static void check_ent_name(type_or_ent tore, void *ctx)
766 find_env_t *env = (find_env_t*)ctx;
768 if (is_entity(tore.ent))
769 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
772 } /* check_ent_name */
775 * Find a firm entity by its number.
777 static ir_entity *find_entity_nr(long nr)
783 type_walk(check_ent_nr, NULL, &env);
785 } /* find_entity_nr */
788 * Find a firm entity by its name.
790 static ir_entity *find_entity_name(const char *name)
796 type_walk(check_ent_name, NULL, &env);
798 } /* find_entity_name */
801 * Search methods for a name.
803 static void show_by_name(type_or_ent tore, void *env)
805 ident *id = (ident *)env;
807 if (is_entity(tore.ent)) {
808 ir_entity *ent = tore.ent;
810 if (is_method_entity(ent)) {
811 if (get_entity_ident(ent) == id) {
812 ir_type *owner = get_entity_owner(ent);
813 ir_graph *irg = get_entity_irg(ent);
815 if (owner != get_glob_type()) {
816 printf("%s::%s", get_compound_name(owner), get_id_str(id));
818 printf("%s", get_id_str(id));
821 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
830 * Search methods for a ldname.
832 static void show_by_ldname(type_or_ent tore, void *env)
834 ident *id = (ident *)env;
836 if (is_entity(tore.ent)) {
837 ir_entity *ent = tore.ent;
839 if (is_method_entity(ent)) {
840 if (get_entity_ld_ident(ent) == id) {
841 ir_type *owner = get_entity_owner(ent);
842 ir_graph *irg = get_entity_irg(ent);
844 if (owner != get_glob_type()) {
845 printf("%s::%s", get_compound_name(owner), get_id_str(id));
847 printf("%s", get_id_str(id));
850 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
856 } /* show_by_ldname */
859 * prints the address and graph number of all irgs with given name
861 static void irg_name(const char *name)
863 ident *id = new_id_from_str(name);
865 type_walk(show_by_name, NULL, (void *)id);
869 * prints the address and graph number of all irgs with given ld_name
871 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 size_t 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)
945 lexer.curr_pos = input;
946 lexer.end_pos = input + strlen(input);
951 * Get the next char from the input.
953 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)
973 /* skip white space */
976 } while (c != '\0' && isspace((unsigned char)c));
978 lexer.tok_start = lexer.curr_pos - 1;
979 if (c == '.' || isalpha((unsigned char)c)) {
980 /* command begins here */
982 const char* tok_start;
987 } while (isgraph((unsigned char)c));
990 tok_start = lexer.tok_start;
991 if (*tok_start == '.') {
995 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
996 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
1001 lexer.s = lexer.tok_start;
1002 lexer.len = lexer.curr_pos - lexer.s;
1003 return tok_identifier;
1004 } else if (isdigit((unsigned char)c) || c == '-') {
1005 unsigned number = 0;
1008 /* we support negative numbers as well, so one can easily set all bits with -1 */
1017 if (c == 'x' || c == 'X') {
1021 if (! isxdigit((unsigned char)c))
1023 if (isdigit((unsigned char)c))
1024 number = (number << 4) | (c - '0');
1026 number = (number << 4) | (toupper((unsigned char)c) - 'A' + 10);
1029 lexer.number = number;
1034 if (! isdigit((unsigned char)c))
1036 number = number * 10 + (c - '0');
1040 lexer.number = sign ? 0 - number : number;
1048 void firm_debug(const char *cmd)
1050 char name[1024], fname[1024];
1058 token = get_token();
1065 token = get_token();
1066 if (token != tok_number)
1068 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1072 token = get_token();
1073 if (token != tok_number)
1075 break_on_nr(lexer.number, BP_ON_REPLACE);
1079 token = get_token();
1080 if (token != tok_number)
1082 break_on_nr(lexer.number, BP_ON_LOWER);
1086 token = get_token();
1088 if (token == tok_number)
1089 break_on_nr(lexer.number, BP_ON_REMIRG);
1090 else if (token == tok_identifier) {
1091 len = MIN(lexer.len, 1023);
1092 strncpy(name, lexer.s, len);
1094 break_on_ident(name, BP_ON_REMIRG);
1100 token = get_token();
1102 if (token == tok_number)
1103 break_on_nr(lexer.number, BP_ON_NEW_ENT);
1104 else if (token == tok_identifier) {
1105 len = MIN(lexer.len, 1023);
1106 strncpy(name, lexer.s, len);
1108 break_on_ident(name, BP_ON_NEW_ENT);
1114 token = get_token();
1116 if (token == tok_number)
1117 break_on_nr(lexer.number, BP_ON_NEW_TYPE);
1118 else if (token == tok_identifier) {
1119 len = MIN(lexer.len, 1023);
1120 strncpy(name, lexer.s, len);
1122 break_on_ident(name, BP_ON_NEW_TYPE);
1128 token = get_token();
1130 if (token == tok_number)
1131 show_firm_object(find_type_nr(lexer.number));
1132 else if (token == tok_identifier) {
1133 len = MIN(lexer.len, 1023);
1134 strncpy(name, lexer.s, len);
1136 show_firm_object(find_type_name(name));
1142 token = get_token();
1144 if (token == tok_number)
1145 show_firm_object(find_entity_nr(lexer.number));
1146 else if (token == tok_identifier) {
1147 len = MIN(lexer.len, 1023);
1148 strncpy(name, lexer.s, len);
1150 show_firm_object(find_entity_name(name));
1164 token = get_token();
1165 if (token != tok_number)
1167 bp_activate(lexer.number, 1);
1171 token = get_token();
1172 if (token != tok_number)
1174 bp_activate(lexer.number, 0);
1178 token = get_token();
1179 if (token != tok_identifier)
1181 len = MIN(lexer.len, 1023);
1182 strncpy(name, lexer.s, len);
1185 token = get_token();
1186 if (token != tok_number)
1188 set_dbg_level(name, lexer.number);
1192 token = get_token();
1193 if (token != tok_identifier)
1195 len = MIN(lexer.len, 1023);
1196 strncpy(name, lexer.s, len);
1199 token = get_token();
1200 if (token != tok_number)
1202 set_dbg_level(name, (1 << lexer.number) - 1);
1205 case tok_setoutfile:
1206 token = get_token();
1207 if (token != tok_identifier)
1209 len = MIN(lexer.len, 1023);
1210 strncpy(name, lexer.s, len);
1213 token = get_token();
1214 if (token != tok_identifier)
1216 len = MIN(lexer.len, 1023);
1217 strncpy(fname, lexer.s, len);
1219 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);
1233 token = get_token();
1234 if (token != tok_identifier)
1236 len = MIN(lexer.len, 1023);
1237 strncpy(name, lexer.s, len);
1249 printf("Error: before %s\n", lexer.tok_start);
1254 token = get_token();
1255 if (token == tok_eof)
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)
1287 static char buf[1024];
1288 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1292 const char *gdb_tarval_helper(void *tv_object)
1294 static char buf[1024];
1295 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1299 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"