wineoss: Fix missing break statement.
[wine.git] / programs / winedbg / types.c
blobbf1276c6adb71f2efb8740af1b59b8e0e59e2bea
1 /*
2 * File types.c - datatype handling stuff for internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Note: This really doesn't do much at the moment, but it forms the framework
21 * upon which full support for datatype handling will eventually be built.
24 #include <stdlib.h>
26 #include "debugger.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
31 /******************************************************************
32 * types_get_real_type
34 * Get rid of any potential typedef in the lvalue's type to get
35 * to the 'real' type (the one we can work upon).
37 BOOL types_get_real_type(struct dbg_type* type, DWORD* tag)
39 if (type->id == dbg_itype_none) return FALSE;
42 if (!types_get_info(type, TI_GET_SYMTAG, tag))
43 return FALSE;
44 if (*tag != SymTagTypedef) return TRUE;
45 } while (types_get_info(type, TI_GET_TYPE, &type->id));
46 return FALSE;
49 /******************************************************************
50 * types_extract_as_lgint
52 * Given a lvalue, try to get an integral (or pointer/address) value
53 * out of it
55 dbg_lgint_t types_extract_as_lgint(const struct dbg_lvalue* lvalue,
56 unsigned* psize, BOOL *issigned)
58 dbg_lgint_t rtn = 0;
59 DWORD tag, bt;
60 DWORD64 size;
61 struct dbg_type type = lvalue->type;
62 BOOL s = FALSE;
64 if (!types_get_real_type(&type, &tag))
65 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
67 if (type.id == dbg_itype_segptr)
69 return (LONG_PTR)memory_to_linear_addr(&lvalue->addr);
71 if (tag != SymTagBaseType && lvalue->bitlen) dbg_printf("Unexpected bitfield on tag %ld\n", tag);
73 if (psize) *psize = 0;
74 if (issigned) *issigned = FALSE;
75 switch (tag)
77 case SymTagBaseType:
78 if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
79 !types_get_info(&type, TI_GET_BASETYPE, &bt))
81 WINE_ERR("Couldn't get information\n");
82 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
83 return rtn;
85 if (size > sizeof(rtn))
87 WINE_ERR("Size too large (%I64x)\n", size);
88 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
89 return rtn;
91 switch (bt)
93 case btChar:
94 case btWChar:
95 case btBool:
96 case btInt:
97 case btLong:
98 if (!memory_fetch_integer(lvalue, (unsigned)size, s = TRUE, &rtn))
99 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
100 break;
101 case btUInt:
102 case btULong:
103 if (!memory_fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn))
104 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
105 break;
106 case btFloat:
107 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
109 if (psize) *psize = (unsigned)size;
110 if (issigned) *issigned = s;
111 break;
112 case SymTagPointerType:
113 if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
114 !memory_fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn))
115 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
116 break;
117 case SymTagArrayType:
118 case SymTagUDT:
119 if (!memory_fetch_integer(lvalue, sizeof(unsigned), s = FALSE, &rtn))
120 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
121 break;
122 case SymTagEnum:
123 if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
124 !memory_fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn))
125 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
126 break;
127 case SymTagFunctionType:
128 rtn = (ULONG_PTR)memory_to_linear_addr(&lvalue->addr);
129 break;
130 default:
131 WINE_FIXME("Unsupported tag %lu\n", tag);
132 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
135 return rtn;
138 /******************************************************************
139 * types_extract_as_integer
141 * Given a lvalue, try to get an integral (or pointer/address) value
142 * out of it
144 dbg_lgint_t types_extract_as_integer(const struct dbg_lvalue* lvalue)
146 return types_extract_as_lgint(lvalue, NULL, NULL);
149 /******************************************************************
150 * types_extract_as_address
154 void types_extract_as_address(const struct dbg_lvalue* lvalue, ADDRESS64* addr)
156 if (lvalue->type.id == dbg_itype_segptr && lvalue->type.module == 0)
158 *addr = lvalue->addr;
160 else
162 addr->Mode = AddrModeFlat;
163 addr->Offset = types_extract_as_lgint(lvalue, NULL, NULL);
167 BOOL types_store_value(struct dbg_lvalue* lvalue_to, const struct dbg_lvalue* lvalue_from)
169 if (!lvalue_to->bitlen && !lvalue_from->bitlen)
171 BOOL equal;
172 if (!types_compare(lvalue_to->type, lvalue_from->type, &equal)) return FALSE;
173 if (equal)
174 return memory_transfer_value(lvalue_to, lvalue_from);
175 if (types_is_float_type(lvalue_from) && types_is_float_type(lvalue_to))
177 double d;
178 return memory_fetch_float(lvalue_from, &d) &&
179 memory_store_float(lvalue_to, &d);
182 if (types_is_integral_type(lvalue_from) && types_is_integral_type(lvalue_to))
184 /* doing integer conversion (about sign, size) */
185 dbg_lgint_t val = types_extract_as_integer(lvalue_from);
186 return memory_store_integer(lvalue_to, val);
188 dbg_printf("Cannot assign (different types)\n"); return FALSE;
189 return FALSE;
192 /******************************************************************
193 * types_get_udt_element_lvalue
195 * Implement a structure derefencement
197 static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, const struct dbg_type* type)
199 DWORD offset, bitoffset;
200 DWORD64 length;
202 types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
203 lvalue->type.module = type->module;
204 if (!types_get_info(type, TI_GET_OFFSET, &offset)) return FALSE;
205 lvalue->addr.Offset += offset;
207 if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset))
209 types_get_info(type, TI_GET_LENGTH, &length);
210 lvalue->bitlen = length;
211 lvalue->bitstart = bitoffset;
212 if (lvalue->bitlen != length || lvalue->bitstart != bitoffset)
214 dbg_printf("too wide bitfields\n"); /* shouldn't happen */
215 return FALSE;
218 else
219 lvalue->bitlen = lvalue->bitstart = 0;
221 return TRUE;
224 /******************************************************************
225 * types_udt_find_element
228 BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name)
230 DWORD tag, count;
231 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
232 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
233 WCHAR* ptr;
234 char tmp[256];
235 struct dbg_type type;
237 if (!types_get_real_type(&lvalue->type, &tag) || tag != SymTagUDT)
238 return FALSE;
240 if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
242 fcp->Start = 0;
243 while (count)
245 fcp->Count = min(count, 256);
246 if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
248 unsigned i;
249 type.module = lvalue->type.module;
250 for (i = 0; i < min(fcp->Count, count); i++)
252 type.id = fcp->ChildId[i];
253 if (types_get_info(&type, TI_GET_SYMNAME, &ptr) && ptr)
255 WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
256 HeapFree(GetProcessHeap(), 0, ptr);
257 if (!strcmp(tmp, name))
258 return types_get_udt_element_lvalue(lvalue, &type);
262 count -= min(count, 256);
263 fcp->Start += 256;
266 return FALSE;
269 /******************************************************************
270 * types_array_index
272 * Grab an element from an array
274 BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lvalue* result)
276 struct dbg_type type = lvalue->type;
277 DWORD tag, count;
279 memset(result, 0, sizeof(*result));
280 result->type.id = dbg_itype_none;
281 result->type.module = 0;
283 if (!types_get_real_type(&type, &tag)) return FALSE;
284 switch (tag)
286 case SymTagArrayType:
287 if (!types_get_info(&type, TI_GET_COUNT, &count)) return FALSE;
288 if (index < 0 || index >= count) return FALSE;
289 result->addr = lvalue->addr;
290 break;
291 case SymTagPointerType:
292 if (!memory_read_value(lvalue, dbg_curr_process->be_cpu->pointer_size, &result->addr.Offset))
293 return FALSE;
294 result->addr.Mode = AddrModeFlat;
295 switch (dbg_curr_process->be_cpu->pointer_size)
297 case 4: result->addr.Offset = (DWORD)result->addr.Offset; break;
298 case 8: break;
299 default: assert(0);
301 break;
302 default:
303 FIXME("unexpected tag %lx\n", tag);
304 return FALSE;
307 * Get the base type, so we know how much to index by.
309 if (!types_get_info(&type, TI_GET_TYPE, &result->type.id)) return FALSE;
310 result->type.module = type.module;
311 if (index)
313 DWORD64 length;
314 if (!types_get_info(&result->type, TI_GET_LENGTH, &length)) return FALSE;
315 result->addr.Offset += index * (DWORD)length;
317 /* FIXME: the following statement is not always true (and can lead to buggy behavior).
318 * There is no way to tell where the deref:ed value is...
319 * For example:
320 * x is a pointer to struct s, x being on the stack
321 * => lvalue is in debuggee, result is in debugger
322 * x is a pointer to struct s, x being optimized into a reg
323 * => lvalue is debugger, result is debuggee
324 * x is a pointer to internal variable x
325 * => lvalue is debugger, result is debuggee
326 * So we always force debuggee address space, because dereferencing pointers to
327 * internal variables is very unlikely. A correct fix would be
328 * rather large.
330 result->in_debuggee = 1;
331 return TRUE;
334 struct type_find_t
336 enum SymTagEnum tag; /* in: the tag to look for */
337 struct dbg_type type; /* out: the type found */
338 ULONG ptr_typeid; /* in: when tag is SymTagPointerType */
341 static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
343 struct type_find_t* user = _user;
344 BOOL ret = TRUE;
345 struct dbg_type type;
346 DWORD type_id;
348 if (sym->Tag == user->tag)
350 switch (user->tag)
352 case SymTagUDT:
353 case SymTagEnum:
354 case SymTagTypedef:
355 user->type.module = sym->ModBase;
356 user->type.id = sym->TypeIndex;
357 ret = FALSE;
358 break;
359 case SymTagPointerType:
360 type.module = sym->ModBase;
361 type.id = sym->TypeIndex;
362 if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->ptr_typeid)
364 user->type = type;
365 ret = FALSE;
367 break;
368 default: break;
371 return ret;
374 /******************************************************************
375 * types_find_pointer
377 * Should look up in module based at linear whether (typeid*) exists
378 * Otherwise, we could create it locally
380 BOOL types_find_pointer(const struct dbg_type* type, struct dbg_type* outtype)
382 struct type_find_t f;
384 f.type.id = dbg_itype_none;
385 f.tag = SymTagPointerType;
386 f.ptr_typeid = type->id;
387 if (!SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f) || f.type.id == dbg_itype_none)
388 return FALSE;
389 *outtype = f.type;
390 return TRUE;
393 /******************************************************************
394 * types_find_type
396 * Should look up in the module based at linear address whether a type
397 * named 'name' and with the correct tag exists
399 BOOL types_find_type(const char* name, enum SymTagEnum tag, struct dbg_type* outtype)
401 struct type_find_t f;
402 char* str = NULL;
403 BOOL ret;
405 if (!strchr(name, '!')) /* no module, lookup across all modules */
407 str = malloc(strlen(name) + 3);
408 if (!str) return FALSE;
409 str[0] = '*';
410 str[1] = '!';
411 strcpy(str + 2, name);
412 name = str;
414 f.type.id = dbg_itype_none;
415 f.tag = tag;
416 ret = SymEnumTypesByName(dbg_curr_process->handle, 0, name, types_cb, &f);
417 free(str);
418 if (!ret || f.type.id == dbg_itype_none)
419 return FALSE;
420 *outtype = f.type;
421 return TRUE;
424 /***********************************************************************
425 * print_value
427 * Implementation of the 'print' command.
429 void print_value(const struct dbg_lvalue* lvalue, char format, int level)
431 struct dbg_type type = lvalue->type;
432 struct dbg_lvalue lvalue_field;
433 int i;
434 DWORD tag;
435 DWORD count;
436 DWORD64 size;
438 if (!types_get_real_type(&type, &tag))
440 WINE_FIXME("---error\n");
441 return;
444 if (type.id == dbg_itype_none)
446 /* No type, just print the addr value */
447 print_bare_address(&lvalue->addr);
448 goto leave;
451 if (format == 'i' || format == 's' || format == 'w' || format == 'b' || format == 'g')
453 dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
454 format = '\0';
457 switch (tag)
459 case SymTagBaseType:
460 case SymTagEnum:
461 case SymTagPointerType:
462 /* FIXME: this in not 100% optimal (as we're going through the typedef handling
463 * stuff again
465 print_basic(lvalue, format);
466 break;
467 case SymTagUDT:
468 if (types_get_info(&type, TI_GET_CHILDRENCOUNT, &count))
470 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
471 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
472 WCHAR* ptr;
473 struct dbg_type sub_type;
475 dbg_printf("{");
476 fcp->Start = 0;
477 while (count)
479 fcp->Count = min(count, 256);
480 if (types_get_info(&type, TI_FINDCHILDREN, fcp))
482 for (i = 0; i < min(fcp->Count, count); i++)
484 sub_type.module = type.module;
485 sub_type.id = fcp->ChildId[i];
486 if (!types_get_info(&sub_type, TI_GET_SYMNAME, &ptr) || !ptr) continue;
487 dbg_printf("%ls=", ptr);
488 HeapFree(GetProcessHeap(), 0, ptr);
489 lvalue_field = *lvalue;
490 if (types_get_udt_element_lvalue(&lvalue_field, &sub_type))
492 print_value(&lvalue_field, format, level + 1);
494 if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
497 count -= min(count, 256);
498 fcp->Start += 256;
500 dbg_printf("}");
502 break;
503 case SymTagArrayType:
505 * Loop over all of the entries, printing stuff as we go.
507 count = 1; size = 1;
508 types_get_info(&type, TI_GET_COUNT, &count);
509 types_get_info(&type, TI_GET_LENGTH, &size);
510 lvalue_field = *lvalue;
511 types_get_info(&lvalue_field.type, TI_GET_TYPE, &lvalue_field.type.id);
512 types_get_real_type(&lvalue_field.type, &tag);
514 if (size == count && tag == SymTagBaseType)
516 DWORD basetype;
518 types_get_info(&lvalue_field.type, TI_GET_BASETYPE, &basetype);
519 if (basetype == btChar)
521 char buffer[256];
523 * Special handling for character arrays.
525 unsigned len = min(count, sizeof(buffer));
526 memory_get_string(dbg_curr_process,
527 memory_to_linear_addr(&lvalue->addr),
528 lvalue->in_debuggee, TRUE, buffer, len);
529 dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
530 break;
533 dbg_printf("{");
534 for (i = 0; i < count; i++)
536 print_value(&lvalue_field, format, level + 1);
537 lvalue_field.addr.Offset += size / count;
538 dbg_printf((i == count - 1) ? "}" : ", ");
540 break;
541 case SymTagFunctionType:
542 dbg_printf("Function ");
543 print_bare_address(&lvalue->addr);
544 dbg_printf(": ");
545 types_print_type(&type, FALSE);
546 break;
547 case SymTagTypedef:
548 lvalue_field = *lvalue;
549 types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
550 print_value(&lvalue_field, format, level);
551 break;
552 default:
553 WINE_FIXME("Unknown tag (%lu)\n", tag);
554 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
555 break;
558 leave:
560 if (level == 0) dbg_printf("\n");
563 static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx)
565 struct dbg_type type;
566 type.module = sym->ModBase;
567 type.id = sym->TypeIndex;
568 dbg_printf("Mod: %0*Ix ID: %08lx\n", ADDRWIDTH, type.module, type.id);
569 types_print_type(&type, TRUE);
570 dbg_printf("\n");
571 return TRUE;
574 static BOOL CALLBACK print_types_mod_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
576 return SymEnumTypes(dbg_curr_process->handle, base, print_types_cb, ctx);
579 BOOL print_types(void)
581 if (!dbg_curr_process)
583 dbg_printf("No known process, cannot print types\n");
584 return FALSE;
586 SymEnumerateModules64(dbg_curr_process->handle, print_types_mod_cb, NULL);
587 return FALSE;
590 BOOL types_print_type(const struct dbg_type* type, BOOL details)
592 WCHAR* ptr;
593 const WCHAR* name;
594 DWORD tag, udt, count, bitoffset, bt;
595 DWORD64 bitlen;
596 struct dbg_type subtype;
598 if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
600 dbg_printf("--invalid--<%lxh>--", type->id);
601 return FALSE;
604 name = (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr) ? ptr : L"--none--";
606 switch (tag)
608 case SymTagBaseType:
609 dbg_printf("%ls", name);
610 if (details && types_get_info(type, TI_GET_LENGTH, &bitlen) && types_get_info(type, TI_GET_BASETYPE, &bt))
612 const char* longness = "";
613 if (bt == btLong || bt == btULong) longness = " long";
614 dbg_printf(": size=%I64d%s", bitlen, longness);
616 break;
617 case SymTagPointerType:
618 types_get_info(type, TI_GET_TYPE, &subtype.id);
619 subtype.module = type->module;
620 types_print_type(&subtype, FALSE);
621 dbg_printf("*");
622 break;
623 case SymTagUDT:
624 types_get_info(type, TI_GET_UDTKIND, &udt);
625 switch (udt)
627 case UdtStruct: dbg_printf("struct %ls", name); break;
628 case UdtUnion: dbg_printf("union %ls", name); break;
629 case UdtClass: dbg_printf("class %ls", name); break;
630 default: WINE_ERR("Unsupported UDT type (%ld) for %ls\n", udt, name); break;
632 if (details &&
633 types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
635 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
636 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
637 WCHAR* ptr;
638 int i;
639 struct dbg_type type_elt;
640 dbg_printf(" {");
642 fcp->Start = 0;
643 while (count)
645 fcp->Count = min(count, 256);
646 if (types_get_info(type, TI_FINDCHILDREN, fcp))
648 for (i = 0; i < min(fcp->Count, count); i++)
650 type_elt.module = type->module;
651 type_elt.id = fcp->ChildId[i];
652 if (!types_get_info(&type_elt, TI_GET_SYMNAME, &ptr) || !ptr) continue;
653 if (!types_get_info(&type_elt, TI_GET_BITPOSITION, &bitoffset) ||
654 !types_get_info(&type_elt, TI_GET_LENGTH, &bitlen))
655 bitlen = ~(DWORD64)0;
656 if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
658 /* print details of embedded UDT:s */
659 types_print_type(&type_elt, types_get_info(&type_elt, TI_GET_UDTKIND, &udt));
661 else dbg_printf("<unknown>");
662 dbg_printf(" %ls", ptr);
663 HeapFree(GetProcessHeap(), 0, ptr);
664 if (bitlen != ~(DWORD64)0)
665 dbg_printf(" : %I64u", bitlen);
666 dbg_printf(";");
667 if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(" ");
670 count -= min(count, 256);
671 fcp->Start += 256;
673 dbg_printf("}");
675 break;
676 case SymTagArrayType:
677 types_get_info(type, TI_GET_TYPE, &subtype.id);
678 subtype.module = type->module;
679 types_print_type(&subtype, FALSE);
680 if (types_get_info(type, TI_GET_COUNT, &count))
681 dbg_printf(" %ls[%ld]", name, count);
682 else
683 dbg_printf(" %ls[]", name);
684 break;
685 case SymTagEnum:
686 dbg_printf("enum %ls", name);
687 if (details &&
688 types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
690 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
691 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
692 WCHAR* ptr;
693 int i;
694 struct dbg_type type_elt;
695 VARIANT variant;
697 dbg_printf(" {");
699 fcp->Start = 0;
700 while (count)
702 fcp->Count = min(count, 256);
703 if (types_get_info(type, TI_FINDCHILDREN, fcp))
705 for (i = 0; i < min(fcp->Count, count); i++)
707 type_elt.module = type->module;
708 type_elt.id = fcp->ChildId[i];
709 if (!types_get_info(&type_elt, TI_GET_SYMNAME, &ptr) || !ptr) continue;
710 if (!types_get_info(&type_elt, TI_GET_VALUE, &variant) || !ptr) continue;
711 dbg_printf("%ls = ", ptr);
712 switch (V_VT(&variant))
714 case VT_I1: dbg_printf("%d", V_I1(&variant)); break;
715 case VT_I2: dbg_printf("%d", V_I2(&variant)); break;
716 case VT_I4: dbg_printf("%ld", V_I4(&variant)); break;
717 case VT_I8: dbg_printf("%I64d", V_I8(&variant)); break;
718 case VT_UI1: dbg_printf("%u", V_UI1(&variant)); break;
719 case VT_UI2: dbg_printf("%u", V_UI2(&variant)); break;
720 case VT_UI4: dbg_printf("%lu", V_UI4(&variant)); break;
721 case VT_UI8: dbg_printf("%I64u", V_UI8(&variant)); break;
723 HeapFree(GetProcessHeap(), 0, ptr);
724 if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
727 count -= min(count, 256);
728 fcp->Start += 256;
730 dbg_printf("}");
732 break;
733 case SymTagFunctionType:
734 types_get_info(type, TI_GET_TYPE, &subtype.id);
735 /* is the returned type the same object as function sig itself ? */
736 if (subtype.id != type->id)
738 subtype.module = type->module;
739 types_print_type(&subtype, FALSE);
741 else
743 subtype.module = 0;
744 dbg_printf("<ret_type=self>");
746 dbg_printf(" (*%ls)(", name);
747 if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
749 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
750 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
751 int i;
753 fcp->Start = 0;
754 if (!count) dbg_printf("void");
755 else while (count)
757 fcp->Count = min(count, 256);
758 if (types_get_info(type, TI_FINDCHILDREN, fcp))
760 for (i = 0; i < min(fcp->Count, count); i++)
762 subtype.id = fcp->ChildId[i];
763 types_get_info(&subtype, TI_GET_TYPE, &subtype.id);
764 types_print_type(&subtype, FALSE);
765 if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
768 count -= min(count, 256);
769 fcp->Start += 256;
772 dbg_printf(")");
773 break;
774 case SymTagTypedef:
775 if (details && types_get_info(type, TI_GET_TYPE, &subtype.id))
777 dbg_printf("typedef %ls => ", name);
778 subtype.module = type->module;
779 types_print_type(&subtype, FALSE);
781 else dbg_printf("%ls", name);
782 break;
783 default:
784 WINE_ERR("Unknown type %lu for %ls\n", tag, name);
785 break;
788 HeapFree(GetProcessHeap(), 0, ptr);
789 return TRUE;
792 /* order here must match order in enum dbg_internal_type */
793 static struct
795 unsigned char base_type;
796 unsigned char byte_size;
798 basic_types_details[] =
800 {btVoid, 0},
801 {btBool, 1},
802 /* chars */
803 {btChar, 1},
804 {btWChar, 2},
805 {btChar8, 1},
806 {btChar16, 2},
807 {btChar32, 4},
808 /* unsigned integers */
809 {btUInt, 1},
810 {btUInt, 2},
811 {btUInt, 4},
812 {btUInt, 8},
813 {btUInt, 16},
814 {btULong, 4},
815 {btULong, 8},
816 /* signed integers */
817 {btInt, 1},
818 {btInt, 2},
819 {btInt, 4},
820 {btInt, 8},
821 {btInt, 16},
822 {btLong, 4},
823 {btLong, 8},
824 /* floats */
825 {btFloat, 4},
826 {btFloat, 8},
827 {btFloat, 10},
830 C_ASSERT(ARRAY_SIZE(basic_types_details) == dbg_itype_last - dbg_itype_first);
832 const struct data_model ilp32_data_model[] =
834 {dbg_itype_void, L"void"},
836 {dbg_itype_bool, L"bool"},
838 {dbg_itype_char, L"char"},
839 {dbg_itype_wchar, L"WCHAR"},
840 {dbg_itype_char8, L"char8_t"},
841 {dbg_itype_char16, L"char16_t"},
842 {dbg_itype_char32, L"char32_t"},
844 {dbg_itype_unsigned_int8, L"unsigned char"},
845 {dbg_itype_unsigned_int16, L"unsigned short int"},
846 {dbg_itype_unsigned_int32, L"unsigned int"},
847 {dbg_itype_unsigned_int64, L"unsigned long long int"},
848 {dbg_itype_unsigned_int64, L"unsigned __int64"},
849 {dbg_itype_unsigned_long32, L"unsigned long int"},
851 {dbg_itype_signed_int8, L"signed char"},
852 {dbg_itype_signed_int16, L"short int"},
853 {dbg_itype_signed_int32, L"int"},
854 {dbg_itype_signed_int64, L"long long int"},
855 {dbg_itype_signed_int64, L"__int64"},
856 {dbg_itype_signed_long32, L"long int"},
858 {dbg_itype_short_real, L"float"},
859 {dbg_itype_real, L"double"},
860 {dbg_itype_long_real, L"long double"},
862 {0, NULL}
865 const struct data_model llp64_data_model[] =
867 {dbg_itype_void, L"void"},
869 {dbg_itype_bool, L"bool"},
871 {dbg_itype_char, L"char"},
872 {dbg_itype_wchar, L"WCHAR"},
873 {dbg_itype_char8, L"char8_t"},
874 {dbg_itype_char16, L"char16_t"},
875 {dbg_itype_char32, L"char32_t"},
877 {dbg_itype_unsigned_int8, L"unsigned char"},
878 {dbg_itype_unsigned_int16, L"unsigned short int"},
879 {dbg_itype_unsigned_int32, L"unsigned int"},
880 {dbg_itype_unsigned_int64, L"unsigned long long int"},
881 {dbg_itype_unsigned_int64, L"unsigned __int64"},
882 {dbg_itype_unsigned_int128, L"unsigned __int128"},
884 {dbg_itype_unsigned_long32, L"unsigned long int"},
886 {dbg_itype_signed_int8, L"signed char"},
887 {dbg_itype_signed_int16, L"short int"},
888 {dbg_itype_signed_int32, L"int"},
889 {dbg_itype_signed_int64, L"long long int"},
890 {dbg_itype_signed_int64, L"__int64"},
891 {dbg_itype_signed_int128, L"__int128"},
892 {dbg_itype_signed_long32, L"long int"},
894 {dbg_itype_short_real, L"float"},
895 {dbg_itype_real, L"double"},
896 {dbg_itype_long_real, L"long double"},
898 {0, NULL}
901 const struct data_model lp64_data_model[] =
903 {dbg_itype_void, L"void"},
905 {dbg_itype_bool, L"bool"},
907 {dbg_itype_char, L"char"},
908 {dbg_itype_wchar, L"WCHAR"},
909 {dbg_itype_char8, L"char8_t"},
910 {dbg_itype_char16, L"char16_t"},
911 {dbg_itype_char32, L"char32_t"},
913 {dbg_itype_unsigned_int8, L"unsigned char"},
914 {dbg_itype_unsigned_int16, L"unsigned short int"},
915 {dbg_itype_unsigned_int32, L"unsigned int"},
916 {dbg_itype_unsigned_int64, L"unsigned long long int"},
917 {dbg_itype_unsigned_int64, L"unsigned __int64"},
918 {dbg_itype_unsigned_int128, L"unsigned __int128"},
919 {dbg_itype_unsigned_long64, L"unsigned long int"}, /* we can't discriminate 'unsigned long' from 'unsigned long long' (on output) */
921 {dbg_itype_signed_int8, L"signed char"},
922 {dbg_itype_signed_int16, L"short int"},
923 {dbg_itype_signed_int32, L"int"},
924 {dbg_itype_signed_int64, L"long long int"},
925 {dbg_itype_signed_int64, L"__int64"},
926 {dbg_itype_signed_int128, L"__int128"},
927 {dbg_itype_signed_long64, L"long int"}, /* we can't discriminate 'long' from 'long long' (on output)*/
929 {dbg_itype_short_real, L"float"},
930 {dbg_itype_real, L"double"},
931 {dbg_itype_long_real, L"long double"},
933 {0, NULL}
936 static const struct data_model* get_data_model(DWORD64 modaddr)
938 const struct data_model *model;
940 if (dbg_curr_process->data_model)
941 model = dbg_curr_process->data_model;
942 else if (ADDRSIZE == 4) model = ilp32_data_model;
943 else
945 IMAGEHLP_MODULEW64 mi;
946 DWORD opt = SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, TRUE);
948 mi.SizeOfStruct = sizeof(mi);
949 if (SymGetModuleInfoW64(dbg_curr_process->handle, modaddr, &mi) &&
950 (wcsstr(mi.ModuleName, L".so") || wcsstr(mi.ModuleName, L"<")))
951 model = lp64_data_model;
952 else
953 model = llp64_data_model;
954 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
956 return model;
959 struct mod_by_name
961 const char* modname;
962 ULONG64 base;
965 static BOOL CALLBACK enum_mod_cb(const char* module, DWORD64 base, void* user)
967 struct mod_by_name* mbn = user;
968 if (!mbn->modname) /* lookup data model from main module */
970 IMAGEHLP_MODULE64 mi;
971 mi.SizeOfStruct = sizeof(mi);
972 if (SymGetModuleInfo64(dbg_curr_process->handle, base, &mi))
974 size_t len = strlen(mi.ImageName);
975 if (len >= 4 && !strcmp(mi.ImageName + len - 4, ".exe"))
977 mbn->base = base;
978 return FALSE;
982 else if (SymMatchStringA(module, mbn->modname, FALSE))
984 mbn->base = base;
985 return FALSE;
987 return TRUE;
990 BOOL types_find_basic(const WCHAR* name, const char* mod, struct dbg_type* type)
992 const struct data_model* model;
993 struct mod_by_name mbn = {mod, 0};
994 DWORD opt;
995 BOOL ret;
997 opt = SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, TRUE);
998 ret = SymEnumerateModules64(dbg_curr_process->handle, enum_mod_cb, &mbn);
999 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
1000 if (!ret || mbn.base == 0)
1001 return FALSE;
1002 model = get_data_model(mbn.base);
1003 for (; model->name; model++)
1005 if (!wcscmp(name, model->name))
1007 type->module = 0;
1008 type->id = model->itype;
1009 return TRUE;
1012 return FALSE;
1015 static BOOL lookup_base_type_in_data_model(DWORD64 module, unsigned bt, unsigned len, WCHAR** pname)
1017 const WCHAR* name = NULL;
1018 WCHAR tmp[64];
1019 const struct data_model* model;
1021 model = get_data_model(module);
1022 for (; model->name; model++)
1024 if (model->itype >= dbg_itype_first && model->itype < dbg_itype_last &&
1025 bt == basic_types_details[model->itype - dbg_itype_first].base_type &&
1026 len == basic_types_details[model->itype - dbg_itype_first].byte_size)
1028 name = model->name;
1029 break;
1032 if (!name) /* synthetize name */
1034 WINE_FIXME("Unsupported basic type %u %u\n", bt, len);
1035 swprintf(tmp, ARRAY_SIZE(tmp), L"bt[%u,%u]", bt, len);
1036 name = tmp;
1038 *pname = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name) + 1) * sizeof(WCHAR));
1039 if (!*pname) return FALSE;
1040 lstrcpyW(*pname, name);
1041 return TRUE;
1044 /* helper to typecast pInfo to its expected type (_t) */
1045 #define X(_t) (*((_t*)pInfo))
1047 BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
1049 if (type->id == dbg_itype_none) return FALSE;
1050 if (type->module != 0)
1052 if (ti == TI_GET_SYMNAME)
1054 DWORD tag, bt;
1055 DWORD64 len;
1056 WCHAR* name;
1057 if (SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_SYMTAG, &tag) &&
1058 tag == SymTagBaseType &&
1059 SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_BASETYPE, &bt) &&
1060 SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_LENGTH, &len) &&
1061 len == (DWORD)len)
1063 if (!lookup_base_type_in_data_model(type->module, bt, len, &name)) return FALSE;
1064 X(WCHAR*) = name;
1065 return TRUE;
1068 return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
1071 assert(type->id >= dbg_itype_first);
1073 if (type->id >= dbg_itype_first && type->id < dbg_itype_last)
1075 switch (ti)
1077 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
1078 case TI_GET_LENGTH: X(DWORD64) = basic_types_details[type->id - dbg_itype_first].byte_size; break;
1079 case TI_GET_BASETYPE: X(DWORD) = basic_types_details[type->id - dbg_itype_first].base_type; break;
1080 case TI_GET_SYMNAME: return lookup_base_type_in_data_model(0, basic_types_details[type->id - dbg_itype_first].base_type,
1081 basic_types_details[type->id - dbg_itype_first].byte_size, &X(WCHAR*));
1082 default: WINE_FIXME("unsupported %u for itype %#lx\n", ti, type->id); return FALSE;
1084 return TRUE;
1086 switch (type->id)
1088 case dbg_itype_lguint:
1089 switch (ti)
1091 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
1092 case TI_GET_LENGTH: X(DWORD64) = sizeof(dbg_lguint_t); break;
1093 case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
1094 default: WINE_FIXME("unsupported %u for lguint_t\n", ti); return FALSE;
1096 break;
1097 case dbg_itype_lgint:
1098 switch (ti)
1100 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
1101 case TI_GET_LENGTH: X(DWORD64) = sizeof(dbg_lgint_t); break;
1102 case TI_GET_BASETYPE: X(DWORD) = btInt; break;
1103 default: WINE_FIXME("unsupported %u for lgint_t\n", ti); return FALSE;
1105 break;
1106 case dbg_itype_astring:
1107 switch (ti)
1109 case TI_GET_SYMTAG: X(DWORD) = SymTagPointerType; break;
1110 case TI_GET_LENGTH: X(DWORD64) = ADDRSIZE; break;
1111 case TI_GET_TYPE: X(DWORD) = dbg_itype_char; break;
1112 default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
1114 break;
1115 case dbg_itype_segptr:
1116 switch (ti)
1118 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
1119 case TI_GET_LENGTH: X(DWORD64) = 4; break;
1120 case TI_GET_BASETYPE: X(DWORD) = btInt; break;
1121 default: WINE_FIXME("unsupported %u for seg-ptr\n", ti); return FALSE;
1123 break;
1124 case dbg_itype_m128a:
1125 switch (ti)
1127 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
1128 case TI_GET_LENGTH: X(DWORD64) = 16; break;
1129 case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
1130 default: WINE_FIXME("unsupported %u for XMM register\n", ti); return FALSE;
1132 break;
1133 default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
1136 #undef X
1137 return TRUE;
1140 static BOOL types_compare_name(struct dbg_type type1, struct dbg_type type2, BOOL* equal)
1142 LPWSTR name1, name2;
1143 BOOL ret;
1145 if (types_get_info(&type1, TI_GET_SYMNAME, &name1))
1147 if (types_get_info(&type2, TI_GET_SYMNAME, &name2))
1149 *equal = !wcscmp(name1, name2);
1150 ret = TRUE;
1151 HeapFree(GetProcessHeap(), 0, name2);
1153 else ret = FALSE;
1154 HeapFree(GetProcessHeap(), 0, name1);
1156 else ret = FALSE;
1157 return ret;
1160 static BOOL types_compare_children(struct dbg_type type1, struct dbg_type type2, BOOL* equal, DWORD tag)
1162 DWORD count1, count2, i;
1163 DWORD* children;
1164 BOOL ret;
1166 if (!types_get_info(&type1, TI_GET_CHILDRENCOUNT, &count1) ||
1167 !types_get_info(&type2, TI_GET_CHILDRENCOUNT, &count2)) return FALSE;
1168 if (count1 != count2) {*equal = FALSE; return TRUE;}
1169 if (!count1) return *equal = TRUE;
1170 if ((children = malloc(sizeof(*children) * 2 * count1)) == NULL) return FALSE;
1171 if (types_get_info(&type1, TI_FINDCHILDREN, &children[0]) &&
1172 types_get_info(&type2, TI_FINDCHILDREN, &children[count1]))
1174 for (i = 0; i < count1; ++i)
1176 type1.id = children[i];
1177 type2.id = children[count1 + i];
1178 switch (tag)
1180 case SymTagFunctionType: ret = types_compare(type1, type2, equal); break;
1181 case SymTagUDT:
1182 /* each child is a SymTagData that describes the member */
1183 ret = types_compare_name(type1, type2, equal);
1184 if (ret && *equal)
1186 /* compare type of member */
1187 ret = types_get_info(&type1, TI_GET_TYPE, &type1.id) &&
1188 types_get_info(&type2, TI_GET_TYPE, &type2.id);
1189 if (ret) ret = types_compare(type1, type2, equal);
1190 /* FIXME should compare bitfield info when present */
1192 break;
1193 default: ret = FALSE; break;
1195 if (!ret || !*equal) break;
1197 if (i == count1) ret = *equal = TRUE;
1199 else ret = FALSE;
1201 free(children);
1202 return ret;
1205 BOOL types_compare(struct dbg_type type1, struct dbg_type type2, BOOL* equal)
1207 DWORD tag1, tag2;
1208 DWORD64 size1, size2;
1209 DWORD bt1, bt2;
1210 DWORD count1, count2;
1211 BOOL ret;
1215 if (type1.module == type2.module && type1.id == type2.id)
1216 return *equal = TRUE;
1218 if (!types_get_real_type(&type1, &tag1) ||
1219 !types_get_real_type(&type2, &tag2)) return FALSE;
1221 if (type1.module == type2.module && type1.id == type2.id)
1222 return *equal = TRUE;
1224 if (tag1 != tag2) return !(*equal = FALSE);
1226 switch (tag1)
1228 case SymTagBaseType:
1229 if (!types_get_info(&type1, TI_GET_BASETYPE, &bt1) ||
1230 !types_get_info(&type2, TI_GET_BASETYPE, &bt2) ||
1231 !types_get_info(&type1, TI_GET_LENGTH, &size1) ||
1232 !types_get_info(&type2, TI_GET_LENGTH, &size2))
1233 return FALSE;
1234 *equal = bt1 == bt2 && size1 == size2;
1235 return TRUE;
1236 case SymTagPointerType:
1237 /* compare sub types */
1238 break;
1239 case SymTagUDT:
1240 case SymTagEnum:
1241 ret = types_compare_name(type1, type2, equal);
1242 if (!ret || !*equal) return ret;
1243 ret = types_compare_children(type1, type2, equal, tag1);
1244 if (!ret || !*equal) return ret;
1245 if (tag1 == SymTagUDT) return TRUE;
1246 /* compare underlying type for enums */
1247 break;
1248 case SymTagArrayType:
1249 if (!types_get_info(&type1, TI_GET_LENGTH, &size1) ||
1250 !types_get_info(&type2, TI_GET_LENGTH, &size2) ||
1251 !types_get_info(&type1, TI_GET_COUNT, &count1) ||
1252 !types_get_info(&type2, TI_GET_COUNT, &count2)) return FALSE;
1253 if (size1 == size2 && count1 == count2)
1255 struct dbg_type subtype1 = type1, subtype2 = type2;
1256 if (!types_get_info(&type1, TI_GET_ARRAYINDEXTYPEID, &subtype1.id) ||
1257 !types_get_info(&type2, TI_GET_ARRAYINDEXTYPEID, &subtype2.id)) return FALSE;
1258 if (!types_compare(subtype1, subtype2, equal)) return FALSE;
1259 if (!*equal) return TRUE;
1261 else return !(*equal = FALSE);
1262 /* compare subtypes */
1263 break;
1264 case SymTagFunctionType:
1265 if (!types_compare_children(type1, type2, equal, tag1)) return FALSE;
1266 if (!*equal) return TRUE;
1267 /* compare return:ed type */
1268 break;
1269 case SymTagFunctionArgType:
1270 /* compare argument type */
1271 break;
1272 default:
1273 dbg_printf("Unsupported yet tag %ld\n", tag1);
1274 return FALSE;
1276 } while (types_get_info(&type1, TI_GET_TYPE, &type1.id) &&
1277 types_get_info(&type2, TI_GET_TYPE, &type2.id));
1278 return FALSE;
1281 static BOOL is_basetype_char(DWORD bt)
1283 return bt == btChar || bt == btWChar || bt == btChar8 || bt == btChar16 || bt == btChar32;
1286 static BOOL is_basetype_integer(DWORD bt)
1288 return is_basetype_char(bt) || bt == btInt || bt == btUInt || bt == btLong || bt == btULong;
1291 BOOL types_is_integral_type(const struct dbg_lvalue* lv)
1293 struct dbg_type type = lv->type;
1294 DWORD tag, bt;
1295 if (lv->bitlen) return TRUE;
1296 if (!types_get_real_type(&type, &tag) ||
1297 !types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
1298 return is_basetype_integer(bt);
1301 BOOL types_is_float_type(const struct dbg_lvalue* lv)
1303 struct dbg_type type = lv->type;
1304 DWORD tag, bt;
1305 if (lv->bitlen) return FALSE;
1306 if (!types_get_real_type(&type, &tag) ||
1307 !types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
1308 return bt == btFloat;
1311 BOOL types_is_pointer_type(const struct dbg_lvalue* lv)
1313 struct dbg_type type = lv->type;
1314 DWORD tag;
1315 if (lv->bitlen) return FALSE;
1316 return types_get_real_type(&type, &tag) &&
1317 (tag == SymTagPointerType || tag == SymTagArrayType || tag == SymTagFunctionType);