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
31 #include "firm_config.h"
36 #define WIN32_LEAN_AND_MEAN
39 #define strncasecmp strnicmp
61 #include "irgraph_t.h"
65 #include "iredges_t.h"
69 /* Break into the debugger. The Win32 way. */
70 void firm_debug_break(void) {
73 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
74 /* Break into the debugger. The ia32/x86_64 way under GCC. */
75 void firm_debug_break(void) {
76 __asm__ __volatile__("int3");
79 /* Break into the debugger. Poor Unix way. */
80 void firm_debug_break(void) {
85 /** supported breakpoint kinds */
87 BP_NR = 'n', /**< break on node number. */
88 BP_IDENT = 'i' /**< break on ident. */
92 * Reasons for node number breakpoints.
94 typedef enum _bp_reasons_t {
95 BP_ON_NEW_NODE, /**< break if node with number is created */
96 BP_ON_REPLACE, /**< break if node with number is replaced */
97 BP_ON_LOWER, /**< break if node with number is lowered */
98 BP_ON_REMIRG, /**< break if an IRG is removed */
99 BP_ON_NEW_ENT, /**< break if a new entity is created */
100 BP_ON_NEW_TYPE, /**< break if a new type is created */
105 typedef struct _breakpoint {
106 bp_kind kind; /**< the kind of this break point */
107 unsigned bpnr; /**< break point number */
108 int active; /**< non-zero, if this break point is active */
109 bp_reasons_t reason; /**< reason for the breakpoint */
110 struct _breakpoint *next; /**< link to the next one */
113 /** A number breakpoint. */
115 breakpoint bp; /**< the breakpoint data */
116 long nr; /**< the node number */
119 /** Calculate the hash value for a node breakpoint. */
120 #define HASH_NR_BP(key) (((key).nr << 2) ^ (key).bp.reason)
122 /** An ident breakpoint. */
124 breakpoint bp; /**< the breakpoint data */
125 ident *id; /**< the ident */
128 /** Calculate the hash value for an ident breakpoint. */
129 #define HASH_IDENT_BP(key) (HASH_PTR((key).id) ^ (key).bp.reason)
131 /** The set containing the breakpoints on node numbers. */
132 static set *bp_numbers;
134 /** The set containing the breakpoints on idents. */
135 static set *bp_idents;
137 /**< the list of all breakpoints */
138 static breakpoint *bp_list;
140 /** number of the current break point */
141 static unsigned bp_num = 0;
143 /** set if break on init command was issued. */
144 static int break_on_init = 0;
146 /** the hook entries for the Firm debugger module. */
147 static hook_entry_t debugger_hooks[hook_last];
149 /** number of active breakpoints to maintain hooks. */
150 static unsigned num_active_bp[BP_MAX_REASON];
153 * The debug message buffer
155 static char firm_dbg_msg_buf[2048];
158 * If set, the debug extension writes all output to the
159 * firm_dbg_msg_buf buffer
161 static int redir_output = 0;
164 * Is set to one, if the debug extension is active
166 static int is_active = 0;
168 /** hook the hook h with function fkt. */
169 #define HOOK(h, fkt) \
171 debugger_hooks[h].hook._##h = fkt; \
172 register_hook(h, &debugger_hooks[h]); \
175 /** unhook the hook h */
178 unregister_hook(h, &debugger_hooks[h]); \
179 debugger_hooks[h].hook._##h = NULL; \
182 /** returns non-zero if a entry hook h is used */
183 #define IS_HOOKED(h) (debugger_hooks[h].hook._##h != NULL)
185 /* some macros needed to create the info string */
186 #define _DBG_VERSION(major, minor) #major "." #minor
187 #define DBG_VERSION(major, minor) _DBG_VERSION(major, minor)
188 #define API_VERSION(major, minor) "API:" DBG_VERSION(major, minor)
190 /* the API version: change if needed */
191 #define FIRM_DBG_MAJOR 1
192 #define FIRM_DBG_MINOR 0
194 /** for automatic detection of the debug extension */
195 static const char firm_debug_info_string[] =
196 API_VERSION(FIRM_DBG_MAJOR, FIRM_DBG_MINOR);
199 * Returns non-zero, if the debug extension is active
201 int firm_debug_active(void) {
203 } /* firm_debug_active */
206 * Reset the debug text buffer.
208 static void reset_dbg_buf(void) {
209 firm_dbg_msg_buf[0] = '\0';
210 } /* reset_dbg_buf */
213 * Add text to the debug text buffer.
215 static void add_to_dbg_buf(const char *buf) {
216 strncat(firm_dbg_msg_buf, buf, sizeof(firm_dbg_msg_buf));
217 } /* add_to_dbg_buf */
220 * Return the content of the debug text buffer.
222 * To be called from the debugger.
224 const char *firm_debug_text(void) {
225 firm_dbg_msg_buf[sizeof(firm_dbg_msg_buf) - 1] = '\0';
226 return firm_dbg_msg_buf;
227 } /* firm_debug_text */
232 static void dbg_printf(const char *fmt, ...)
244 ir_vsnprintf(buf, sizeof(buf), fmt, args);
254 * A new node is created.
256 * @param ctx the hook context
257 * @param irg the IR graph on which the node is created
258 * @param node the new IR node that was created
260 static void dbg_new_node(void *ctx, ir_graph *irg, ir_node *node)
266 key.nr = get_irn_node_nr(node);
267 key.bp.reason = BP_ON_NEW_NODE;
269 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
270 if (elem && elem->bp.active) {
271 dbg_printf("Firm BP %u reached, %+F created\n", elem->bp.bpnr, node);
277 * A node is replaced.
279 * @param ctx the hook context
280 * @param old the IR node the is replaced
281 * @param nw the new IR node that will replace old
283 static void dbg_replace(void *ctx, ir_node *old, ir_node *nw)
288 key.nr = get_irn_node_nr(old);
289 key.bp.reason = BP_ON_REPLACE;
291 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
292 if (elem && elem->bp.active) {
293 dbg_printf("Firm BP %u reached, %+F will be replaced by %+F\n", elem->bp.bpnr, old, nw);
299 * A new node is lowered.
301 * @param ctx the hook context
302 * @param node the new IR node that will be lowered
304 static void dbg_lower(void *ctx, ir_node *node)
309 key.nr = get_irn_node_nr(node);
310 key.bp.reason = BP_ON_LOWER;
312 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
313 if (elem && elem->bp.active) {
314 dbg_printf("Firm BP %u reached, %+F will be lowered\n", elem->bp.bpnr, node);
320 * A graph will be deleted.
322 * @param ctx the hook context
323 * @param irg the IR graph that will be deleted
325 static void dbg_free_graph(void *ctx, ir_graph *irg)
330 key.nr = get_irg_graph_nr(irg);
331 key.bp.reason = BP_ON_REMIRG;
333 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
334 if (elem && elem->bp.active) {
335 ir_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, irg);
340 bp_ident_t key, *elem;
341 ir_entity *ent = get_irg_entity(irg);
346 key.id = get_entity_ident(ent);
347 key.bp.reason = BP_ON_REMIRG;
349 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
350 if (elem && elem->bp.active) {
351 dbg_printf("Firm BP %u reached, %+F will be deleted\n", elem->bp.bpnr, ent);
355 } /* dbg_free_graph */
358 * An entity was created.
360 * @param ctx the hook context
361 * @param ent the newly created entity
363 static void dbg_new_entity(void *ctx, ir_entity *ent)
367 bp_ident_t key, *elem;
369 key.id = get_entity_ident(ent);
370 key.bp.reason = BP_ON_NEW_ENT;
372 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
373 if (elem && elem->bp.active) {
374 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
381 key.nr = get_entity_nr(ent);
382 key.bp.reason = BP_ON_NEW_ENT;
384 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
385 if (elem && elem->bp.active) {
386 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, ent);
390 } /* dbg_new_entity */
393 * A type was created.
395 * @param ctx the hook context
396 * @param tp the newly created type
398 static void dbg_new_type(void *ctx, ir_type *tp)
404 key.nr = get_type_nr(tp);
405 key.bp.reason = BP_ON_NEW_TYPE;
407 elem = set_find(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
408 if (elem && elem->bp.active) {
409 ir_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
414 bp_ident_t key, *elem;
416 key.id = get_type_ident(tp);
417 key.bp.reason = BP_ON_NEW_TYPE;
419 elem = set_find(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
420 if (elem && elem->bp.active) {
421 dbg_printf("Firm BP %u reached, %+F was created\n", elem->bp.bpnr, tp);
428 * Return the reason string.
430 static const char *reason_str(bp_reasons_t reason)
433 case BP_ON_NEW_NODE: return "node creation";
434 case BP_ON_REPLACE: return "node replace";
435 case BP_ON_LOWER: return "node lowering";
436 case BP_ON_REMIRG: return "removing IRG";
437 case BP_ON_NEW_ENT: return "entity creation";
438 case BP_ON_NEW_TYPE: return "type creation";
445 * Compare two number breakpoints.
447 static int cmp_nr_bp(const void *elt, const void *key, size_t size)
449 const bp_nr_t *e1 = elt;
450 const bp_nr_t *e2 = key;
453 return (e1->nr - e2->nr) | (e1->bp.reason - e2->bp.reason);
457 * Compare two ident breakpoints.
459 static int cmp_ident_bp(const void *elt, const void *key, size_t size)
461 const bp_ident_t *e1 = elt;
462 const bp_ident_t *e2 = key;
465 return (e1->id != e2->id) | (e1->bp.reason - e2->bp.reason);
471 static void update_hooks(breakpoint *bp)
473 #define CASE_ON(a, b) case a: if (! IS_HOOKED(hook_##b)) HOOK(hook_##b, dbg_##b); break
474 #define CASE_OFF(a, b) case a: if (IS_HOOKED(hook_##b)) UNHOOK(hook_##b); break
477 ++num_active_bp[bp->reason];
479 --num_active_bp[bp->reason];
481 if (num_active_bp[bp->reason] > 0) {
482 /* register the hooks on demand */
483 switch (bp->reason) {
484 CASE_ON(BP_ON_NEW_NODE, new_node);
485 CASE_ON(BP_ON_REPLACE, replace);
486 CASE_ON(BP_ON_LOWER, lower);
487 CASE_ON(BP_ON_REMIRG, free_graph);
488 CASE_ON(BP_ON_NEW_ENT, new_entity);
489 CASE_ON(BP_ON_NEW_TYPE, new_type);
495 /* unregister the hook on demand */
496 switch (bp->reason) {
497 CASE_OFF(BP_ON_NEW_NODE, new_node);
498 CASE_OFF(BP_ON_REPLACE, replace);
499 CASE_OFF(BP_ON_LOWER, lower);
500 CASE_OFF(BP_ON_REMIRG, free_graph);
501 CASE_OFF(BP_ON_NEW_ENT, new_entity);
502 CASE_OFF(BP_ON_NEW_TYPE, new_type);
512 * Break if nr is reached.
514 static void break_on_nr(long nr, bp_reasons_t reason)
521 key.bp.reason = reason;
524 elem = set_insert(bp_numbers, &key, sizeof(key), HASH_NR_BP(key));
526 if (elem->bp.bpnr == 0) {
527 /* new break point */
528 elem->bp.bpnr = ++bp_num;
529 elem->bp.next = bp_list;
532 dbg_printf("Firm BP %u: %s of Nr %ld\n", elem->bp.bpnr, reason_str(reason), nr);
534 update_hooks(&elem->bp);
539 * Break if ident name is reached.
541 static void break_on_ident(const char *name, bp_reasons_t reason) {
542 bp_ident_t key, *elem;
544 key.bp.kind = BP_IDENT;
547 key.bp.reason = reason;
548 key.id = new_id_from_str(name);
550 elem = set_insert(bp_idents, &key, sizeof(key), HASH_IDENT_BP(key));
552 if (elem->bp.bpnr == 0) {
553 /* new break point */
554 elem->bp.bpnr = ++bp_num;
555 elem->bp.next = bp_list;
558 dbg_printf("Firm BP %u: %s of ident \"%s\"\n", elem->bp.bpnr, reason_str(reason), name);
560 update_hooks(&elem->bp);
562 } /* break_on_ident */
565 * Sets/resets the active flag of breakpoint bp.
567 static void bp_activate(unsigned bp, int active)
571 for (p = bp_list; p; p = p->next) {
573 if (p->active != active) {
578 dbg_printf("Firm BP %u is now %s\n", bp, active ? "enabled" : "disabled");
582 dbg_printf("Error: Firm BP %u not exists.\n", bp);
587 * Show a list of supported commands
589 static void show_commands(void) {
590 dbg_printf("Internal Firm debugger extension $Revision$ commands:\n"
591 "init break after initialization\n"
592 "create nr break if node nr was created\n"
593 "replace nr break if node nr is replaced by another node\n"
594 "lower nr break before node nr is lowered\n"
595 "remirg nr|name break if the irg of nr or entity name is deleted\n"
596 "newent nr|name break if the entity nr or name was created\n"
597 "newtype nr|name break if the type nr or name was created\n"
598 "bp show all breakpoints\n"
599 "enable nr enable breakpoint nr\n"
600 "disable nr disable breakpoint nr\n"
601 "showtype nr|name show content of the type nr or name\n"
602 "showent nr|name show content of the entity nr or name\n"
603 "setmask name msk sets the debug module name to mask msk\n"
604 "setlvl name lvl sets the debug module name to level lvl\n"
605 "setoutfile name file redirects debug output of module name to file\n"
606 "irgname name prints address and graph number of a method given by its name\n"
607 "irgldname ldname prints address and graph number of a method given by its ldname\n"
608 "help list all commands\n"
610 } /* show_commands */
613 * Shows all Firm breakpoints.
615 static void show_bp(void) {
621 dbg_printf("Firm Breakpoints:");
622 for (p = bp_list; p; p = p->next) {
624 dbg_printf("+\n BP %u: ", p->bpnr);
628 node_p = (bp_nr_t *)p;
629 dbg_printf("%s of Nr %ld ", reason_str(p->reason), node_p->nr);
633 ident_p = (bp_ident_t *)p;
634 dbg_printf("+%s of ident \"%s\" ", reason_str(p->reason), get_id_str(ident_p->id));
638 dbg_printf(p->active ? "+enabled" : "+disabled");
640 dbg_printf(have_one ? "+\n" : "+ NONE\n");
644 * firm_dbg_register() expects that the name is stored persistent.
645 * So we need this little helper function
647 static firm_dbg_module_t *dbg_register(const char *name) {
648 ident *id = new_id_from_str(name);
650 return firm_dbg_register(get_id_str(id));
654 * Sets the debug mask of module name to lvl
656 static void set_dbg_level(const char *name, unsigned lvl)
658 firm_dbg_module_t *module = dbg_register(name);
660 if (firm_dbg_get_mask(module) != lvl) {
661 firm_dbg_set_mask(module, lvl);
663 dbg_printf("Setting debug mask of module %s to %u\n", name, lvl);
665 } /* set_dbg_level */
668 * Redirects the debug output of module name to fname
670 static void set_dbg_outfile(const char *name, const char *fname)
672 firm_dbg_module_t *module = dbg_register(name);
673 FILE *f = fopen(fname, "w");
680 firm_dbg_set_file(module, f);
681 dbg_printf("Redirecting debug output of module %s to file %s\n", name, fname);
682 } /* set_dbg_outfile */
685 * Show info about a firm thing.
687 static void show_firm_object(void *firm_thing) {
690 if (firm_thing == NULL) {
691 fprintf(f, "<NULL>\n");
694 switch (get_kind(firm_thing)) {
696 fprintf(f, "BAD: (%p)\n", firm_thing);
699 dump_entity_to_file(f, firm_thing, dump_verbosity_max);
702 dump_type_to_file(f, firm_thing, dump_verbosity_max);
710 case k_ir_compound_graph_path:
716 fprintf(f, "Cannot identify thing at (%p).\n", firm_thing);
718 } /* show_firm_object */
721 * Find a firm type by its number.
723 static ir_type *find_type_nr(long nr) {
724 int i, n = get_irp_n_types();
727 for (i = 0; i < n; ++i) {
728 tp = get_irp_type(i);
729 if (get_type_nr(tp) == nr)
732 tp = get_glob_type();
733 if (get_type_nr(tp) == nr)
739 * Find a firm type by its name.
741 static ir_type *find_type_name(const char *name) {
742 int i, n = get_irp_n_types();
745 for (i = 0; i < n; ++i) {
746 tp = get_irp_type(i);
747 if (strcmp(get_type_name(tp), name) == 0)
750 tp = get_glob_type();
751 if (strcmp(get_type_name(tp), name) == 0)
754 } /* find_type_name */
756 /** The environment for the entity search functions. */
757 typedef struct find_env {
759 long nr; /**< the number that is searched for */
760 const char *name; /**< the name that is searched for */
762 ir_entity *res; /**< the result */
766 * Type-walker: Find an entity with given number.
768 static void check_ent_nr(type_or_ent tore, void *ctx) {
769 find_env_t *env = ctx;
771 if (is_entity(tore.ent)) {
772 if (get_entity_nr(tore.ent) == env->u.nr) {
779 * Type-walker: Find an entity with given name.
781 static void check_ent_name(type_or_ent tore, void *ctx) {
782 find_env_t *env = ctx;
784 if (is_entity(tore.ent))
785 if (strcmp(get_entity_name(tore.ent), env->u.name) == 0) {
788 } /* check_ent_name */
791 * Find a firm entity by its number.
793 static ir_entity *find_entity_nr(long nr) {
798 type_walk(check_ent_nr, NULL, &env);
800 } /* find_entity_nr */
803 * Find a firm entity by its name.
805 static ir_entity *find_entity_name(const char *name) {
810 type_walk(check_ent_name, NULL, &env);
812 } /* find_entity_name */
815 * Search methods for a name.
817 static void show_by_name(type_or_ent *tore, void *env) {
818 ident *id = (ident *)env;
820 if (is_entity(tore)) {
821 ir_entity *ent = (ir_entity *)tore;
823 if (is_method_entity(ent)) {
824 if (get_entity_ident(ent) == id) {
825 ir_type *owner = get_entity_owner(ent);
826 ir_graph *irg = get_entity_irg(ent);
828 if (owner != get_glob_type()) {
829 printf("%s::%s", get_type_name(owner), get_id_str(id));
831 printf("%s", get_id_str(id));
834 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
843 * Search methods for a ldname.
845 static void show_by_ldname(type_or_ent tore, void *env) {
846 ident *id = (ident *)env;
848 if (is_entity(tore.ent)) {
849 ir_entity *ent = tore.ent;
851 if (is_method_entity(ent)) {
852 if (get_entity_ld_ident(ent) == id) {
853 ir_type *owner = get_entity_owner(ent);
854 ir_graph *irg = get_entity_irg(ent);
856 if (owner != get_glob_type()) {
857 printf("%s::%s", get_type_name(owner), get_id_str(id));
859 printf("%s", get_id_str(id));
862 printf("[%ld] (%p)\n", get_irg_graph_nr(irg), irg);
868 } /* show_by_ldname */
871 * prints the address and graph number of all irgs with given name
873 static void irg_name(const char *name) {
874 ident *id = new_id_from_str(name);
876 type_walk(show_by_name, NULL, (void *)id);
880 * prints the address and graph number of all irgs with given ld_name
882 static void irg_ld_name(const char *name) {
883 ident *id = new_id_from_str(name);
885 type_walk(show_by_ldname, NULL, (void *)id);
913 static const char *reserved[] = {
937 static struct lexer {
938 int has_token; /**< set if a token is cached. */
939 unsigned cur_token; /**< current token. */
940 unsigned number; /**< current token attribute. */
941 const char *s; /**< current token attribute. */
942 unsigned len; /**< current token attribute. */
944 const char *curr_pos;
946 const char *tok_start;
950 * Initialize the lexer.
952 static void init_lexer(const char *input) {
954 lexer.curr_pos = input;
955 lexer.end_pos = input + strlen(input);
960 * Get the next char from the input.
962 static char next_char(void) {
963 if (lexer.curr_pos >= lexer.end_pos)
965 return *lexer.curr_pos++;
968 #define unput() if (lexer.curr_pos < lexer.end_pos) --lexer.curr_pos
971 #define MIN(a, b) (a) < (b) ? (a) : (b)
976 static unsigned get_token(void) {
980 /* skip white space */
983 } while (c != '\0' && isspace(c));
985 lexer.tok_start = lexer.curr_pos - 1;
986 if (c == '.' || isalpha(c)) {
987 /* command begins here */
989 const char* tok_start;
994 } while (isgraph(c));
997 tok_start = lexer.tok_start;
998 if (*tok_start == '.') {
1002 for (i = sizeof(reserved)/sizeof(reserved[0]) - 1; i >= 0; --i) {
1003 if (strncasecmp(tok_start, reserved[i], len) == 0 && reserved[i][len] == '\0')
1008 lexer.s = lexer.tok_start;
1009 lexer.len = lexer.curr_pos - lexer.s;
1010 return tok_identifier;
1011 } else if (isdigit(c) || c == '-') {
1012 unsigned number = 0;
1015 /* we support negative numbers as well, so one can easily set all bits with -1 */
1024 if (c == 'x' || c == 'X') {
1031 number = (number << 4) | (c - '0');
1033 number = (number << 4) | (toupper(c) - 'A' + 10);
1036 lexer.number = number;
1043 number = number * 10 + (c - '0');
1047 lexer.number = sign ? 0 - number : number;
1056 * High level function to use from debugger interface
1058 * See show_commands() for supported commands.
1060 void firm_debug(const char *cmd) {
1061 char name[1024], fname[1024];
1069 token = get_token();
1076 token = get_token();
1077 if (token != tok_number)
1079 break_on_nr(lexer.number, BP_ON_NEW_NODE);
1083 token = get_token();
1084 if (token != tok_number)
1086 break_on_nr(lexer.number, BP_ON_REPLACE);
1090 token = get_token();
1091 if (token != tok_number)
1093 break_on_nr(lexer.number, BP_ON_LOWER);
1097 token = get_token();
1099 if (token == tok_number)
1100 break_on_nr(lexer.number, BP_ON_REMIRG);
1101 else if (token == tok_identifier) {
1102 len = MIN(lexer.len, 1023);
1103 strncpy(name, lexer.s, len);
1105 break_on_ident(name, BP_ON_REMIRG);
1111 token = get_token();
1113 if (token == tok_number)
1114 break_on_nr(lexer.number, BP_ON_NEW_ENT);
1115 else if (token == tok_identifier) {
1116 len = MIN(lexer.len, 1023);
1117 strncpy(name, lexer.s, len);
1119 break_on_ident(name, BP_ON_NEW_ENT);
1125 token = get_token();
1127 if (token == tok_number)
1128 break_on_nr(lexer.number, BP_ON_NEW_TYPE);
1129 else if (token == tok_identifier) {
1130 len = MIN(lexer.len, 1023);
1131 strncpy(name, lexer.s, len);
1133 break_on_ident(name, BP_ON_NEW_TYPE);
1139 token = get_token();
1141 if (token == tok_number)
1142 show_firm_object(find_type_nr(lexer.number));
1143 else if (token == tok_identifier) {
1144 len = MIN(lexer.len, 1023);
1145 strncpy(name, lexer.s, len);
1147 show_firm_object(find_type_name(name));
1153 token = get_token();
1155 if (token == tok_number)
1156 show_firm_object(find_entity_nr(lexer.number));
1157 else if (token == tok_identifier) {
1158 len = MIN(lexer.len, 1023);
1159 strncpy(name, lexer.s, len);
1161 show_firm_object(find_entity_name(name));
1175 token = get_token();
1176 if (token != tok_number)
1178 bp_activate(lexer.number, 1);
1182 token = get_token();
1183 if (token != tok_number)
1185 bp_activate(lexer.number, 0);
1189 token = get_token();
1190 if (token != tok_identifier)
1192 len = MIN(lexer.len, 1023);
1193 strncpy(name, lexer.s, len);
1196 token = get_token();
1197 if (token != tok_number)
1199 set_dbg_level(name, lexer.number);
1203 token = get_token();
1204 if (token != tok_identifier)
1206 len = MIN(lexer.len, 1023);
1207 strncpy(name, lexer.s, len);
1210 token = get_token();
1211 if (token != tok_number)
1213 set_dbg_level(name, (1 << lexer.number) - 1);
1216 case tok_setoutfile:
1217 token = get_token();
1218 if (token != tok_identifier)
1220 len = MIN(lexer.len, 1023);
1221 strncpy(name, lexer.s, len);
1224 token = get_token();
1225 if (token != tok_identifier)
1227 len = MIN(lexer.len, 1023);
1228 strncpy(fname, lexer.s, len);
1230 set_dbg_outfile(name, fname);
1233 token = get_token();
1234 if (token != tok_identifier)
1236 len = MIN(lexer.len, 1023);
1237 strncpy(name, lexer.s, len);
1242 token = get_token();
1243 if (token != tok_identifier)
1245 len = MIN(lexer.len, 1023);
1246 strncpy(name, lexer.s, len);
1258 printf("Error: before %s\n", lexer.tok_start);
1263 token = get_token();
1264 if (token == tok_eof)
1273 /* creates the debugger tables */
1274 void firm_init_debugger(void)
1278 bp_numbers = new_set(cmp_nr_bp, 8);
1279 bp_idents = new_set(cmp_ident_bp, 8);
1281 env = getenv("FIRMDBG");
1290 } /* firm_init_debugger */
1293 * A gdb helper function to print firm objects.
1295 const char *gdb_node_helper(void *firm_object) {
1296 static char buf[1024];
1297 ir_snprintf(buf, sizeof(buf), "%+F", firm_object);
1302 * A gdb helper function to print tarvals.
1304 const char *gdb_tarval_helper(void *tv_object) {
1305 static char buf[1024];
1306 ir_snprintf(buf, sizeof(buf), "%+T", tv_object);
1310 const char *gdb_out_edge_helper(const ir_node *node) {
1311 static char buf[4*1024];
1314 size_t len = sizeof(buf);
1315 const ir_edge_t *edge;
1316 foreach_out_edge(node, edge) {
1317 ir_node *n = get_edge_src_irn(edge);
1319 ir_snprintf(b, len, "%+F ", n);
1330 /* some picky compiler do not allow empty files */
1331 static int __attribute__((unused)) _firm_only_that_you_can_compile_with_NDEBUG_defined;
1336 * @page debugger The Firm debugger extension
1338 * Firm contains a debugger extension. This allows to set debugger breakpoints
1339 * an various events.
1340 * The extension uses a text interface which can be accessed from most debuggers.
1341 * More than one command can be given separated by ';'.
1343 * @section sec_cmd Supported commands
1345 * Historically all debugger commands start with a dot. This isn't needed in newer
1346 * versions, but still supported, ie the commands ".init" and "init" are equal.
1347 * The following commands are currently supported:
1351 * Break immediately after the debugger extension was initialized.
1352 * Typically this command is used in the environment to stop the execution
1353 * of a Firm compiler right after the initialization, like this:
1355 * $export FIRMDBG=".init"
1359 * Break if a new IR-node with node number nr was created.
1360 * Typically used to find the place where wrong nodes are created.
1364 * Break before IR-node with node number nr is replaced by another node.
1368 * Break before IR-node with node number nr is lowered.
1372 * Break if the irg with graph number nr is deleted.
1376 * Break if the irg of entity name is deleted.
1380 * Break if the entity with number nr was created.
1384 * Break if the entity name was created.
1388 * Break if the type with number nr was created.
1392 * Break if the type name was created.
1396 * Show all Firm internal breakpoints.
1400 * Enables breakpoint nr.
1404 * Disables breakpoint nr.
1408 * Show the content of entity nr.
1412 * Show the content of entity name.
1416 * Show the content of type nr.
1420 * Show the content of type name.
1422 * @b setmask name msk
1424 * Sets the debug module name to mask msk.
1426 * @b setlvl name lvl
1428 * Sets the debug module name to level lvl.
1430 * @b setoutfile name file
1432 * Redirects debug output of module name to file.
1436 * Prints address and graph number of a method given by its name.
1440 * Prints address and graph number of a method given by its linker name.
1444 * List all commands.
1447 * The Firm debugger extension can be accessed using the function firm_debug().
1448 * The following example shows how to set a creation breakpoint in GDB when
1449 * node 2101 is created.
1451 * -# set FIRMDBG="init"
1452 * -# start gdb with your compiler
1453 * -# after gdb breaks, issue
1455 * call firm_debug("create 2101")
1457 * On the console the following text should be issued:
1459 * Firm BP 1: creation of Node 2101
1462 * @section gdb_macro GDB macro
1464 * Add the following to your .gdbinit file:
1467 # define firm "cmd" Firm debugger extension
1470 call firm_debug($arg0)
1474 * Then, all Firm debugger extension commands can be accessed in the gdb
1475 * console using the firm prefix, eg.:
1477 * firm "create 2101"