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
->id
));
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
.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 */
219 lvalue
->bitlen
= lvalue
->bitstart
= 0;
224 /******************************************************************
225 * types_udt_find_element
228 BOOL
types_udt_find_element(struct dbg_lvalue
* lvalue
, const char* name
)
231 char buffer
[sizeof(TI_FINDCHILDREN_PARAMS
) + 256 * sizeof(DWORD
)];
232 TI_FINDCHILDREN_PARAMS
* fcp
= (TI_FINDCHILDREN_PARAMS
*)buffer
;
235 struct dbg_type type
;
237 if (!types_get_real_type(&lvalue
->type
, &tag
) || tag
!= SymTagUDT
)
240 if (types_get_info(&lvalue
->type
, TI_GET_CHILDRENCOUNT
, &count
))
245 fcp
->Count
= min(count
, 256);
246 if (types_get_info(&lvalue
->type
, TI_FINDCHILDREN
, fcp
))
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);
269 /******************************************************************
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
;
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
;
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
;
291 case SymTagPointerType
:
292 if (!memory_read_value(lvalue
, dbg_curr_process
->be_cpu
->pointer_size
, &result
->addr
.Offset
))
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;
303 FIXME("unexpected tag %lx\n", tag
);
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
;
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...
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
330 result
->in_debuggee
= 1;
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
;
345 struct dbg_type type
;
348 if (sym
->Tag
== user
->tag
)
355 user
->type
.module
= sym
->ModBase
;
356 user
->type
.id
= sym
->TypeIndex
;
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
)
374 /******************************************************************
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
)
393 /******************************************************************
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
;
405 if (!strchr(name
, '!')) /* no module, lookup across all modules */
407 str
= malloc(strlen(name
) + 3);
408 if (!str
) return FALSE
;
411 strcpy(str
+ 2, name
);
414 f
.type
.id
= dbg_itype_none
;
416 ret
= SymEnumTypesByName(dbg_curr_process
->handle
, 0, name
, types_cb
, &f
);
418 if (!ret
|| f
.type
.id
== dbg_itype_none
)
424 /***********************************************************************
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
;
438 if (!types_get_real_type(&type
, &tag
))
440 WINE_FIXME("---error\n");
444 if (type
.id
== dbg_itype_none
)
446 /* No type, just print the addr value */
447 print_bare_address(&lvalue
->addr
);
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
);
461 case SymTagPointerType
:
462 /* FIXME: this in not 100% optimal (as we're going through the typedef handling
465 print_basic(lvalue
, format
);
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
;
473 struct dbg_type sub_type
;
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);
503 case SymTagArrayType
:
505 * Loop over all of the entries, printing stuff as we go.
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
)
518 types_get_info(&lvalue_field
.type
, TI_GET_BASETYPE
, &basetype
);
519 if (basetype
== btChar
)
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
) ? "..." : "");
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) ? "}" : ", ");
541 case SymTagFunctionType
:
542 dbg_printf("Function ");
543 print_bare_address(&lvalue
->addr
);
545 types_print_type(&type
, FALSE
);
548 lvalue_field
= *lvalue
;
549 types_get_info(&lvalue
->type
, TI_GET_TYPE
, &lvalue_field
.type
.id
);
550 print_value(&lvalue_field
, format
, level
);
553 WINE_FIXME("Unknown tag (%lu)\n", tag
);
554 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
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
);
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");
586 SymEnumerateModules64(dbg_curr_process
->handle
, print_types_mod_cb
, NULL
);
590 BOOL
types_print_type(const struct dbg_type
* type
, BOOL details
)
594 DWORD tag
, udt
, count
, bitoffset
, bt
;
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
);
604 name
= (types_get_info(type
, TI_GET_SYMNAME
, &ptr
) && ptr
) ? ptr
: L
"--none--";
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
);
617 case SymTagPointerType
:
618 types_get_info(type
, TI_GET_TYPE
, &subtype
.id
);
619 subtype
.module
= type
->module
;
620 types_print_type(&subtype
, FALSE
);
624 types_get_info(type
, TI_GET_UDTKIND
, &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;
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
;
639 struct dbg_type type_elt
;
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
);
667 if (i
< min(fcp
->Count
, count
) - 1 || count
> 256) dbg_printf(" ");
670 count
-= min(count
, 256);
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
);
683 dbg_printf(" %ls[]", name
);
686 dbg_printf("enum %ls", name
);
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
;
694 struct dbg_type type_elt
;
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);
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
);
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
;
754 if (!count
) dbg_printf("void");
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);
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
);
784 WINE_ERR("Unknown type %lu for %ls\n", tag
, name
);
788 HeapFree(GetProcessHeap(), 0, ptr
);
792 /* order here must match order in enum dbg_internal_type */
795 unsigned char base_type
;
796 unsigned char byte_size
;
798 basic_types_details
[] =
808 /* unsigned integers */
816 /* signed integers */
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"},
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"},
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"},
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
;
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
;
953 model
= llp64_data_model
;
954 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt
);
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"))
982 else if (SymMatchStringA(module
, mbn
->modname
, FALSE
))
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};
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)
1002 model
= get_data_model(mbn
.base
);
1003 for (; model
->name
; model
++)
1005 if (!wcscmp(name
, model
->name
))
1008 type
->id
= model
->itype
;
1015 static BOOL
lookup_base_type_in_data_model(DWORD64 module
, unsigned bt
, unsigned len
, WCHAR
** pname
)
1017 const WCHAR
* name
= NULL
;
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
)
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
);
1038 *pname
= HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name
) + 1) * sizeof(WCHAR
));
1039 if (!*pname
) return FALSE
;
1040 lstrcpyW(*pname
, name
);
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
)
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
) &&
1063 if (!lookup_base_type_in_data_model(type
->module
, bt
, len
, &name
)) return FALSE
;
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
)
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
;
1088 case dbg_itype_lguint
:
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
;
1097 case dbg_itype_lgint
:
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
;
1106 case dbg_itype_astring
:
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
;
1115 case dbg_itype_segptr
:
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
;
1124 case dbg_itype_m128a
:
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
;
1133 default: WINE_FIXME("unsupported type id 0x%lx\n", type
->id
);
1140 static BOOL
types_compare_name(struct dbg_type type1
, struct dbg_type type2
, BOOL
* equal
)
1142 LPWSTR name1
, name2
;
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
);
1151 HeapFree(GetProcessHeap(), 0, name2
);
1154 HeapFree(GetProcessHeap(), 0, name1
);
1160 static BOOL
types_compare_children(struct dbg_type type1
, struct dbg_type type2
, BOOL
* equal
, DWORD tag
)
1162 DWORD count1
, count2
, i
;
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
];
1180 case SymTagFunctionType
: ret
= types_compare(type1
, type2
, equal
); break;
1182 /* each child is a SymTagData that describes the member */
1183 ret
= types_compare_name(type1
, type2
, 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 */
1193 default: ret
= FALSE
; break;
1195 if (!ret
|| !*equal
) break;
1197 if (i
== count1
) ret
= *equal
= TRUE
;
1205 BOOL
types_compare(struct dbg_type type1
, struct dbg_type type2
, BOOL
* equal
)
1208 DWORD64 size1
, size2
;
1210 DWORD count1
, count2
;
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
);
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
))
1234 *equal
= bt1
== bt2
&& size1
== size2
;
1236 case SymTagPointerType
:
1237 /* compare sub types */
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 */
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 */
1264 case SymTagFunctionType
:
1265 if (!types_compare_children(type1
, type2
, equal
, tag1
)) return FALSE
;
1266 if (!*equal
) return TRUE
;
1267 /* compare return:ed type */
1269 case SymTagFunctionArgType
:
1270 /* compare argument type */
1273 dbg_printf("Unsupported yet tag %ld\n", tag1
);
1276 } while (types_get_info(&type1
, TI_GET_TYPE
, &type1
.id
) &&
1277 types_get_info(&type2
, TI_GET_TYPE
, &type2
.id
));
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
;
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
;
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
;
1315 if (lv
->bitlen
) return FALSE
;
1316 return types_get_real_type(&type
, &tag
) &&
1317 (tag
== SymTagPointerType
|| tag
== SymTagArrayType
|| tag
== SymTagFunctionType
);