2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Helper function for integrated debug support
23 * @author Michael Beck
34 #define WIN32_LEAN_AND_MEAN
37 #define strncasecmp strnicmp
59 #include "irgraph_t.h"
66 /* Break into the debugger. The Win32 way. */
67 void firm_debug_break(void) {
70 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
71 /* Break into the debugger. The ia32/x86_64 way under GCC. */
72 void firm_debug_break(void) {
73 __asm__ __volatile__("int3");
76 /* Break into the debugger. Poor Unix way. */
77 void firm_debug_break(void) {
82 /** supported breakpoint kinds */
84 BP_NR = 'n', /**< break on node number. */
85 BP_IDENT = 'i' /**< break on ident. */
89 * Reasons for node number breakpoints.
91 typedef enum _bp_reasons_t {
92 BP_ON_NEW_NODE, /**< break if node with number is created */
93 BP_ON_REPLACE, /**< break if node with number is replaced */
94 BP_ON_LOWER, /**< break if node with number is lowered */
95 BP_ON_REMIRG, /**< break if an IRG is removed */
96 BP_ON_NEW_ENT, /**< break if a new entity is created */
97 BP_ON_NEW_TYPE, /**< break if a new type is created */
102 typedef struct _breakpoint {
103 bp_kind kind; /**< the kind of this break point */
104 unsigned bpnr; /**< break point number */
105 int active; /**< non-zero, if this break point is active */
106 bp_reasons_t reason; /**< reason for the breakpoint */
107 struct _breakpoint *next; /**< link to the next one */
110 /** A number breakpoint. */
112 breakpoint bp; /**< the breakpoint data */
113 long nr; /**< the node number */
116 /** Calculate the hash value for a node breakpoint. */
117 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
119 /** An ident breakpoint. */
121 breakpoint bp; /**< the breakpoint data */
122 ident *id; /**< the ident */
125 /** Calculate the hash value for an ident breakpoint. */
126 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
128 /** The set containing the breakpoints on node numbers. */
129 static set *bp_numbers;
131 /** The set containing the breakpoints on idents. */
132 static set *bp_idents;
134 /**< the list of all breakpoints */
135 static breakpoint *bp_list;
137 /** number of the current break point */
138 static unsigned bp_num = 0;
140 /** set if break on init command was issued. */
141 static int break_on_init = 0;
143 /** the hook entries for the Firm debugger module. */
144 static hook_entry_t debugger_hooks[hook_last];
146 /** number of active breakpoints to maintain hooks. */
147 static unsigned num_active_bp[BP_MAX_REASON];
150 * The debug message buffer
152 static char firm_dbg_msg_buf[2048];
155 * If set, the debug extension writes all output to the
156 * firm_dbg_msg_buf buffer
158 static int redir_output = 0;
161 * Is set to one, if the debug extension is active
163 static int is_active = 0;
165 /** hook the hook h with function fkt. */
166 #define HOOK(h, fkt) \
168 debugger_hooks[h].hook._##h = fkt; \
169 register_hook(h, &debugger_hooks[h]); \
172 /** unhook the hook h */
175 unregister_hook(h, &debugger_hooks[h]); \
176 debugger_hooks[h].hook._##h = NULL; \
179 /** returns non-zero if a entry hook h is used */
180 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
182 /* some macros needed to create the info string */
183 #define _DBG_VERSION(major, minor) #major "." #minor
184 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
185 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
187 /* the API version: change if needed */
188 #define FIRM_DBG_MAJOR 1
189 #define FIRM_DBG_MINOR 0
191 /** for automatic detection of the debug extension */
192 static const char firm_debug_info_string[] =
193 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
196 * Returns non-zero, if the debug extension is active
198 int firm_debug_active(void) {
200 } /* firm_debug_active */
203 * Reset the debug text buffer.
205 static void reset_dbg_buf(void) {
206 firm_dbg_msg_buf[0] = '\0';
207 } /* reset_dbg_buf */
210 * Add text to the debug text buffer.
212 static void add_to_dbg_buf(const char *buf) {
213 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
214 } /* add_to_dbg_buf */
217 * Return the content of the debug text buffer.
219 * To be called from the debugger.
221 const char *firm_debug_text(void) {
222 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
223 return firm_dbg_msg_buf;
224 } /* firm_debug_text */
229 static void dbg_printf(const char *fmt, ...)
241 ir_vsnprintf(buf, sizeof(buf), fmt, args);
251 * A new node is created.
253 * @param ctx the hook context
254 * @param irg the IR graph on which the node is created
255 * @param node the new IR node that was created
257 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
263 key.nr = get_irn_node_nr(node);
264 key.bp.reason = BP_ON_NEW_NODE;
266 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
267 if (elem && elem->bp.active) {
268 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
274 * A node is replaced.
276 * @param ctx the hook context
277 * @param old the IR node the is replaced
278 * @param nw the new IR node that will replace old
280 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
285 key.nr = get_irn_node_nr(old);
286 key.bp.reason = BP_ON_REPLACE;
288 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
289 if (elem && elem->bp.active) {
290 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
296 * A new node is lowered.
298 * @param ctx the hook context
299 * @param node the new IR node that will be lowered
301 static void dbg_lower(void *ctx, ir_node *node)
306 key.nr = get_irn_node_nr(node);
307 key.bp.reason = BP_ON_LOWER;
309 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
310 if (elem && elem->bp.active) {
311 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
317 * A graph will be deleted.
319 * @param ctx the hook context
320 * @param irg the IR graph that will be deleted
322 static void dbg_free_graph(void *ctx, ir_graph *irg)
327 key.nr = get_irg_graph_nr(irg);
328 key.bp.reason = BP_ON_REMIRG;
330 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
331 if (elem && elem->bp.active) {
332 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
337 bp_ident_t key, *elem;
338 ir_entity *ent = get_irg_entity(irg);
343 key.id = get_entity_ident(ent);
344 key.bp.reason = BP_ON_REMIRG;
346 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
347 if (elem && elem->bp.active) {
348 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
352 } /* dbg_free_graph */
355 * An entity was created.
357 * @param ctx the hook context
358 * @param ent the newly created entity
360 static void dbg_new_entity(void *ctx, ir_entity *ent)
364 bp_ident_t key, *elem;
366 key.id = get_entity_ident(ent);
367 key.bp.reason = BP_ON_NEW_ENT;
369 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
370 if (elem && elem->bp.active) {
371 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
378 key.nr = get_entity_nr(ent);
379 key.bp.reason = BP_ON_NEW_ENT;
381 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
382 if (elem && elem->bp.active) {
383 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
387 } /* dbg_new_entity */
390 * A type was created.
392 * @param ctx the hook context
393 * @param tp the newly created type
395 static void dbg_new_type(void *ctx, ir_type *tp)
401 key.nr = get_type_nr(tp);
402 key.bp.reason = BP_ON_NEW_TYPE;
404 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
405 if (elem && elem->bp.active) {
406 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
411 bp_ident_t key, *elem;
413 key.id = get_type_ident(tp);
414 key.bp.reason = BP_ON_NEW_TYPE;
416 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
417 if (elem && elem->bp.active) {
418 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
425 * Return the reason string.
427 static const char *reason_str(bp_reasons_t reason)
430 case BP_ON_NEW_NODE: return "node creation";
431 case BP_ON_REPLACE: return "node replace";
432 case BP_ON_LOWER: return "node lowering";
433 case BP_ON_REMIRG: return "removing IRG";
434 case BP_ON_NEW_ENT: return "entity creation";
435 case BP_ON_NEW_TYPE: return "type creation";
442 * Compare two number breakpoints.
444 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
446 const bp_nr_t *e1 = elt;
447 const bp_nr_t *e2 = key;
450 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
454 * Compare two ident breakpoints.
456 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
458 const bp_ident_t *e1 = elt;
459 const bp_ident_t *e2 = key;
462 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
468 static void update_hooks(breakpoint *bp)
470 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
471 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
474 ++num_active_bp[bp->reason];
476 --num_active_bp[bp->reason];
478 if (num_active_bp[bp->reason] > 0) {
479 /* register the hooks on demand */
480 switch (bp->reason) {
481 CASE_ON(BP_ON_NEW_NODE, new_node);
482 CASE_ON(BP_ON_REPLACE, replace);
483 CASE_ON(BP_ON_LOWER, lower);
484 CASE_ON(BP_ON_REMIRG, free_graph);
485 CASE_ON(BP_ON_NEW_ENT, new_entity);
486 CASE_ON(BP_ON_NEW_TYPE, new_type);
492 /* unregister the hook on demand */
493 switch (bp->reason) {
494 CASE_OFF(BP_ON_NEW_NODE, new_node);
495 CASE_OFF(BP_ON_REPLACE, replace);
496 CASE_OFF(BP_ON_LOWER, lower);
497 CASE_OFF(BP_ON_REMIRG, free_graph);
498 CASE_OFF(BP_ON_NEW_ENT, new_entity);
499 CASE_OFF(BP_ON_NEW_TYPE, new_type);
509 * Break if nr is reached.
511 static void break_on_nr(long nr, bp_reasons_t reason)
518 key.bp.reason = reason;
521 elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
523 if (elem->bp.bpnr == 0) {
524 /* new break point */
525 elem->bp.bpnr = ++bp_num;
526 elem->bp.next = bp_list;
529 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
531 update_hooks(&elem->bp);
536 * Break if ident name is reached.
538 static void break_on_ident(const char *name, bp_reasons_t reason) {
539 bp_ident_t key, *elem;
541 key.bp.kind = BP_IDENT;
544 key.bp.reason = reason;
545 key.id = new_id_from_str(name);
547 elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
549 if (elem->bp.bpnr == 0) {
550 /* new break point */
551 elem->bp.bpnr = ++bp_num;
552 elem->bp.next = bp_list;
555 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
557 update_hooks(&elem->bp);
559 } /* break_on_ident */
562 * Sets/resets the active flag of breakpoint bp.
564 static void bp_activate(unsigned bp, int active)
568 for (p = bp_list; p; p = p->next) {
570 if (p->active != active) {
575 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
579 dbg_printf("Error: Firm BP %u not exists.\n", bp);
584 * Show a list of supported commands
586 static void show_commands(void) {
587 dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
588 ".init break after initialization\n"
589 ".create nr break if node nr was created\n"
590 ".replace nr break if node nr is replaced by another node\n"
591 ".lower nr break before node nr is lowered\n"
592 ".remirg nr|name break if the irg of nr or entity name is deleted\n"
593 ".newent nr|name break if the entity nr or name was created\n"
594 ".newtype nr|name break if the type nr or name was created\n"
595 ".bp show all breakpoints\n"
596 ".enable nr enable breakpoint nr\n"
597 ".disable nr disable breakpoint nr\n"
598 ".showtype nr|name show content of the type nr or name\n"
599 ".showent nr|name show content of the entity nr or name\n"
600 ".setmask name msk sets the debug module name to mask msk\n"
601 ".setlvl name lvl sets the debug module name to level lvl\n"
602 ".setoutfile name file redirects debug output of module name to file\n"
603 ".irgname name prints address and graph number of a method given by its name\n"
604 ".irgldname ldname prints address and graph number of a method given by its ldname\n"
605 ".help list all commands\n"
607 } /* show_commands */
610 * Shows all Firm breakpoints.
612 static void show_bp(void) {
618 dbg_printf("Firm Breakpoints:");
619 for (p = bp_list; p; p = p->next) {
621 dbg_printf("+\n BP %u: ", p->bpnr);
625 node_p = (bp_nr_t *)p;
626 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
630 ident_p = (bp_ident_t *)p;
631 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
635 dbg_printf(p->active ? "+enabled" : "+disabled");
637 dbg_printf(have_one ? "+\n" : "+ NONE\n");
641 * firm_dbg_register() expects that the name is stored persistent.
642 * So we need this little helper function
644 static firm_dbg_module_t *dbg_register(const char *name) {
645 ident *id = new_id_from_str(name);
647 return firm_dbg_register(get_id_str(id));
651 * Sets the debug mask of module name to lvl
653 static void set_dbg_level(const char *name, unsigned lvl)
655 firm_dbg_module_t *module = dbg_register(name);
657 if (firm_dbg_get_mask(module) != lvl) {
658 firm_dbg_set_mask(module, lvl);
660 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
662 } /* set_dbg_level */
665 * Redirects the debug output of module name to fname
667 static void set_dbg_outfile(const char *name, const char *fname)
669 firm_dbg_module_t *module = dbg_register(name);
670 FILE *f = fopen(fname, "w");
677 firm_dbg_set_file(module, f);
678 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
679 } /* set_dbg_outfile */
682 * Show info about a firm thing.
684 static void show_firm_object(void *firm_thing) {
687 if (firm_thing == NULL) {
688 fprintf(f, "<NULL>\n");
691 switch (get_kind(firm_thing)) {
693 fprintf(f, "BAD: (%p)\n", firm_thing);
696 dump_entity_to_file(f, firm_thing, dump_verbosity_max);
699 dump_type_to_file(f, firm_thing, dump_verbosity_max);
707 case k_ir_compound_graph_path:
713 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
715 } /* show_firm_object */
718 * Find a firm type by its number.
720 static ir_type *find_type_nr(long nr) {
721 int i, n = get_irp_n_types();
724 for (i = 0; i < n; ++i) {
725 tp = get_irp_type(i);
726 if (get_type_nr(tp) == nr)
729 tp = get_glob_type();
730 if (get_type_nr(tp) == nr)
736 * Find a firm type by its name.
738 static ir_type *find_type_name(const char *name) {
739 int i, n = get_irp_n_types();
742 for (i = 0; i < n; ++i) {
743 tp = get_irp_type(i);
744 if (strcmp(get_type_name(tp), name) == 0)
747 tp = get_glob_type();
748 if (strcmp(get_type_name(tp), name) == 0)
751 } /* find_type_name */
753 /** The environment for the entity search functions. */
754 typedef struct find_env {
756 long nr; /**< the number that is searched for */
757 const char *name; /**< the name that is searched for */
759 ir_entity *res; /**< the result */
763 * Type-walker: Find an entity with given number.
765 static void check_ent_nr(type_or_ent *tore, void *ctx) {
766 ir_entity *ent = (ir_entity *)tore;
767 find_env_t *env = ctx;
770 if (get_entity_nr(ent) == env->u.nr) {
776 * Type-walker: Find an entity with given name.
778 static void check_ent_name(type_or_ent *tore, void *ctx) {
779 ir_entity *ent = (ir_entity *)tore;
780 find_env_t *env = ctx;
783 if (strcmp(get_entity_name(ent), env->u.name) == 0) {
786 } /* check_ent_name */
789 * Find a firm entity by its number.
791 static ir_entity *find_entity_nr(long nr) {
796 type_walk(check_ent_nr, NULL, &env);
798 } /* find_entity_nr */
801 * Find a firm entity by its name.
803 static ir_entity *find_entity_name(const char *name) {
808 type_walk(check_ent_name, NULL, &env);
810 } /* find_entity_name */
813 * Search methods for a name.
815 static void show_by_name(type_or_ent *tore, void *env) {
816 ident *id = (ident *)env;
818 if (is_entity(tore)) {
819 ir_entity *ent = (ir_entity *)tore;
821 if (is_method_entity(ent)) {
822 if (get_entity_ident(ent) == id) {
823 ir_type *owner = get_entity_owner(ent);
824 ir_graph *irg = get_entity_irg(ent);
826 if (owner != get_glob_type()) {
827 printf("%s::%s", get_type_name(owner), get_id_str(id));
829 printf("%s", get_id_str(id));
832 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
841 * Search methods for a ldname.
843 static void show_by_ldname(type_or_ent *tore, void *env) {
844 ident *id = (ident *)env;
846 if (is_entity(tore)) {
847 ir_entity *ent = (ir_entity *)tore;
849 if (is_method_entity(ent)) {
850 if (get_entity_ld_ident(ent) == id) {
851 ir_type *owner = get_entity_owner(ent);
852 ir_graph *irg = get_entity_irg(ent);
854 if (owner != get_glob_type()) {
855 printf("%s::%s", get_type_name(owner), get_id_str(id));
857 printf("%s", get_id_str(id));
860 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
866 } /* show_by_ldname */
869 * prints the address and graph number of all irgs with given name
871 static void irg_name(const char *name) {
872 ident *id = new_id_from_str(name);
874 type_walk(show_by_name, NULL, (void *)id);
878 * prints the address and graph number of all irgs with given ld_name
880 static void irg_ld_name(const char *name) {
881 ident *id = new_id_from_str(name);
883 type_walk(show_by_ldname, NULL, (void *)id);
911 static const char *reserved[] = {
935 static struct lexer {
936 int has_token; /**< set if a token is cached. */
937 unsigned cur_token; /**< current token. */
938 unsigned number; /**< current token attribute. */
939 const char *s; /**< current token attribute. */
940 unsigned len; /**< current token attribute. */
942 const char *curr_pos;
944 const char *tok_start;
948 * Initialize the lexer.
950 static void init_lexer(const char *input) {
952 lexer.curr_pos = input;
953 lexer.end_pos = input + strlen(input);
958 * Get the next char from the input.
960 static char next_char(void) {
961 if (lexer.curr_pos >= lexer.end_pos)
963 return *lexer.curr_pos++;
966 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
969 #define MIN(a, b) (a) < (b) ? (a) : (b)
974 static unsigned get_token(void) {
978 /* skip white space */
981 } while (c != '\0' && isspace(c));
983 lexer.tok_start = lexer.curr_pos - 1;
985 /* command begins here */
991 } while (isalpha(c));
995 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
996 if (strncasecmp(lexer.tok_start + 1, reserved[i], len) == 0 && reserved[i][len] == '\0')
1002 } else if (isalpha(c)) {
1004 lexer.s = lexer.curr_pos - 1;
1008 } while (isgraph(c));
1010 lexer.len = lexer.curr_pos - lexer.s;
1011 return tok_identifier;
1012 } else if (isdigit(c) || c == '-') {
1013 unsigned number = 0;
1016 /* we support negative numbers as well, so one can easily set all bits with -1 */
1025 if (c == 'x' || c == 'X') {
1032 number = (number << 4) | (c - '0');
1034 number = (number << 4) | (toupper(c) - 'A' + 10);
1037 lexer.number = number;
1044 number = number * 10 + (c - '0');
1048 lexer.number = sign ? 0 - number : number;
1057 * High level function to use from debugger interface
1059 * Supported commands:
1060 * .create nr break if node nr was created
1061 * .help list all commands
1063 void firm_debug(const char *cmd) {
1064 char name[1024], fname[1024];
1072 token = get_token();
1079 token = get_token();
1080 if (token != tok_number)
1082 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1086 token = get_token();
1087 if (token != tok_number)
1089 break_on_nr(lexer.number, BP_ON_REPLACE);
1093 token = get_token();
1094 if (token != tok_number)
1096 break_on_nr(lexer.number, BP_ON_LOWER);
1100 token = get_token();
1102 if (token == tok_number)
1103 break_on_nr(lexer.number, BP_ON_REMIRG);
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_REMIRG);
1114 token = get_token();
1116 if (token == tok_number)
1117 break_on_nr(lexer.number, BP_ON_NEW_ENT);
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_ENT);
1128 token = get_token();
1130 if (token == tok_number)
1131 break_on_nr(lexer.number, BP_ON_NEW_TYPE);
1132 else if (token == tok_identifier) {
1133 len = MIN(lexer.len, 1023);
1134 strncpy(name, lexer.s, len);
1136 break_on_ident(name, BP_ON_NEW_TYPE);
1142 token = get_token();
1144 if (token == tok_number)
1145 show_firm_object(find_type_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_type_name(name));
1156 token = get_token();
1158 if (token == tok_number)
1159 show_firm_object(find_entity_nr(lexer.number));
1160 else if (token == tok_identifier) {
1161 len = MIN(lexer.len, 1023);
1162 strncpy(name, lexer.s, len);
1164 show_firm_object(find_entity_name(name));
1178 token = get_token();
1179 if (token != tok_number)
1181 bp_activate(lexer.number, 1);
1185 token = get_token();
1186 if (token != tok_number)
1188 bp_activate(lexer.number, 0);
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, lexer.number);
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_number)
1216 set_dbg_level(name, (1 << lexer.number) - 1);
1219 case tok_setoutfile:
1220 token = get_token();
1221 if (token != tok_identifier)
1223 len = MIN(lexer.len, 1023);
1224 strncpy(name, lexer.s, len);
1227 token = get_token();
1228 if (token != tok_identifier)
1230 len = MIN(lexer.len, 1023);
1231 strncpy(fname, lexer.s, len);
1233 set_dbg_outfile(name, fname);
1236 token = get_token();
1237 if (token != tok_identifier)
1239 len = MIN(lexer.len, 1023);
1240 strncpy(name, lexer.s, len);
1245 token = get_token();
1246 if (token != tok_identifier)
1248 len = MIN(lexer.len, 1023);
1249 strncpy(name, lexer.s, len);
1261 printf("Error: before %s\n", lexer.tok_start);
1266 token = get_token();
1267 if (token == tok_eof)
1276 /* creates the debugger tables */
1277 void firm_init_debugger(void)
1281 bp_numbers = new_set(cmp_nr_bp, 8);
1282 bp_idents = new_set(cmp_ident_bp, 8);
1284 env = getenv("FIRMDBG");
1293 } /* firm_init_debugger */
1296 * A gdb helper function to print firm objects.
1298 const char *gdb_node_helper(void *firm_object) {
1299 static char buf[1024];
1300 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1305 * A gdb helper function to print tarvals.
1307 const char *gdb_tarval_helper(void *tv_object) {
1308 static char buf[1024];
1309 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1315 /* some picky compiler do not allow empty files */
1316 static int _firm_only_that_you_can_compile_with_NDEBUG_defined;
1321 * @page debugger The Firm debugger extension
1323 * Firm contains a debugger extension. This allows to set debugger breakpoints
1324 * an various events.
1325 * The extension uses a text interface which can be accessed from most debuggers.
1326 * More than one command can be given separated by ';'.
1328 * @section sec_cmd Supported commands
1330 * The following commands are currently supported:
1334 * Break immediately after the debugger extension was initialized.
1335 * Typically this command is used in the environment to stop the execution
1336 * of a Firm compiler right after the initialization, like this:
1338 * $export FIRMDBG=".init"
1342 * Break if a new IR-node with node number nr was created.
1343 * Typically used to find the place where wrong nodes are created.
1347 * Break before IR-node with node number nr is replaced by another node.
1351 * Break before IR-node with node number nr is lowered.
1355 * Break if the irg with graph number nr is deleted.
1359 * Break if the irg of entity name is deleted.
1363 * Break if the entity with number nr was created.
1367 * Break if the entity name was created.
1371 * Break if the type with number nr was created.
1375 * Break if the type name was created.
1379 * Show all Firm internal breakpoints.
1383 * Enables breakpoint nr.
1387 * Disables breakpoint nr.
1391 * Show the content of entity nr.
1395 * Show the content of entity name.
1399 * Show the content of type nr.
1403 * Show the content of type name.
1405 * @b .setmask name msk
1407 * Sets the debug module name to mask msk.
1409 * @b .setlvl name lvl
1411 * Sets the debug module name to level lvl.
1413 * @b .setoutfile name file
1415 * Redirects debug output of module name to file.
1419 * Prints address and graph number of a method given by its name.
1421 * @b .irgldname name
1423 * Prints address and graph number of a method given by its linker name.
1427 * List all commands.
1430 * The Firm debugger extension can be accessed using the function firm_debug().
1431 * The following example shows how to set a creation breakpoint in GDB when
1432 * node 2101 is created.
1434 * -# set FIRMDBG=".init"
1435 * -# start gdb with your compiler
1436 * -# after gdb breaks, issue
1438 * call firm_debug(".create 2101")
1440 * On the console the following text should be issued:
1442 * Firm BP 1: creation of Node 2101
1445 * @section gdb_macro GDB macro
1447 * Add the following to your .gdbinit file:
1450 # define firm "cmd" Firm debugger extension
1453 call firm_debug($arg0)
1457 * Then, all Firm debugger extension commands can be accessed in the gdb
1458 * console using the firm prefix, eg.:
1460 * firm ".create 2101"