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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
32 /******************************************************************
33 * types_extract_as_integer
35 * Given a lvalue, try to get an integral (or pointer/address) value
38 long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
44 if (lvalue->type.id == dbg_itype_none ||
45 !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
51 if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size64) ||
52 !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
54 WINE_ERR("Couldn't get information\n");
55 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
57 if (size64 > sizeof(rtn))
59 WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size64));
63 /* FIXME: we have an ugly & non portable thing here !!! */
64 if (!memory_read_value(lvalue, size, &rtn)) return 0;
66 /* now let's do some promotions !! */
70 /* propagate sign information */
71 if (((size & 3) != 0) && (rtn >> (size * 8 - 1)) != 0)
72 rtn |= (-1) << (size * 8);
78 RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
81 case SymTagPointerType:
82 if (!memory_read_value(lvalue, sizeof(void*), &rtn)) return 0;
86 assert(lvalue->cookie == DLV_TARGET);
87 if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) return 0;
90 assert(lvalue->cookie == DLV_TARGET);
91 if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) return 0;
94 WINE_FIXME("Unsupported tag %lu\n", tag);
102 /******************************************************************
106 BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
110 memset(result, 0, sizeof(*result));
111 result->type.id = dbg_itype_none;
112 result->type.module = 0;
115 * Make sure that this really makes sense.
117 if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
118 tag != SymTagPointerType ||
119 !memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
120 !types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id))
122 result->type.module = lvalue->type.module;
123 result->cookie = DLV_TARGET;
124 /* FIXME: this is currently buggy.
125 * there is no way to tell were the deref:ed value is...
127 * x is a pointer to struct s, x being on the stack
128 * => lvalue is in debuggee, result is in debugger
129 * x is a pointer to struct s, x being optimized into a reg
130 * => lvalue is debugger, result is debuggee
131 * x is a pointer to internal variable x
132 * => lvalue is debugger, result is debuggee
133 * so we force debuggee address space, because dereferencing pointers to
134 * internal variables is very unlikely. A correct fix would be
137 result->addr.Mode = AddrModeFlat;
141 /******************************************************************
142 * types_get_udt_element_lvalue
144 * Implement a structure derefencement
146 static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue,
147 const struct dbg_type* type, long int* tmpbuf)
149 DWORD offset, bitoffset;
155 types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
156 lvalue->type.module = type->module;
157 if (!types_get_info(type, TI_GET_OFFSET, &offset)) return FALSE;
158 lvalue->addr.Offset += offset;
160 if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset))
162 types_get_info(type, TI_GET_LENGTH, &length);
163 /* FIXME: this test isn't sufficient, depending on start of bitfield
164 * (ie a 32 bit field can spread across 5 bytes)
166 if (length > 8 * sizeof(*tmpbuf)) return FALSE;
167 lvalue->addr.Offset += bitoffset >> 3;
169 * Bitfield operation. We have to extract the field and store
170 * it in a temporary buffer so that we get it all right.
172 if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;
173 mask = 0xffffffff << (DWORD)length;
174 *tmpbuf >>= bitoffset & 7;
177 lvalue->cookie = DLV_HOST;
178 lvalue->addr.Offset = (DWORD)tmpbuf;
181 * OK, now we have the correct part of the number.
182 * Check to see whether the basic type is signed or not, and if so,
183 * we need to sign extend the number.
185 if (types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt) &&
186 bt == btInt && (*tmpbuf & (1 << ((DWORD)length - 1))))
193 if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;
199 /******************************************************************
200 * types_udt_find_element
203 BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long int* tmpbuf)
206 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
207 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
211 struct dbg_type type;
213 if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
217 if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
222 fcp->Count = min(count, 256);
223 if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
225 type.module = lvalue->type.module;
226 for (i = 0; i < min(fcp->Count, count); i++)
229 type.id = fcp->ChildId[i];
230 types_get_info(&type, TI_GET_SYMNAME, &ptr);
232 WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
233 HeapFree(GetProcessHeap(), 0, ptr);
234 if (strcmp(tmp, name)) continue;
236 return types_get_udt_element_lvalue(lvalue, &type, tmpbuf);
239 count -= min(count, 256);
246 /******************************************************************
249 * Grab an element from an array
251 BOOL types_array_index(const struct dbg_lvalue* lvalue, int index,
252 struct dbg_lvalue* result)
257 if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
261 case SymTagArrayType:
262 types_get_info(&lvalue->type, TI_GET_COUNT, &count);
263 if (index < 0 || index >= count) return FALSE;
265 case SymTagPointerType:
266 /* Contents of array share same data (addr mode, module...) */
269 * Get the base type, so we know how much to index by.
271 types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id);
272 types_get_info(&result->type, TI_GET_LENGTH, &length);
273 memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
274 result->addr.Offset += index * (DWORD)length;
284 unsigned long result; /* out: the found type */
285 enum SymTagEnum tag; /* in: the tag to look for */
288 unsigned long typeid; /* when tag is SymTagUDT */
289 const char* name; /* when tag is SymTagPointerType */
293 static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
295 struct type_find_t* user = (struct type_find_t*)_user;
297 struct dbg_type type;
300 if (sym->Tag == user->tag)
305 if (!strcmp(user->u.name, sym->Name))
307 user->result = sym->TypeIndex;
311 case SymTagPointerType:
312 type.module = sym->ModBase;
313 type.id = sym->TypeIndex;
314 if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->u.typeid)
316 user->result = sym->TypeIndex;
326 /******************************************************************
329 * Should look up in module based at linear whether (typeid*) exists
330 * Otherwise, we could create it locally
332 struct dbg_type types_find_pointer(const struct dbg_type* type)
334 struct type_find_t f;
337 f.result = dbg_itype_none;
338 f.tag = SymTagPointerType;
339 f.u.typeid = type->id;
340 SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
341 ret.module = type->module;
346 /******************************************************************
349 * Should look up in the module based at linear address whether a type
350 * named 'name' and with the correct tag exists
352 struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag)
355 struct type_find_t f;
358 f.result = dbg_itype_none;
361 SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
367 /***********************************************************************
370 * Implementation of the 'print' command.
372 void print_value(const struct dbg_lvalue* lvalue, char format, int level)
374 struct dbg_lvalue lvalue_field;
380 if (lvalue->type.id == dbg_itype_none)
382 /* No type, just print the addr value */
383 print_bare_address(&lvalue->addr);
387 if (format == 'i' || format == 's' || format == 'w' || format == 'b' || format == 'g')
389 dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
393 if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
395 WINE_FIXME("---error\n");
402 case SymTagPointerType:
403 print_basic(lvalue, 1, format);
406 if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
408 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
409 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
413 struct dbg_type type;
419 fcp->Count = min(count, 256);
420 if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
422 for (i = 0; i < min(fcp->Count, count); i++)
425 type.module = lvalue->type.module;
426 type.id = fcp->ChildId[i];
427 types_get_info(&type, TI_GET_SYMNAME, &ptr);
429 WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
430 dbg_printf("%s=", tmp);
431 HeapFree(GetProcessHeap(), 0, ptr);
432 lvalue_field = *lvalue;
433 if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
435 print_value(&lvalue_field, format, level + 1);
437 if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
440 count -= min(count, 256);
446 case SymTagArrayType:
448 * Loop over all of the entries, printing stuff as we go.
451 types_get_info(&lvalue->type, TI_GET_COUNT, &count);
452 types_get_info(&lvalue->type, TI_GET_LENGTH, &size);
459 * Special handling for character arrays.
461 /* FIXME should check basic type here (should be a char!!!!)... */
462 len = min(count, sizeof(buffer));
463 memory_get_string(dbg_curr_process,
464 memory_to_linear_addr(&lvalue->addr),
465 lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
466 dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
469 lvalue_field = *lvalue;
470 types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
472 for (i = 0; i < count; i++)
474 print_value(&lvalue_field, format, level + 1);
475 lvalue_field.addr.Offset += size / count;
476 dbg_printf((i == count - 1) ? "}" : ", ");
479 case SymTagFunctionType:
480 dbg_printf("Function ");
481 print_bare_address(&lvalue->addr);
483 types_print_type(&lvalue->type, FALSE);
486 WINE_FIXME("Unknown tag (%lu)\n", tag);
487 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
493 if (level == 0) dbg_printf("\n");
496 static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx)
498 struct dbg_type type;
499 type.module = sym->ModBase;
500 type.id = sym->TypeIndex;
501 dbg_printf("Mod: %08lx ID: %08lx \n", type.module, type.id);
502 types_print_type(&type, TRUE);
507 static BOOL CALLBACK print_types_mod_cb(PSTR mod_name, DWORD base, void* ctx)
509 return SymEnumTypes(dbg_curr_process->handle, base, print_types_cb, ctx);
512 int print_types(void)
514 SymEnumerateModules(dbg_curr_process->handle, print_types_mod_cb, NULL);
518 int types_print_type(const struct dbg_type* type, BOOL details)
523 DWORD tag, udt, count;
524 struct dbg_type subtype;
526 if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
528 dbg_printf("--invalid--<%lxh>--", type->id);
532 if (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr)
534 WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
536 HeapFree(GetProcessHeap(), 0, ptr);
538 else name = "--none--";
543 if (details) dbg_printf("Basic<%s>", name); else dbg_printf("%s", name);
545 case SymTagPointerType:
546 types_get_info(type, TI_GET_TYPE, &subtype.id);
547 subtype.module = type->module;
548 types_print_type(&subtype, FALSE);
552 types_get_info(type, TI_GET_UDTKIND, &udt);
555 case UdtStruct: dbg_printf("struct %s", name); break;
556 case UdtUnion: dbg_printf("union %s", name); break;
557 case UdtClass: dbg_printf("class %s", name); break;
558 default: WINE_ERR("Unsupported UDT type (%ld) for %s", udt, name); break;
561 types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
563 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
564 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
568 struct dbg_type type_elt;
574 fcp->Count = min(count, 256);
575 if (types_get_info(type, TI_FINDCHILDREN, fcp))
577 for (i = 0; i < min(fcp->Count, count); i++)
580 type_elt.module = type->module;
581 type_elt.id = fcp->ChildId[i];
582 types_get_info(&type_elt, TI_GET_SYMNAME, &ptr);
584 WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
585 HeapFree(GetProcessHeap(), 0, ptr);
586 dbg_printf("%s", tmp);
587 if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
590 types_print_type(&type_elt, details);
592 if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
595 count -= min(count, 256);
601 case SymTagArrayType:
602 types_get_info(type, TI_GET_TYPE, &subtype.id);
603 subtype.module = type->module;
604 types_print_type(&subtype, details);
605 dbg_printf(" %s[]", name);
608 dbg_printf("enum %s", name);
610 case SymTagFunctionType:
611 types_get_info(type, TI_GET_TYPE, &subtype.id);
612 subtype.module = type->module;
613 types_print_type(&subtype, FALSE);
614 dbg_printf(" (*%s)(", name);
615 if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
617 char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
618 TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
624 fcp->Count = min(count, 256);
625 if (types_get_info(type, TI_FINDCHILDREN, fcp))
627 for (i = 0; i < min(fcp->Count, count); i++)
629 subtype.id = fcp->ChildId[i];
630 types_get_info(&subtype, TI_GET_TYPE, &subtype.id);
631 types_print_type(&subtype, FALSE);
632 if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
635 count -= min(count, 256);
642 WINE_ERR("Unknown type %lu for %s\n", tag, name);
649 BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
651 if (type->id == dbg_itype_none) return FALSE;
652 if (type->module != 0)
653 return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
655 assert(type->id >= dbg_itype_first);
656 /* helper to typecast pInfo to its expected type (_t) */
657 #define X(_t) (*((_t*)pInfo))
661 case dbg_itype_unsigned_int:
664 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
665 case TI_GET_LENGTH: X(DWORD64) = 4; break;
666 case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
667 default: WINE_FIXME("unsupported %u for u-int\n", ti); return FALSE;
670 case dbg_itype_signed_int:
673 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
674 case TI_GET_LENGTH: X(DWORD64) = 4; break;
675 case TI_GET_BASETYPE: X(DWORD) = btInt; break;
676 default: WINE_FIXME("unsupported %u for s-int\n", ti); return FALSE;
679 case dbg_itype_unsigned_short_int:
682 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
683 case TI_GET_LENGTH: X(DWORD64) = 2; break;
684 case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
685 default: WINE_FIXME("unsupported %u for u-short int\n", ti); return FALSE;
688 case dbg_itype_signed_short_int:
691 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
692 case TI_GET_LENGTH: X(DWORD64) = 2; break;
693 case TI_GET_BASETYPE: X(DWORD) = btInt; break;
694 default: WINE_FIXME("unsupported %u for s-short int\n", ti); return FALSE;
697 case dbg_itype_unsigned_char_int:
700 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
701 case TI_GET_LENGTH: X(DWORD64) = 1; break;
702 case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
703 default: WINE_FIXME("unsupported %u for u-char int\n", ti); return FALSE;
706 case dbg_itype_signed_char_int:
709 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
710 case TI_GET_LENGTH: X(DWORD64) = 1; break;
711 case TI_GET_BASETYPE: X(DWORD) = btInt; break;
712 default: WINE_FIXME("unsupported %u for s-char int\n", ti); return FALSE;
718 case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
719 case TI_GET_LENGTH: X(DWORD64) = 1; break;
720 case TI_GET_BASETYPE: X(DWORD) = btChar; break;
721 default: WINE_FIXME("unsupported %u for char int\n", ti); return FALSE;
724 case dbg_itype_astring:
727 case TI_GET_SYMTAG: X(DWORD) = SymTagPointerType; break;
728 case TI_GET_LENGTH: X(DWORD64) = 4; break;
729 case TI_GET_TYPE: X(DWORD) = dbg_itype_char; break;
730 default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
733 default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);