4 * (C) 2005 Michael Beck beck@ipd.info.uni-karlsruhe.de
6 #define WIN32_LEAN_AND_MEAN
14 /* ugly, but I must include array.h WITHOUT NDEBUG */
24 #include "irgraph_t.h"
30 #include "compound_path_t.h"
40 #include "firmEvaluator.h"
42 /** get the address of a pointer */
43 #define ADD_ADR(p, off) ((void *)((char *)(p) + (off)))
46 static void debug(char *fmt, ...)
52 vsprintf(buf, fmt, ap);
54 OutputDebugString(buf);
59 * return the size of a firm object
61 int get_firm_object_size(firm_kind kind)
64 case k_entity: /* an entity */
65 return sizeof(ir_entity);
66 case k_type: /* a type */
67 return sizeof(ir_type);
68 case k_ir_graph: /* an ir graph */
69 return sizeof(ir_graph);
70 case k_ir_node: /* an ir node */
71 return sizeof(ir_node);
72 case k_ir_mode: /* an ir mode */
73 return sizeof(ir_mode);
74 case k_ir_op: /* an ir opcode */
76 case k_tarval: /* a tarval */
77 return sizeof(tarval);
78 case k_ir_loop: /* a loop */
79 return sizeof(ir_loop);
80 case k_ir_prog: /* a program representation (irp) */
81 return sizeof(ir_prog);
85 } /* get_firm_object_size */
88 * returns the string length of a string in debuggee space
90 * @return string length or negative value on error
92 static int strlen_debuggee(DEBUGHELPER *pHelper, const void *address, size_t max)
96 const char *p = address;
98 for (i = 0; i < max; ++i) {
99 if (copy_from_debuggee(p + i, pHelper, &v, sizeof(v)) != S_OK)
106 } /* strlen_debuggee */
111 HRESULT format_ident(DEBUGHELPER *pHelper, const void *address, char *pResult, size_t max)
113 set_entry *data = NULL;
117 if (copy_from_debuggee(address, pHelper, &id, sizeof(id)) != S_OK)
121 if (id.size < 1 || id.size > 256)
125 len = offsetof(set_entry, dptr) + slen;
129 if (copy_from_debuggee(address, pHelper, data, len) != S_OK)
132 _tcsncpy(pResult, (const char *)data->dptr, max);
139 static HRESULT format_tp_op(DEBUGHELPER *pHelper, const void *addr, char *pResult, size_t max)
143 #define X(a) case tpo_##a: _tcsncpy(pResult, #a, max); return S_OK
144 #define Y(a, b) case tpo_##a: _tcsncpy(pResult, b, max); return S_OK
146 if (copy_from_debuggee(addr, pHelper, &op, sizeof(op)) != S_OK)
156 Y(enumeration, "enum");
158 Y(primitive, "prim");
169 * Checks whether a type is the global type
171 * @param type the address of the type in debuggee's space
173 static HRESULT is_global_type(DEBUGHELPER *pHelper, const void *type, int *flag)
178 if (copy_from_debuggee(type, pHelper, &tp, sizeof(tp)) != S_OK)
181 *flag = tp.flags & tf_global_type;
183 } /* is_global_type */
188 static HRESULT format_entity(DEBUGHELPER *pHelper, int nBase, const void *addr, char *pResult, size_t max, int top)
195 if (copy_from_debuggee(addr, pHelper, &ent, sizeof(ent)) != S_OK) {
198 if (is_global_type(pHelper, ent.owner, &is_global) != S_OK)
203 _tcsncpy(pResult, "ENT: ", max);
206 if (copy_from_debuggee(ent.owner, pHelper, &owner, sizeof(owner)) != S_OK)
208 if (format_ident(pHelper, (void *)owner.name, name, sizeof(name)) != S_OK)
210 _tcsncat(pResult, name, max);
211 _tcsncat(pResult, "::", max);
214 if (format_ident(pHelper, (void *)ent.name, name, sizeof(name)) != S_OK)
216 _tcsncat(pResult, name, max);
220 _snprintf(name, sizeof(name), " [0x%lx]", ent.nr);
223 _snprintf(name, sizeof(name), " [0%lo]", ent.nr);
226 _snprintf(name, sizeof(name), " [%ld]", ent.nr);
228 _tcsncat(pResult, name, max);
231 } /* format_entity */
236 static HRESULT format_mode(DEBUGHELPER *pHelper, const void *addr, char *pResult, size_t max)
240 if (copy_from_debuggee(addr, pHelper, &mode, sizeof(mode)) != S_OK)
242 if (format_ident(pHelper, mode.name, pResult, max) != S_OK)
250 static HRESULT format_type(DEBUGHELPER *pHelper, int nBase, const void *addr, char *pResult, size_t max, int top)
255 if (copy_from_debuggee(addr, pHelper, &tp, sizeof(tp)) != S_OK)
260 if (format_tp_op(pHelper, tp.type_op, pResult, max) != S_OK)
263 _tcsncat(pResult, " ", max);
268 if (format_ident(pHelper, tp.name, name, sizeof(name)) != S_OK)
271 if (format_mode(pHelper, tp.mode, name, sizeof(name)) != S_OK)
275 _tcsncat(pResult, name, max);
278 _snprintf(name, sizeof(name), " [0x%lx]", tp.nr);
281 _snprintf(name, sizeof(name), " [0%lo]", tp.nr);
284 _snprintf(name, sizeof(name), " [%ld]", tp.nr);
286 _tcsncat(pResult, name, max);
294 static HRESULT format_irg(DEBUGHELPER *pHelper, int nBase, const void *addr, char *pResult, size_t max, int top)
299 if (copy_from_debuggee(addr, pHelper, &irg, sizeof(irg)) != S_OK)
304 _tcsncpy(pResult, "IRG: ", max);
311 if (copy_from_debuggee(irg.ent, pHelper, &ent, sizeof(ent)) != S_OK)
313 if (is_global_type(pHelper, ent.owner, &is_global) != S_OK)
316 if (copy_from_debuggee(ent.owner, pHelper, &owner, sizeof(owner)) != S_OK)
318 if (format_ident(pHelper, (void *)owner.name, name, sizeof(name)) != S_OK)
320 _tcsncat(pResult, name, max);
321 _tcsncat(pResult, "::", max);
323 if (format_ident(pHelper, ent.name, name, sizeof(name)) != S_OK)
325 _tcsncat(pResult, name, max);
328 _tcsncat(pResult, "NULL", max);
332 _snprintf(name, sizeof(name), " [0x%lx, 0x%u nodes]", irg.graph_nr, irg.last_node_idx);
335 _snprintf(name, sizeof(name), " [0%lo, 0%o nodes]", irg.graph_nr, irg.last_node_idx);
338 _snprintf(name, sizeof(name), " [%ld, %u nodes]", irg.graph_nr, irg.last_node_idx);
340 _tcsncat(pResult, name, max);
347 HRESULT format_op(DEBUGHELPER *pHelper, const void *addr, char *pResult, size_t max)
351 if (copy_from_debuggee(addr, pHelper, &op, sizeof(op)) != S_OK)
353 if (format_ident(pHelper, op.name, pResult, max) != S_OK)
358 /** get a temporary string */
359 #define get_string(str) \
364 len = strlen_debuggee(pHelper, str, 256); \
367 s = alloca(len + 1); \
368 if (copy_from_debuggee(str, pHelper, s, (DWORD)len) != S_OK) \
378 static HRESULT format_tarval(DEBUGHELPER *pHelper, int nBase, const void *addr, char *pResult, size_t max)
384 tarval_mode_info modinfo;
387 static int initialized = 0;
390 /* from init_tarval_1() */
398 if (copy_from_debuggee(addr, pHelper, &tv, sizeof(tv)) != S_OK)
405 if (copy_from_debuggee(tv.mode, pHelper, &mode, sizeof(mode)) != S_OK)
410 if (mode_is_int(&mode)) {
413 modinfo.mode_output = TVO_HEX;
414 modinfo.mode_prefix = "0x";
415 modinfo.mode_suffix = "";
418 modinfo.mode_output = TVO_OCTAL;
419 modinfo.mode_prefix = "0";
420 modinfo.mode_suffix = "";
423 modinfo.mode_output = TVO_DECIMAL;
424 modinfo.mode_prefix = "";
425 modinfo.mode_suffix = "";
430 if (copy_from_debuggee(mode.tv_priv, pHelper, &modinfo, sizeof(modinfo)) != S_OK)
433 get_string(modinfo.mode_prefix);
434 get_string(modinfo.mode_suffix);
437 mode.tv_priv = &modinfo;
446 if (copy_from_debuggee(tv.value, pHelper, value, len) != S_OK)
451 tarval_snprintf(pResult, max, &tv);
454 /* might be a reserved tarval */
455 int resid = PTR_TO_INT(tv.value);
458 case resid_tarval_bad:
459 _tcsncat(pResult, "BAD", max);
461 case resid_tarval_undefined:
462 _tcsncat(pResult, "UNDEF", max);
464 case resid_tarval_b_false:
465 _tcsncat(pResult, "FALSE", max);
467 case resid_tarval_b_true:
468 _tcsncat(pResult, "TRUE", max);
472 tarval_snprintf(pResult, max, &tv);
476 } /* format_tarval */
481 static HRESULT format_node(DEBUGHELPER *pHelper, int nBase, const void *addr, char *pResult, size_t max, int top)
487 if (copy_from_debuggee(addr, pHelper, &n, sizeof(n)) != S_OK)
491 if (format_op(pHelper, n.op, pResult, max) != S_OK)
495 if (format_mode(pHelper, n.mode, name, sizeof(name)) != S_OK)
497 _tcsncat(pResult, name, max);
499 if (copy_from_debuggee(n.op, pHelper, &op, sizeof(op)) != S_OK)
502 /* show show node attributes */
505 if (format_tarval(pHelper, nBase, n.attr.con.tarval, name, sizeof(name)) != S_OK) {
506 _tcsncat(pResult, "<???>", max);
509 _tcsncat(pResult, "<", max);
510 _tcsncat(pResult, name, max);
511 _tcsncat(pResult, ">", max);
515 _tcsncat(pResult, "<", max);
516 switch (n.attr.symc.kind) {
517 case symconst_type_size:
518 _tcsncat(pResult, "SIZE:", max);
519 if (format_type(pHelper, nBase, n.attr.symc.sym.type_p, name, sizeof(name), 0) != S_OK)
521 _tcsncat(pResult, name, max);
523 case symconst_type_align:
524 _tcsncat(pResult, "ALGN:", max);
525 if (format_type(pHelper, nBase, n.attr.symc.sym.type_p, name, sizeof(name), 0) != S_OK)
527 _tcsncat(pResult, name, max);
529 case symconst_addr_ent:
530 _tcsncat(pResult, "ENT:", max);
531 if (format_entity(pHelper, nBase, n.attr.symc.sym.entity_p, name, sizeof(name), 0) != S_OK)
533 _tcsncat(pResult, name, max);
536 _tcsncat(pResult, ">", max);
539 _tcsncat(pResult, "<", max);
540 if (format_entity(pHelper, nBase, n.attr.sel.entity, name, sizeof(name), 0) != S_OK)
542 _tcsncat(pResult, name, max);
543 _tcsncat(pResult, ">", max);
546 _tcsncat(pResult, "<", max);
547 if (format_type(pHelper, nBase, n.attr.cast.type, name, sizeof(name), 0) != S_OK)
549 _tcsncat(pResult, name, max);
550 _tcsncat(pResult, ">", max);
553 _tcsncat(pResult, "<", max);
554 if (format_type(pHelper, nBase, n.attr.alloc.type, name, sizeof(name), 0) != S_OK)
556 _tcsncat(pResult, name, max);
557 _snprintf(name, sizeof(name), ", %s", n.attr.alloc.where == stack_alloc ? "stack" : "heap");
558 _tcsncat(pResult, name, max);
559 _tcsncat(pResult, ">", max);
562 _tcsncat(pResult, "<", max);
563 if (format_type(pHelper, nBase, n.attr.free.type, name, sizeof(name), 0) != S_OK)
565 _tcsncat(pResult, name, max);
566 _snprintf(name, sizeof(name), ", %s", n.attr.free.where == stack_alloc ? "stack" : "heap");
567 _tcsncat(pResult, name, max);
568 _tcsncat(pResult, ">", max);
571 _tcsncat(pResult, "<", max);
572 if (format_type(pHelper, nBase, n.attr.copyb.type, name, sizeof(name), 0) != S_OK)
574 _tcsncat(pResult, name, max);
575 _tcsncat(pResult, ">", max);
581 _snprintf(name, sizeof(name), " [0x%lx:0x%x]", n.node_nr, n.node_idx);
584 _snprintf(name, sizeof(name), " [0%lo:0%o]", n.node_nr, n.node_idx);
587 _snprintf(name, sizeof(name), " [%ld:%u]", n.node_nr, n.node_idx);
589 _tcsncat(pResult, name, max);
597 static HRESULT format_loop(DEBUGHELPER *pHelper, const void *addr, char *pResult, size_t max)
601 if (copy_from_debuggee(addr, pHelper, &loop, sizeof(loop)) != S_OK)
607 * Get an array descriptor
609 static HRESULT get_array_desc(DEBUGHELPER *pHelper, const void *address, ir_arr_descr *desc)
611 address = ARR_DESCR(address);
612 if (copy_from_debuggee(address, pHelper, desc, sizeof(*desc)) != S_OK)
616 } /* get_array_desc */
621 static HRESULT format_prog(DEBUGHELPER *pHelper, int nBase, const void *addr, char *pResult, size_t max)
624 ir_arr_descr graphs, types;
627 if (copy_from_debuggee(addr, pHelper, &irp, sizeof(irp)) != S_OK)
630 if (get_array_desc(pHelper, irp.graphs, &graphs) != S_OK)
633 irp.graphs = (ir_graph**)&graphs.v.elts;
637 if (get_array_desc(pHelper, irp.types, &types) != S_OK)
640 irp.types = (ir_type**)&types.v.elts;
645 _snprintf(name, sizeof(name), "0x%x graphs 0x%x types", ARR_LEN(irp.graphs), ARR_LEN(irp.types));
648 _snprintf(name, sizeof(name), "0%o graphs 0%o types", ARR_LEN(irp.graphs), ARR_LEN(irp.types));
651 _snprintf(name, sizeof(name), "%d graphs %d types", ARR_LEN(irp.graphs), ARR_LEN(irp.types));
653 _tcsncpy(pResult, name, max);
659 * Format an array descriptor
661 HRESULT format_arr_descr(DEBUGHELPER *pHelper, int nBase, const void *addr, char *pResult, size_t max)
666 if (copy_from_debuggee(addr, pHelper, &desc, sizeof(desc)) != S_OK)
669 switch (desc.magic) {
671 _tcsncpy(pResult, "DynArr ", max); break;
673 _tcsncpy(pResult, "AutoArr ", max); break;
675 _tcsncpy(pResult, "FlexArr ", max); break;
677 _tcsncpy(pResult, "UNKN ", max);
682 _snprintf(name, sizeof(name), "nelts 0x%x", desc.nelts);
685 _snprintf(name, sizeof(name), "nelts 0%o", desc.nelts);
688 _snprintf(name, sizeof(name), "nelts %d", desc.nelts);
690 _tcsncat(pResult, name, max);
693 } /* format_arr_descr */
696 * format a firm object
698 HRESULT FormatFirmObject(DEBUGHELPER *pHelper, int nBase, firm_kind kind, const void *addr, char *pResult, size_t max)
701 case k_entity: /* an entity */
702 return format_entity(pHelper, nBase, addr, pResult, max, 1);
703 case k_type: /* a type */
704 return format_type(pHelper, nBase, addr, pResult, max, 1);
705 case k_ir_graph: /* an ir graph */
706 return format_irg(pHelper, nBase, addr, pResult, max, 1);
707 case k_ir_node: /* an ir node */
708 return format_node(pHelper, nBase, addr, pResult, max, 1);
709 case k_ir_mode: /* an ir mode */
710 return format_mode(pHelper, addr, pResult, max);
711 case k_ir_op: /* an ir opcode */
712 return format_op(pHelper, addr, pResult, max);
713 case k_tarval: /* a tarval */
714 return format_tarval(pHelper, nBase, addr, pResult, max);
715 case k_ir_loop: /* a loop */
716 return format_loop(pHelper, addr, pResult, max);
717 case k_ir_prog: /* a program representation (irp) */
718 return format_prog(pHelper, nBase, addr, pResult, max);
722 } /* FormatFirmObject */
724 #define SEGMENT_SIZE_SHIFT 8
725 #define SEGMENT_SIZE (1 << SEGMENT_SIZE_SHIFT)
726 #define DIRECTORY_SIZE_SHIFT 8
727 #define DIRECTORY_SIZE (1 << DIRECTORY_SIZE_SHIFT)
728 #define MAX_LOAD_FACTOR 4
730 typedef struct pset_element {
731 struct pset_element *chain; /**< for chaining Elements */
733 } pset_Element, *pset_Segment;
735 /* not visible from outside */
737 unsigned p; /**< Next bucket to be split */
738 unsigned maxp; /**< upper bound on p during expansion */
739 unsigned nkey; /**< current # keys */
740 unsigned nseg; /**< current # segments */
741 pset_Segment *dir[DIRECTORY_SIZE];
742 int (*cmp)(); /**< function comparing entries */
743 unsigned iter_i, iter_j;
744 pset_Element *iter_tail; /**< non-NULL while iterating over elts */
745 pset_Element *free_list; /**< list of free Elements */
746 struct obstack obst; /**< obstack for allocation all data */
749 typedef struct set_element {
750 struct set_element *chain; /**< for chaining Elements */
752 } set_Element, *set_Segment;
754 /* not visible from outside */
756 unsigned p; /**< Next bucket to be split */
757 unsigned maxp; /**< upper bound on p during expansion */
758 unsigned nkey; /**< current # keys */
759 unsigned nseg; /**< current # segments */
760 set_Segment *dir[DIRECTORY_SIZE];
761 int (*cmp)(); /**< function comparing entries */
762 unsigned iter_i, iter_j;
763 set_Element *iter_tail; /**< non-NULL while iterating over elts */
764 struct obstack obst; /**< obstack for allocation all data */
768 * Find the longest chain of a pset
770 static HRESULT find_longest_pset_chain(DEBUGHELPER *pHelper, pset *set,
771 int *chains, int *lenght, size_t *size)
774 pset_Segment *seg, *curr;
777 int len, nchains = 0, max_len = 0;
780 for (i = 0; i < set->nseg; ++i) {
783 dyns += sizeof(seg[j]) * SEGMENT_SIZE;
784 for (j = 0; j < SEGMENT_SIZE; ++j) {
785 if (copy_from_debuggee(&seg[j], pHelper, &curr, sizeof(curr)) != S_OK)
791 for (len = 0; address != NULL; address = elem.chain) {
792 if (copy_from_debuggee(address, pHelper, &elem, sizeof(elem)) != S_OK)
794 dyns += sizeof(pset_Element);
806 } /* find_longest_pset_chain */
809 * Find the longest chain of a set
811 static HRESULT find_longest_set_chain(DEBUGHELPER *pHelper, set *set,
812 int *chains, int *lenght, size_t *size)
815 set_Segment *seg, *curr;
818 int len, nchains = 0, max_len = 0;
821 for (i = 0; i < set->nseg; ++i) {
824 dyns += sizeof(seg[j]) * SEGMENT_SIZE;
825 for (j = 0; j < SEGMENT_SIZE; ++j) {
826 if (copy_from_debuggee(&seg[j], pHelper, &curr, sizeof(curr)) != S_OK)
832 for (len = 0; address != NULL; address = elem.chain) {
833 if (copy_from_debuggee(address, pHelper, &elem, sizeof(elem)) != S_OK)
835 dyns += offsetof(set_Element, entry.dptr) + elem.entry.size;
847 } /* find_longest_set_chain */
852 HRESULT format_pset(DEBUGHELPER *pHelper, int nBase, const void *address, char *pResult, size_t max)
856 int nchains, chain_len;
859 if (copy_from_debuggee(address, pHelper, &set, sizeof(set)) != S_OK)
862 if (find_longest_pset_chain(pHelper, &set, &nchains, &chain_len, &size) != S_OK)
867 _snprintf(name, sizeof(name), "nkey 0x%x nseg 0x%x nchain 0x%x maxlen 0x%x size %u kB", set.nkey, set.nseg, nchains, chain_len, (size + 1023) >> 10);
870 _snprintf(name, sizeof(name), "nkey 0%o nseg 0%o nchain 0%o maxlen 0%o size %u kB", set.nkey, set.nseg, nchains, chain_len, (size + 1023) >> 10);
873 _snprintf(name, sizeof(name), "nkey %u nseg %d nchain %d maxlen %d size %u kB", set.nkey, set.nseg, nchains, chain_len, (size + 1023) >> 10);
875 _tcsncpy(pResult, name, max);
883 HRESULT format_set(DEBUGHELPER *pHelper, int nBase, const void *address, char *pResult, size_t max)
887 int nchains, chain_len;
890 if (copy_from_debuggee(address, pHelper, &set, sizeof(set)) != S_OK)
893 if (find_longest_set_chain(pHelper, &set, &nchains, &chain_len, &size) != S_OK)
898 _snprintf(name, sizeof(name), "nkey 0x%x nseg 0x%x nchain 0x%x maxlen 0x%x size %u kB", set.nkey, set.nseg, nchains, chain_len, (size + 1023) >> 10);
901 _snprintf(name, sizeof(name), "nkey 0%o nseg 0%o nchain 0%o maxlen 0%o size %u kB", set.nkey, set.nseg, nchains, chain_len, (size + 1023) >> 10);
904 _snprintf(name, sizeof(name), "nkey %u nseg %d nchain %d maxlen %d size %u kB", set.nkey, set.nseg, nchains, chain_len, (size + 1023) >> 10);
906 _tcsncpy(pResult, name, max);
912 unsigned magic; /**< debug magic, only available in DEBUG builds */
913 pdeq *l_end, *r_end; /**< left and right ends of the queue */
914 pdeq *l, *r; /**< left and right neighbor */
915 int n; /**< number of elements in the current chunk */
916 int p; /**< the read/write pointer */
917 const void *data[1]; /**< storage for elements */
920 /** Returns the length of a double ended pointer list. */
921 static int get_pdeq_len(DEBUGHELPER *pHelper, pdeq *dq)
930 if (copy_from_debuggee(q, pHelper, &pdeq, sizeof(pdeq)) != S_OK)
940 if (copy_from_debuggee(q, pHelper, &pdeq, sizeof(pdeq)) != S_OK)
951 HRESULT format_pdeq(DEBUGHELPER *pHelper, int nBase, const void *address, char *pResult, size_t max)
957 if (copy_from_debuggee(address, pHelper, &pdeq, sizeof(pdeq)) != S_OK)
960 len = get_pdeq_len(pHelper, &pdeq);
966 _snprintf(name, sizeof(name), "pdeq 0x%x elem", len);
969 _snprintf(name, sizeof(name), "pdeq 0%o elem", len);
972 _snprintf(name, sizeof(name), "pdeq %d elem", len);
974 _tcsncpy(pResult, name, max);
979 /** show the first 2 units */
980 static HRESULT fill_bits(DEBUGHELPER *pHelper, bitset_t *bs, char *pResult)
982 unsigned i, units = bs->size;
983 int l = 0, o = 0, breaked = 0;
986 for (i = 0; i < units; ++i) {
989 if (copy_from_debuggee((void *)(&bs->data[i]), pHelper, &data, sizeof(data)) != S_OK)
992 for (j = 0; j < 32; ++j) {
993 if (data & (1 << j)) {
994 sprintf(pResult + l, "%d,", i * sizeof(data) * 8 + j);
995 l += strlen(pResult + l);
1006 sprintf(pResult + l, "...");
1009 sprintf(pResult + l, "}");
1016 HRESULT format_bitset(DEBUGHELPER *pHelper, int nBase, const void *address, char *pResult, size_t max)
1022 if (copy_from_debuggee(address, pHelper, &bs, sizeof(bs)) != S_OK)
1027 _snprintf(name, sizeof(name), "bitset{0x%x:", bs.size);
1030 _snprintf(name, sizeof(name), "bitset{0%o:", bs.size);
1033 _snprintf(name, sizeof(name), "bitset{%u:", bs.size);
1037 if (fill_bits(pHelper, &bs, &name[l]) != S_OK)
1041 _tcsncpy(pResult, name, max);
1044 } /* format_bitset */