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.
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(winedbg
);
31 /******************************************************************
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
))
44 if (*tag
!= SymTagTypedef
) return TRUE
;
45 } while (types_get_info(type
, TI_GET_TYPE
, type
));
49 /******************************************************************
50 * types_extract_as_lgint
52 * Given a lvalue, try to get an integral (or pointer/address) value
55 dbg_lgint_t
types_extract_as_lgint(const struct dbg_lvalue
* lvalue
,
56 unsigned* psize
, BOOL
*issigned
)
61 struct dbg_type type
= lvalue
->type
;
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
;
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
);
85 if (size
> sizeof(rtn
))
87 WINE_ERR("Size too large (%I64x)\n", size
);
88 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER
, 0, 0, NULL
);
98 if (!memory_fetch_integer(lvalue
, (unsigned)size
, s
= TRUE
, &rtn
))
99 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
103 if (!memory_fetch_integer(lvalue
, (unsigned)size
, s
= FALSE
, &rtn
))
104 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
107 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER
, 0, 0, NULL
);
109 if (psize
) *psize
= (unsigned)size
;
110 if (issigned
) *issigned
= s
;
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
);
117 case SymTagArrayType
:
119 if (!memory_fetch_integer(lvalue
, sizeof(unsigned), s
= FALSE
, &rtn
))
120 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
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
);
127 case SymTagFunctionType
:
128 rtn
= (ULONG_PTR
)memory_to_linear_addr(&lvalue
->addr
);
131 WINE_FIXME("Unsupported tag %lu\n", tag
);
132 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER
, 0, 0, NULL
);
138 /******************************************************************
139 * types_extract_as_integer
141 * Given a lvalue, try to get an integral (or pointer/address) value
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
;
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
)
172 if (!types_compare(lvalue_to
->type
, lvalue_from
->type
, &equal
)) return FALSE
;
174 return memory_transfer_value(lvalue_to
, lvalue_from
);
175 if (types_is_float_type(lvalue_from
) && types_is_float_type(lvalue_to
))
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
;
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
;
202 types_get_info(type
, TI_GET_TYPE
, &lvalue
->type
);
203 if (!types_get_info(type
, TI_GET_OFFSET
, &offset
)) return FALSE
;
204 lvalue
->addr
.Offset
+= offset
;
206 if (types_get_info(type
, TI_GET_BITPOSITION
, &bitoffset
))
208 types_get_info(type
, TI_GET_LENGTH
, &length
);
209 lvalue
->bitlen
= length
;
210 lvalue
->bitstart
= bitoffset
;
211 if (lvalue
->bitlen
!= length
|| lvalue
->bitstart
!= bitoffset
)
213 dbg_printf("too wide bitfields\n"); /* shouldn't happen */
218 lvalue
->bitlen
= lvalue
->bitstart
= 0;
223 /******************************************************************
224 * types_udt_find_element
227 BOOL
types_udt_find_element(struct dbg_lvalue
* lvalue
, const char* name
)
230 char buffer
[sizeof(TI_FINDCHILDREN_PARAMS
) + 256 * sizeof(DWORD
)];
231 TI_FINDCHILDREN_PARAMS
* fcp
= (TI_FINDCHILDREN_PARAMS
*)buffer
;
234 struct dbg_type type
;
236 if (!types_get_real_type(&lvalue
->type
, &tag
) || tag
!= SymTagUDT
)
239 if (types_get_info(&lvalue
->type
, TI_GET_CHILDRENCOUNT
, &count
))
244 fcp
->Count
= min(count
, 256);
245 if (types_get_info(&lvalue
->type
, TI_FINDCHILDREN
, fcp
))
248 type
.module
= lvalue
->type
.module
;
249 for (i
= 0; i
< min(fcp
->Count
, count
); i
++)
251 type
.id
= fcp
->ChildId
[i
];
252 if (types_get_info(&type
, TI_GET_SYMNAME
, &ptr
) && ptr
)
254 WideCharToMultiByte(CP_ACP
, 0, ptr
, -1, tmp
, sizeof(tmp
), NULL
, NULL
);
255 HeapFree(GetProcessHeap(), 0, ptr
);
256 if (!strcmp(tmp
, name
))
257 return types_get_udt_element_lvalue(lvalue
, &type
);
261 count
-= min(count
, 256);
268 /******************************************************************
271 * Grab an element from an array
273 BOOL
types_array_index(const struct dbg_lvalue
* lvalue
, int index
, struct dbg_lvalue
* result
)
275 struct dbg_type type
= lvalue
->type
;
278 memset(result
, 0, sizeof(*result
));
279 result
->type
.id
= dbg_itype_none
;
280 result
->type
.module
= 0;
282 if (!types_get_real_type(&type
, &tag
)) return FALSE
;
285 case SymTagArrayType
:
286 if (!types_get_info(&type
, TI_GET_COUNT
, &count
)) return FALSE
;
287 if (index
< 0 || index
>= count
) return FALSE
;
288 result
->addr
= lvalue
->addr
;
290 case SymTagPointerType
:
291 if (!memory_read_value(lvalue
, dbg_curr_process
->be_cpu
->pointer_size
, &result
->addr
.Offset
))
293 result
->addr
.Mode
= AddrModeFlat
;
294 switch (dbg_curr_process
->be_cpu
->pointer_size
)
296 case 4: result
->addr
.Offset
= (DWORD
)result
->addr
.Offset
; break;
302 FIXME("unexpected tag %lx\n", tag
);
306 * Get the base type, so we know how much to index by.
308 if (!types_get_info(&type
, TI_GET_TYPE
, &result
->type
)) return FALSE
;
312 if (!types_get_info(&result
->type
, TI_GET_LENGTH
, &length
)) return FALSE
;
313 result
->addr
.Offset
+= index
* (DWORD
)length
;
315 /* FIXME: the following statement is not always true (and can lead to buggy behavior).
316 * There is no way to tell where the deref:ed value is...
318 * x is a pointer to struct s, x being on the stack
319 * => lvalue is in debuggee, result is in debugger
320 * x is a pointer to struct s, x being optimized into a reg
321 * => lvalue is debugger, result is debuggee
322 * x is a pointer to internal variable x
323 * => lvalue is debugger, result is debuggee
324 * So we always force debuggee address space, because dereferencing pointers to
325 * internal variables is very unlikely. A correct fix would be
328 result
->in_debuggee
= 1;
334 enum SymTagEnum tag
; /* in: the tag to look for */
335 struct dbg_type type
; /* out: the type found */
336 ULONG ptr_typeid
; /* in: when tag is SymTagPointerType */
339 static BOOL CALLBACK
types_cb(PSYMBOL_INFO sym
, ULONG size
, void* _user
)
341 struct type_find_t
* user
= _user
;
343 struct dbg_type type
, type_id
;
345 if (sym
->Tag
== user
->tag
)
352 user
->type
.module
= sym
->ModBase
;
353 user
->type
.id
= sym
->TypeIndex
;
356 case SymTagPointerType
:
357 type
.module
= sym
->ModBase
;
358 type
.id
= sym
->TypeIndex
;
359 if (types_get_info(&type
, TI_GET_TYPE
, &type_id
) && type_id
.id
== user
->ptr_typeid
)
371 /******************************************************************
374 * There's no simple API in dbghelp for looking up the pointer type of a given type
375 * - SymEnumTypes would do, but it'll enumerate all types, which could be long
376 * - and more impacting, there's no guarantee such a type exists
377 * Hence, we synthetize inside Winedbg all needed pointer types.
378 * That's cumbersome as we end up with dbg_type in different modules between pointer
381 BOOL
types_find_pointer(const struct dbg_type
* type
, struct dbg_type
* outtype
)
383 struct type_find_t f
;
385 struct dbg_type
* new;
387 if (!dbg_curr_process
) return FALSE
;
389 /* first lookup if pointer to type exists in module */
390 f
.type
.id
= dbg_itype_none
;
391 f
.tag
= SymTagPointerType
;
392 f
.ptr_typeid
= type
->id
;
393 SymEnumTypes(dbg_curr_process
->handle
, type
->module
, types_cb
, &f
);
394 if (f
.type
.id
!= dbg_itype_none
)
400 /* then look up in synthetized types */
401 for (i
= 0; i
< dbg_curr_process
->num_synthetized_types
; i
++)
402 if (!memcmp(type
, &dbg_curr_process
->synthetized_types
[i
], sizeof(*type
)))
405 outtype
->id
= dbg_itype_synthetized
+ i
;
408 if (dbg_itype_synthetized
+ dbg_curr_process
->num_synthetized_types
>= dbg_itype_first
)
410 /* for now, we don't reuse old slots... */
411 FIXME("overflow in pointer types\n");
414 /* otherwise, synthetize it */
415 new = realloc(dbg_curr_process
->synthetized_types
,
416 (dbg_curr_process
->num_synthetized_types
+ 1) * sizeof(*new));
417 if (!new) return FALSE
;
418 dbg_curr_process
->synthetized_types
= new;
419 dbg_curr_process
->synthetized_types
[dbg_curr_process
->num_synthetized_types
] = *type
;
421 outtype
->id
= dbg_itype_synthetized
+ dbg_curr_process
->num_synthetized_types
;
422 dbg_curr_process
->num_synthetized_types
++;
427 /******************************************************************
430 * Should look up in the module based at linear address whether a type
431 * named 'name' and with the correct tag exists
433 BOOL
types_find_type(const char* name
, enum SymTagEnum tag
, struct dbg_type
* outtype
)
435 struct type_find_t f
;
439 if (!strchr(name
, '!')) /* no module, lookup across all modules */
441 str
= malloc(strlen(name
) + 3);
442 if (!str
) return FALSE
;
445 strcpy(str
+ 2, name
);
448 f
.type
.id
= dbg_itype_none
;
450 ret
= SymEnumTypesByName(dbg_curr_process
->handle
, 0, name
, types_cb
, &f
);
452 if (!ret
|| f
.type
.id
== dbg_itype_none
)
458 /***********************************************************************
461 * Implementation of the 'print' command.
463 void print_value(const struct dbg_lvalue
* lvalue
, char format
, int level
)
465 struct dbg_type type
= lvalue
->type
;
466 struct dbg_lvalue lvalue_field
;
472 if (!types_get_real_type(&type
, &tag
))
474 WINE_FIXME("---error\n");
478 if (type
.id
== dbg_itype_none
)
480 /* No type, just print the addr value */
481 print_bare_address(&lvalue
->addr
);
485 if (format
== 'i' || format
== 's' || format
== 'w' || format
== 'b' || format
== 'g')
487 dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format
);
495 case SymTagPointerType
:
496 /* FIXME: this in not 100% optimal (as we're going through the typedef handling
499 print_basic(lvalue
, format
);
502 if (types_get_info(&type
, TI_GET_CHILDRENCOUNT
, &count
))
504 char buffer
[sizeof(TI_FINDCHILDREN_PARAMS
) + 256 * sizeof(DWORD
)];
505 TI_FINDCHILDREN_PARAMS
* fcp
= (TI_FINDCHILDREN_PARAMS
*)buffer
;
507 struct dbg_type sub_type
;
513 fcp
->Count
= min(count
, 256);
514 if (types_get_info(&type
, TI_FINDCHILDREN
, fcp
))
516 for (i
= 0; i
< min(fcp
->Count
, count
); i
++)
518 sub_type
.module
= type
.module
;
519 sub_type
.id
= fcp
->ChildId
[i
];
520 if (!types_get_info(&sub_type
, TI_GET_SYMNAME
, &ptr
) || !ptr
) continue;
521 dbg_printf("%ls=", ptr
);
522 HeapFree(GetProcessHeap(), 0, ptr
);
523 lvalue_field
= *lvalue
;
524 if (types_get_udt_element_lvalue(&lvalue_field
, &sub_type
))
526 print_value(&lvalue_field
, format
, level
+ 1);
528 if (i
< min(fcp
->Count
, count
) - 1 || count
> 256) dbg_printf(", ");
531 count
-= min(count
, 256);
537 case SymTagArrayType
:
539 * Loop over all of the entries, printing stuff as we go.
542 types_get_info(&type
, TI_GET_COUNT
, &count
);
543 types_get_info(&type
, TI_GET_LENGTH
, &size
);
544 lvalue_field
= *lvalue
;
545 types_get_info(&lvalue_field
.type
, TI_GET_TYPE
, &lvalue_field
.type
);
546 types_get_real_type(&lvalue_field
.type
, &tag
);
548 if (size
== count
&& tag
== SymTagBaseType
)
552 types_get_info(&lvalue_field
.type
, TI_GET_BASETYPE
, &basetype
);
553 if (basetype
== btChar
)
557 * Special handling for character arrays.
559 unsigned len
= min(count
, sizeof(buffer
));
560 memory_get_string(dbg_curr_process
,
561 memory_to_linear_addr(&lvalue
->addr
),
562 lvalue
->in_debuggee
, TRUE
, buffer
, len
);
563 dbg_printf("\"%s%s\"", buffer
, (len
< count
) ? "..." : "");
568 for (i
= 0; i
< count
; i
++)
570 print_value(&lvalue_field
, format
, level
+ 1);
571 lvalue_field
.addr
.Offset
+= size
/ count
;
572 dbg_printf((i
== count
- 1) ? "}" : ", ");
575 case SymTagFunctionType
:
576 dbg_printf("Function ");
577 print_bare_address(&lvalue
->addr
);
579 types_print_type(&type
, FALSE
, NULL
);
582 lvalue_field
= *lvalue
;
583 types_get_info(&lvalue
->type
, TI_GET_TYPE
, &lvalue_field
.type
);
584 print_value(&lvalue_field
, format
, level
);
587 WINE_FIXME("Unknown tag (%lu)\n", tag
);
588 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
594 if (level
== 0) dbg_printf("\n");
597 static BOOL CALLBACK
print_types_cb(PSYMBOL_INFO sym
, ULONG size
, void* ctx
)
599 struct dbg_type type
;
600 type
.module
= sym
->ModBase
;
601 type
.id
= sym
->TypeIndex
;
602 dbg_printf("Mod: %0*Ix ID: %08lx\n", ADDRWIDTH
, type
.module
, type
.id
);
603 types_print_type(&type
, TRUE
, FALSE
);
608 static BOOL CALLBACK
print_types_mod_cb(PCSTR mod_name
, DWORD64 base
, PVOID ctx
)
610 return SymEnumTypes(dbg_curr_process
->handle
, base
, print_types_cb
, ctx
);
613 BOOL
print_types(void)
615 if (!dbg_curr_process
)
617 dbg_printf("No known process, cannot print types\n");
620 SymEnumerateModules64(dbg_curr_process
->handle
, print_types_mod_cb
, NULL
);
624 BOOL
types_print_type(const struct dbg_type
* type
, BOOL details
, const WCHAR
* varname
)
628 DWORD tag
, udt
, count
, bitoffset
, bt
;
630 struct dbg_type subtype
;
631 BOOL printed
= FALSE
;
633 if (type
->id
== dbg_itype_none
|| !types_get_info(type
, TI_GET_SYMTAG
, &tag
))
635 dbg_printf("--invalid--<%lxh>--", type
->id
);
639 name
= (types_get_info(type
, TI_GET_SYMNAME
, &ptr
) && ptr
) ? ptr
: L
"--none--";
644 dbg_printf("%ls", name
);
645 if (details
&& types_get_info(type
, TI_GET_LENGTH
, &bitlen
) && types_get_info(type
, TI_GET_BASETYPE
, &bt
))
647 const char* longness
= "";
648 if (bt
== btLong
|| bt
== btULong
) longness
= " long";
649 dbg_printf(": size=%I64d%s", bitlen
, longness
);
652 case SymTagPointerType
:
653 types_get_info(type
, TI_GET_TYPE
, &subtype
);
654 types_print_type(&subtype
, FALSE
, NULL
);
658 types_get_info(type
, TI_GET_UDTKIND
, &udt
);
661 case UdtStruct
: dbg_printf("struct %ls", name
); break;
662 case UdtUnion
: dbg_printf("union %ls", name
); break;
663 case UdtClass
: dbg_printf("class %ls", name
); break;
664 default: WINE_ERR("Unsupported UDT type (%ld) for %ls\n", udt
, name
); break;
667 types_get_info(type
, TI_GET_CHILDRENCOUNT
, &count
))
669 char buffer
[sizeof(TI_FINDCHILDREN_PARAMS
) + 256 * sizeof(DWORD
)];
670 TI_FINDCHILDREN_PARAMS
* fcp
= (TI_FINDCHILDREN_PARAMS
*)buffer
;
673 struct dbg_type type_elt
;
679 fcp
->Count
= min(count
, 256);
680 if (types_get_info(type
, TI_FINDCHILDREN
, fcp
))
682 for (i
= 0; i
< min(fcp
->Count
, count
); i
++)
684 type_elt
.module
= type
->module
;
685 type_elt
.id
= fcp
->ChildId
[i
];
686 if (!types_get_info(&type_elt
, TI_GET_SYMNAME
, &ptr
) || !ptr
) continue;
687 if (!types_get_info(&type_elt
, TI_GET_BITPOSITION
, &bitoffset
) ||
688 !types_get_info(&type_elt
, TI_GET_LENGTH
, &bitlen
))
689 bitlen
= ~(DWORD64
)0;
690 if (types_get_info(&type_elt
, TI_GET_TYPE
, &type_elt
))
692 /* print details of embedded UDT:s */
693 types_print_type(&type_elt
, types_get_info(&type_elt
, TI_GET_UDTKIND
, &udt
), ptr
);
695 else dbg_printf("<unknown> %ls", ptr
);
696 HeapFree(GetProcessHeap(), 0, ptr
);
697 if (bitlen
!= ~(DWORD64
)0)
698 dbg_printf(" : %I64u", bitlen
);
700 if (i
< min(fcp
->Count
, count
) - 1 || count
> 256) dbg_printf(" ");
703 count
-= min(count
, 256);
709 case SymTagArrayType
:
710 if (types_get_info(type
, TI_GET_TYPE
, &subtype
))
712 types_print_type(&subtype
, FALSE
, varname
);
713 if (types_get_info(type
, TI_GET_COUNT
, &count
))
714 dbg_printf("[%ld]", count
);
721 dbg_printf("enum %ls", name
);
723 types_get_info(type
, TI_GET_CHILDRENCOUNT
, &count
))
725 char buffer
[sizeof(TI_FINDCHILDREN_PARAMS
) + 256 * sizeof(DWORD
)];
726 TI_FINDCHILDREN_PARAMS
* fcp
= (TI_FINDCHILDREN_PARAMS
*)buffer
;
729 struct dbg_type type_elt
;
737 fcp
->Count
= min(count
, 256);
738 if (types_get_info(type
, TI_FINDCHILDREN
, fcp
))
740 for (i
= 0; i
< min(fcp
->Count
, count
); i
++)
742 type_elt
.module
= type
->module
;
743 type_elt
.id
= fcp
->ChildId
[i
];
744 if (!types_get_info(&type_elt
, TI_GET_SYMNAME
, &ptr
) || !ptr
) continue;
745 if (!types_get_info(&type_elt
, TI_GET_VALUE
, &variant
) || !ptr
) continue;
746 dbg_printf("%ls = ", ptr
);
747 switch (V_VT(&variant
))
749 case VT_I1
: dbg_printf("%d", V_I1(&variant
)); break;
750 case VT_I2
: dbg_printf("%d", V_I2(&variant
)); break;
751 case VT_I4
: dbg_printf("%ld", V_I4(&variant
)); break;
752 case VT_I8
: dbg_printf("%I64d", V_I8(&variant
)); break;
753 case VT_UI1
: dbg_printf("%u", V_UI1(&variant
)); break;
754 case VT_UI2
: dbg_printf("%u", V_UI2(&variant
)); break;
755 case VT_UI4
: dbg_printf("%lu", V_UI4(&variant
)); break;
756 case VT_UI8
: dbg_printf("%I64u", V_UI8(&variant
)); break;
758 HeapFree(GetProcessHeap(), 0, ptr
);
759 if (i
< min(fcp
->Count
, count
) - 1 || count
> 256) dbg_printf(", ");
762 count
-= min(count
, 256);
768 case SymTagFunctionType
:
769 types_get_info(type
, TI_GET_TYPE
, &subtype
);
770 /* is the returned type the same object as function sig itself ? */
771 if (subtype
.id
!= type
->id
)
773 types_print_type(&subtype
, FALSE
, NULL
);
778 dbg_printf("<ret_type=self>");
780 dbg_printf(" (*%ls)(", varname
? varname
: L
"");
782 if (types_get_info(type
, TI_GET_CHILDRENCOUNT
, &count
))
784 char buffer
[sizeof(TI_FINDCHILDREN_PARAMS
) + 256 * sizeof(DWORD
)];
785 TI_FINDCHILDREN_PARAMS
* fcp
= (TI_FINDCHILDREN_PARAMS
*)buffer
;
789 if (!count
) dbg_printf("void");
792 fcp
->Count
= min(count
, 256);
793 if (types_get_info(type
, TI_FINDCHILDREN
, fcp
))
795 for (i
= 0; i
< min(fcp
->Count
, count
); i
++)
797 subtype
.id
= fcp
->ChildId
[i
];
798 types_get_info(&subtype
, TI_GET_TYPE
, &subtype
);
799 types_print_type(&subtype
, FALSE
, NULL
);
800 if (i
< min(fcp
->Count
, count
) - 1 || count
> 256) dbg_printf(", ");
803 count
-= min(count
, 256);
810 if (details
&& types_get_info(type
, TI_GET_TYPE
, &subtype
))
812 dbg_printf("typedef %ls => ", name
);
813 types_print_type(&subtype
, FALSE
, NULL
);
815 else dbg_printf("%ls", name
);
818 WINE_ERR("Unknown type %lu for %ls\n", tag
, name
);
821 if (varname
&& !printed
) dbg_printf(" %ls", varname
);
824 HeapFree(GetProcessHeap(), 0, ptr
);
828 /* order here must match order in enum dbg_internal_type */
831 unsigned char base_type
;
832 unsigned char byte_size
;
834 basic_types_details
[] =
844 /* unsigned integers */
852 /* signed integers */
866 C_ASSERT(ARRAY_SIZE(basic_types_details
) == dbg_itype_last
- dbg_itype_first
);
868 const struct data_model ilp32_data_model
[] =
870 {dbg_itype_void
, L
"void"},
872 {dbg_itype_bool
, L
"bool"},
874 {dbg_itype_char
, L
"char"},
875 {dbg_itype_wchar
, L
"WCHAR"},
876 {dbg_itype_char8
, L
"char8_t"},
877 {dbg_itype_char16
, L
"char16_t"},
878 {dbg_itype_char32
, L
"char32_t"},
880 {dbg_itype_unsigned_int8
, L
"unsigned char"},
881 {dbg_itype_unsigned_int16
, L
"unsigned short int"},
882 {dbg_itype_unsigned_int32
, L
"unsigned int"},
883 {dbg_itype_unsigned_int64
, L
"unsigned long long int"},
884 {dbg_itype_unsigned_int64
, L
"unsigned __int64"},
885 {dbg_itype_unsigned_long32
, L
"unsigned long int"},
887 {dbg_itype_signed_int8
, L
"signed char"},
888 {dbg_itype_signed_int16
, L
"short int"},
889 {dbg_itype_signed_int32
, L
"int"},
890 {dbg_itype_signed_int64
, L
"long long int"},
891 {dbg_itype_signed_int64
, L
"__int64"},
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"},
901 const struct data_model llp64_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"},
920 {dbg_itype_unsigned_long32
, L
"unsigned long int"},
922 {dbg_itype_signed_int8
, L
"signed char"},
923 {dbg_itype_signed_int16
, L
"short int"},
924 {dbg_itype_signed_int32
, L
"int"},
925 {dbg_itype_signed_int64
, L
"long long int"},
926 {dbg_itype_signed_int64
, L
"__int64"},
927 {dbg_itype_signed_int128
, L
"__int128"},
928 {dbg_itype_signed_long32
, L
"long int"},
930 {dbg_itype_short_real
, L
"float"},
931 {dbg_itype_real
, L
"double"},
932 {dbg_itype_long_real
, L
"long double"},
937 const struct data_model lp64_data_model
[] =
939 {dbg_itype_void
, L
"void"},
941 {dbg_itype_bool
, L
"bool"},
943 {dbg_itype_char
, L
"char"},
944 {dbg_itype_wchar
, L
"WCHAR"},
945 {dbg_itype_char8
, L
"char8_t"},
946 {dbg_itype_char16
, L
"char16_t"},
947 {dbg_itype_char32
, L
"char32_t"},
949 {dbg_itype_unsigned_int8
, L
"unsigned char"},
950 {dbg_itype_unsigned_int16
, L
"unsigned short int"},
951 {dbg_itype_unsigned_int32
, L
"unsigned int"},
952 {dbg_itype_unsigned_int64
, L
"unsigned long long int"},
953 {dbg_itype_unsigned_int64
, L
"unsigned __int64"},
954 {dbg_itype_unsigned_int128
, L
"unsigned __int128"},
955 {dbg_itype_unsigned_long64
, L
"unsigned long int"}, /* we can't discriminate 'unsigned long' from 'unsigned long long' (on output) */
957 {dbg_itype_signed_int8
, L
"signed char"},
958 {dbg_itype_signed_int16
, L
"short int"},
959 {dbg_itype_signed_int32
, L
"int"},
960 {dbg_itype_signed_int64
, L
"long long int"},
961 {dbg_itype_signed_int64
, L
"__int64"},
962 {dbg_itype_signed_int128
, L
"__int128"},
963 {dbg_itype_signed_long64
, L
"long int"}, /* we can't discriminate 'long' from 'long long' (on output)*/
965 {dbg_itype_short_real
, L
"float"},
966 {dbg_itype_real
, L
"double"},
967 {dbg_itype_long_real
, L
"long double"},
972 static const struct data_model
* get_data_model(DWORD64 modaddr
)
974 const struct data_model
*model
;
976 if (dbg_curr_process
->data_model
)
977 model
= dbg_curr_process
->data_model
;
978 else if (ADDRSIZE
== 4) model
= ilp32_data_model
;
981 IMAGEHLP_MODULEW64 mi
;
982 DWORD opt
= SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, TRUE
);
984 mi
.SizeOfStruct
= sizeof(mi
);
985 if (SymGetModuleInfoW64(dbg_curr_process
->handle
, modaddr
, &mi
) &&
986 (wcsstr(mi
.ModuleName
, L
".so") || wcsstr(mi
.ModuleName
, L
"<")))
987 model
= lp64_data_model
;
989 model
= llp64_data_model
;
990 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt
);
1001 static BOOL CALLBACK
enum_mod_cb(const char* module
, DWORD64 base
, void* user
)
1003 struct mod_by_name
* mbn
= user
;
1004 if (!mbn
->modname
) /* lookup data model from main module */
1006 IMAGEHLP_MODULE64 mi
;
1007 mi
.SizeOfStruct
= sizeof(mi
);
1008 if (SymGetModuleInfo64(dbg_curr_process
->handle
, base
, &mi
))
1010 size_t len
= strlen(mi
.ImageName
);
1011 if (len
>= 4 && !strcmp(mi
.ImageName
+ len
- 4, ".exe"))
1018 else if (SymMatchStringA(module
, mbn
->modname
, FALSE
))
1026 BOOL
types_find_basic(const WCHAR
* name
, const char* mod
, struct dbg_type
* type
)
1028 const struct data_model
* model
;
1029 struct mod_by_name mbn
= {mod
, 0};
1033 opt
= SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, TRUE
);
1034 ret
= SymEnumerateModules64(dbg_curr_process
->handle
, enum_mod_cb
, &mbn
);
1035 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt
);
1036 if (!ret
|| mbn
.base
== 0)
1038 model
= get_data_model(mbn
.base
);
1039 for (; model
->name
; model
++)
1041 if (!wcscmp(name
, model
->name
))
1044 type
->id
= model
->itype
;
1051 static BOOL
lookup_base_type_in_data_model(DWORD64 module
, unsigned bt
, unsigned len
, WCHAR
** pname
)
1053 const WCHAR
* name
= NULL
;
1055 const struct data_model
* model
;
1057 model
= get_data_model(module
);
1058 for (; model
->name
; model
++)
1060 if (model
->itype
>= dbg_itype_first
&& model
->itype
< dbg_itype_last
&&
1061 bt
== basic_types_details
[model
->itype
- dbg_itype_first
].base_type
&&
1062 len
== basic_types_details
[model
->itype
- dbg_itype_first
].byte_size
)
1068 if (!name
) /* synthetize name */
1070 WINE_FIXME("Unsupported basic type %u %u\n", bt
, len
);
1071 swprintf(tmp
, ARRAY_SIZE(tmp
), L
"bt[%u,%u]", bt
, len
);
1074 *pname
= HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name
) + 1) * sizeof(WCHAR
));
1075 if (!*pname
) return FALSE
;
1076 lstrcpyW(*pname
, name
);
1080 /* helper to typecast pInfo to its expected type (_t) */
1081 #define X(_t) (*((_t*)pInfo))
1083 /* Wrapper around SymGetTypeInfo
1084 * - module & type id on input are in dbg_type structure
1085 * - for TI_GET_TYPE a pointer to a dbg_type is expected for pInfo
1086 * (instead of DWORD* for SymGetTypeInfo)
1087 * - handles also internal types, and synthetized types.
1089 BOOL
types_get_info(const struct dbg_type
* type
, IMAGEHLP_SYMBOL_TYPE_INFO ti
, void* pInfo
)
1091 if (type
->id
== dbg_itype_none
) return FALSE
;
1092 if (type
->module
!= 0)
1094 if (ti
== TI_GET_SYMNAME
)
1099 if (SymGetTypeInfo(dbg_curr_process
->handle
, type
->module
, type
->id
, TI_GET_SYMTAG
, &tag
) &&
1100 tag
== SymTagBaseType
&&
1101 SymGetTypeInfo(dbg_curr_process
->handle
, type
->module
, type
->id
, TI_GET_BASETYPE
, &bt
) &&
1102 SymGetTypeInfo(dbg_curr_process
->handle
, type
->module
, type
->id
, TI_GET_LENGTH
, &len
) &&
1105 if (!lookup_base_type_in_data_model(type
->module
, bt
, len
, &name
)) return FALSE
;
1110 else if (ti
== TI_GET_TYPE
)
1112 struct dbg_type
* dt
= (struct dbg_type
*)pInfo
;
1113 if (!SymGetTypeInfo(dbg_curr_process
->handle
, type
->module
, type
->id
, ti
, &dt
->id
))
1115 dt
->module
= type
->module
;
1118 return SymGetTypeInfo(dbg_curr_process
->handle
, type
->module
, type
->id
, ti
, pInfo
);
1121 if (type
->id
>= dbg_itype_synthetized
&& type
->id
< dbg_itype_first
)
1123 unsigned i
= type
->id
- dbg_itype_synthetized
;
1124 if (i
>= dbg_curr_process
->num_synthetized_types
) return FALSE
;
1127 case TI_GET_SYMTAG
: X(DWORD
) = SymTagPointerType
; break;
1128 case TI_GET_LENGTH
: X(DWORD64
) = ADDRSIZE
; break;
1129 case TI_GET_TYPE
: if (dbg_curr_process
->synthetized_types
[i
].module
== 0 &&
1130 dbg_curr_process
->synthetized_types
[i
].id
== dbg_itype_none
) return FALSE
;
1132 X(struct dbg_type
) = dbg_curr_process
->synthetized_types
[i
];
1134 default: WINE_FIXME("unsupported %u for pointer type %d\n", ti
, i
); return FALSE
;
1139 assert(type
->id
>= dbg_itype_first
);
1141 if (type
->id
>= dbg_itype_first
&& type
->id
< dbg_itype_last
)
1145 case TI_GET_SYMTAG
: X(DWORD
) = SymTagBaseType
; break;
1146 case TI_GET_LENGTH
: X(DWORD64
) = basic_types_details
[type
->id
- dbg_itype_first
].byte_size
; break;
1147 case TI_GET_BASETYPE
: X(DWORD
) = basic_types_details
[type
->id
- dbg_itype_first
].base_type
; break;
1148 case TI_GET_SYMNAME
: return lookup_base_type_in_data_model(0, basic_types_details
[type
->id
- dbg_itype_first
].base_type
,
1149 basic_types_details
[type
->id
- dbg_itype_first
].byte_size
, &X(WCHAR
*));
1150 default: WINE_FIXME("unsupported %u for itype %#lx\n", ti
, type
->id
); return FALSE
;
1156 case dbg_itype_lguint
:
1159 case TI_GET_SYMTAG
: X(DWORD
) = SymTagBaseType
; break;
1160 case TI_GET_LENGTH
: X(DWORD64
) = sizeof(dbg_lguint_t
); break;
1161 case TI_GET_BASETYPE
: X(DWORD
) = btUInt
; break;
1162 default: WINE_FIXME("unsupported %u for lguint_t\n", ti
); return FALSE
;
1165 case dbg_itype_lgint
:
1168 case TI_GET_SYMTAG
: X(DWORD
) = SymTagBaseType
; break;
1169 case TI_GET_LENGTH
: X(DWORD64
) = sizeof(dbg_lgint_t
); break;
1170 case TI_GET_BASETYPE
: X(DWORD
) = btInt
; break;
1171 default: WINE_FIXME("unsupported %u for lgint_t\n", ti
); return FALSE
;
1174 case dbg_itype_astring
:
1177 case TI_GET_SYMTAG
: X(DWORD
) = SymTagPointerType
; break;
1178 case TI_GET_LENGTH
: X(DWORD64
) = ADDRSIZE
; break;
1179 case TI_GET_TYPE
: { struct dbg_type
* dt
= pInfo
; dt
->id
= dbg_itype_char
; dt
->module
= type
->module
; break; }
1180 default: WINE_FIXME("unsupported %u for a string\n", ti
); return FALSE
;
1183 case dbg_itype_segptr
:
1186 case TI_GET_SYMTAG
: X(DWORD
) = SymTagBaseType
; break;
1187 case TI_GET_LENGTH
: X(DWORD64
) = 4; break;
1188 case TI_GET_BASETYPE
: X(DWORD
) = btInt
; break;
1189 default: WINE_FIXME("unsupported %u for seg-ptr\n", ti
); return FALSE
;
1192 case dbg_itype_m128a
:
1195 case TI_GET_SYMTAG
: X(DWORD
) = SymTagBaseType
; break;
1196 case TI_GET_LENGTH
: X(DWORD64
) = 16; break;
1197 case TI_GET_BASETYPE
: X(DWORD
) = btUInt
; break;
1198 default: WINE_FIXME("unsupported %u for XMM register\n", ti
); return FALSE
;
1201 default: WINE_FIXME("unsupported type id 0x%lx\n", type
->id
); return FALSE
;
1208 BOOL
types_unload_module(struct dbg_process
* pcs
, DWORD_PTR linear
)
1211 if (!pcs
) return FALSE
;
1212 for (i
= 0; i
< pcs
->num_synthetized_types
; i
++)
1214 if (pcs
->synthetized_types
[i
].module
== linear
)
1216 pcs
->synthetized_types
[i
].module
= 0;
1217 pcs
->synthetized_types
[i
].id
= dbg_itype_none
;
1223 static BOOL
types_compare_name(struct dbg_type type1
, struct dbg_type type2
, BOOL
* equal
)
1225 LPWSTR name1
, name2
;
1228 if (types_get_info(&type1
, TI_GET_SYMNAME
, &name1
))
1230 if (types_get_info(&type2
, TI_GET_SYMNAME
, &name2
))
1232 *equal
= !wcscmp(name1
, name2
);
1234 HeapFree(GetProcessHeap(), 0, name2
);
1237 HeapFree(GetProcessHeap(), 0, name1
);
1243 static BOOL
types_compare_children(struct dbg_type type1
, struct dbg_type type2
, BOOL
* equal
, DWORD tag
)
1245 DWORD count1
, count2
, i
;
1249 if (!types_get_info(&type1
, TI_GET_CHILDRENCOUNT
, &count1
) ||
1250 !types_get_info(&type2
, TI_GET_CHILDRENCOUNT
, &count2
)) return FALSE
;
1251 if (count1
!= count2
) {*equal
= FALSE
; return TRUE
;}
1252 if (!count1
) return *equal
= TRUE
;
1253 if ((children
= malloc(sizeof(*children
) * 2 * count1
)) == NULL
) return FALSE
;
1254 if (types_get_info(&type1
, TI_FINDCHILDREN
, &children
[0]) &&
1255 types_get_info(&type2
, TI_FINDCHILDREN
, &children
[count1
]))
1257 for (i
= 0; i
< count1
; ++i
)
1259 type1
.id
= children
[i
];
1260 type2
.id
= children
[count1
+ i
];
1263 case SymTagFunctionType
: ret
= types_compare(type1
, type2
, equal
); break;
1265 /* each child is a SymTagData that describes the member */
1266 ret
= types_compare_name(type1
, type2
, equal
);
1269 /* compare type of member */
1270 ret
= types_get_info(&type1
, TI_GET_TYPE
, &type1
) &&
1271 types_get_info(&type2
, TI_GET_TYPE
, &type2
);
1272 if (ret
) ret
= types_compare(type1
, type2
, equal
);
1273 /* FIXME should compare bitfield info when present */
1276 default: ret
= FALSE
; break;
1278 if (!ret
|| !*equal
) break;
1280 if (i
== count1
) ret
= *equal
= TRUE
;
1288 BOOL
types_compare(struct dbg_type type1
, struct dbg_type type2
, BOOL
* equal
)
1291 DWORD64 size1
, size2
;
1293 DWORD count1
, count2
;
1298 if (type1
.module
== type2
.module
&& type1
.id
== type2
.id
)
1299 return *equal
= TRUE
;
1301 if (!types_get_real_type(&type1
, &tag1
) ||
1302 !types_get_real_type(&type2
, &tag2
)) return FALSE
;
1304 if (type1
.module
== type2
.module
&& type1
.id
== type2
.id
)
1305 return *equal
= TRUE
;
1307 if (tag1
!= tag2
) return !(*equal
= FALSE
);
1311 case SymTagBaseType
:
1312 if (!types_get_info(&type1
, TI_GET_BASETYPE
, &bt1
) ||
1313 !types_get_info(&type2
, TI_GET_BASETYPE
, &bt2
) ||
1314 !types_get_info(&type1
, TI_GET_LENGTH
, &size1
) ||
1315 !types_get_info(&type2
, TI_GET_LENGTH
, &size2
))
1317 *equal
= bt1
== bt2
&& size1
== size2
;
1319 case SymTagPointerType
:
1320 /* compare sub types */
1324 ret
= types_compare_name(type1
, type2
, equal
);
1325 if (!ret
|| !*equal
) return ret
;
1326 ret
= types_compare_children(type1
, type2
, equal
, tag1
);
1327 if (!ret
|| !*equal
) return ret
;
1328 if (tag1
== SymTagUDT
) return TRUE
;
1329 /* compare underlying type for enums */
1331 case SymTagArrayType
:
1332 if (!types_get_info(&type1
, TI_GET_LENGTH
, &size1
) ||
1333 !types_get_info(&type2
, TI_GET_LENGTH
, &size2
) ||
1334 !types_get_info(&type1
, TI_GET_COUNT
, &count1
) ||
1335 !types_get_info(&type2
, TI_GET_COUNT
, &count2
)) return FALSE
;
1336 if (size1
== size2
&& count1
== count2
)
1338 struct dbg_type subtype1
= type1
, subtype2
= type2
;
1339 if (!types_get_info(&type1
, TI_GET_ARRAYINDEXTYPEID
, &subtype1
.id
) ||
1340 !types_get_info(&type2
, TI_GET_ARRAYINDEXTYPEID
, &subtype2
.id
)) return FALSE
;
1341 if (!types_compare(subtype1
, subtype2
, equal
)) return FALSE
;
1342 if (!*equal
) return TRUE
;
1344 else return !(*equal
= FALSE
);
1345 /* compare subtypes */
1347 case SymTagFunctionType
:
1348 if (!types_compare_children(type1
, type2
, equal
, tag1
)) return FALSE
;
1349 if (!*equal
) return TRUE
;
1350 /* compare return:ed type */
1352 case SymTagFunctionArgType
:
1353 /* compare argument type */
1356 dbg_printf("Unsupported yet tag %ld\n", tag1
);
1359 } while (types_get_info(&type1
, TI_GET_TYPE
, &type1
) &&
1360 types_get_info(&type2
, TI_GET_TYPE
, &type2
));
1364 static BOOL
is_basetype_char(DWORD bt
)
1366 return bt
== btChar
|| bt
== btWChar
|| bt
== btChar8
|| bt
== btChar16
|| bt
== btChar32
;
1369 static BOOL
is_basetype_integer(DWORD bt
)
1371 return is_basetype_char(bt
) || bt
== btInt
|| bt
== btUInt
|| bt
== btLong
|| bt
== btULong
;
1374 BOOL
types_is_integral_type(const struct dbg_lvalue
* lv
)
1376 struct dbg_type type
= lv
->type
;
1378 if (lv
->bitlen
) return TRUE
;
1379 if (!types_get_real_type(&type
, &tag
) || tag
!= SymTagBaseType
||
1380 !types_get_info(&type
, TI_GET_BASETYPE
, &bt
)) return FALSE
;
1381 return is_basetype_integer(bt
);
1384 BOOL
types_is_float_type(const struct dbg_lvalue
* lv
)
1386 struct dbg_type type
= lv
->type
;
1388 if (lv
->bitlen
) return FALSE
;
1389 if (!types_get_real_type(&type
, &tag
) || tag
!= SymTagBaseType
||
1390 !types_get_info(&type
, TI_GET_BASETYPE
, &bt
)) return FALSE
;
1391 return bt
== btFloat
;
1394 BOOL
types_is_pointer_type(const struct dbg_lvalue
* lv
)
1396 struct dbg_type type
= lv
->type
;
1398 if (lv
->bitlen
) return FALSE
;
1399 return types_get_real_type(&type
, &tag
) &&
1400 (tag
== SymTagPointerType
|| tag
== SymTagArrayType
|| tag
== SymTagFunctionType
);