Reactos
at master 938 lines 33 kB view raw
1/* 2 * File types.c - management of types (hierarchical tree) 3 * 4 * Copyright (C) 1997, Eric Youngdale. 5 * 2004, Eric Pouech. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 * 21 * Note: This really doesn't do much at the moment, but it forms the framework 22 * upon which full support for datatype handling will eventually be built. 23 */ 24 25#define NONAMELESSUNION 26 27#include <stdlib.h> 28#include <stdarg.h> 29#include <assert.h> 30 31#ifndef DBGHELP_STATIC_LIB 32#include "windef.h" 33#include "winbase.h" 34#include "winnls.h" 35#include "wine/debug.h" 36#endif 37#include "dbghelp_private.h" 38 39WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); 40WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt); 41 42static const char* symt_get_tag_str(DWORD tag) 43{ 44 switch (tag) 45 { 46 case SymTagNull: return "SymTagNull"; 47 case SymTagExe: return "SymTagExe"; 48 case SymTagCompiland: return "SymTagCompiland"; 49 case SymTagCompilandDetails: return "SymTagCompilandDetails"; 50 case SymTagCompilandEnv: return "SymTagCompilandEnv"; 51 case SymTagFunction: return "SymTagFunction"; 52 case SymTagBlock: return "SymTagBlock"; 53 case SymTagData: return "SymTagData"; 54 case SymTagAnnotation: return "SymTagAnnotation"; 55 case SymTagLabel: return "SymTagLabel"; 56 case SymTagPublicSymbol: return "SymTagPublicSymbol"; 57 case SymTagUDT: return "SymTagUDT"; 58 case SymTagEnum: return "SymTagEnum"; 59 case SymTagFunctionType: return "SymTagFunctionType"; 60 case SymTagPointerType: return "SymTagPointerType"; 61 case SymTagArrayType: return "SymTagArrayType"; 62 case SymTagBaseType: return "SymTagBaseType"; 63 case SymTagTypedef: return "SymTagTypedef,"; 64 case SymTagBaseClass: return "SymTagBaseClass"; 65 case SymTagFriend: return "SymTagFriend"; 66 case SymTagFunctionArgType: return "SymTagFunctionArgType,"; 67 case SymTagFuncDebugStart: return "SymTagFuncDebugStart,"; 68 case SymTagFuncDebugEnd: return "SymTagFuncDebugEnd"; 69 case SymTagUsingNamespace: return "SymTagUsingNamespace,"; 70 case SymTagVTableShape: return "SymTagVTableShape"; 71 case SymTagVTable: return "SymTagVTable"; 72 case SymTagCustom: return "SymTagCustom"; 73 case SymTagThunk: return "SymTagThunk"; 74 case SymTagCustomType: return "SymTagCustomType"; 75 case SymTagManagedType: return "SymTagManagedType"; 76 case SymTagDimension: return "SymTagDimension"; 77 default: return "---"; 78 } 79} 80 81const char* symt_get_name(const struct symt* sym) 82{ 83 switch (sym->tag) 84 { 85 /* lexical tree */ 86 case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name; 87 case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name; 88 case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name; 89 case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name; 90 case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name; 91 case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name; 92 /* hierarchy tree */ 93 case SymTagEnum: return ((const struct symt_enum*)sym)->name; 94 case SymTagTypedef: return ((const struct symt_typedef*)sym)->hash_elt.name; 95 case SymTagUDT: return ((const struct symt_udt*)sym)->hash_elt.name; 96 default: 97 FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag)); 98 /* fall through */ 99 case SymTagArrayType: 100 case SymTagPointerType: 101 case SymTagFunctionType: 102 return NULL; 103 } 104} 105 106WCHAR* symt_get_nameW(const struct symt* sym) 107{ 108 const char* name = symt_get_name(sym); 109 WCHAR* nameW; 110 DWORD sz; 111 112 if (!name) return NULL; 113 sz = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0); 114 if ((nameW = HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR)))) 115 MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, sz); 116 return nameW; 117} 118 119BOOL symt_get_address(const struct symt* type, ULONG64* addr) 120{ 121 switch (type->tag) 122 { 123 case SymTagData: 124 switch (((const struct symt_data*)type)->kind) 125 { 126 case DataIsGlobal: 127 case DataIsFileStatic: 128 *addr = ((const struct symt_data*)type)->u.var.offset; 129 break; 130 default: return FALSE; 131 } 132 break; 133 case SymTagFunction: 134 *addr = ((const struct symt_function*)type)->address; 135 break; 136 case SymTagPublicSymbol: 137 *addr = ((const struct symt_public*)type)->address; 138 break; 139 case SymTagFuncDebugStart: 140 case SymTagFuncDebugEnd: 141 case SymTagLabel: 142 if (!((const struct symt_hierarchy_point*)type)->parent || 143 !symt_get_address(((const struct symt_hierarchy_point*)type)->parent, addr)) 144 return FALSE; 145 *addr += ((const struct symt_hierarchy_point*)type)->loc.offset; 146 break; 147 case SymTagThunk: 148 *addr = ((const struct symt_thunk*)type)->address; 149 break; 150 case SymTagCompiland: 151 *addr = ((const struct symt_compiland*)type)->address; 152 break; 153 default: 154 FIXME("Unsupported sym-tag %s for get-address\n", symt_get_tag_str(type->tag)); 155 return FALSE; 156 } 157 return TRUE; 158} 159 160static struct symt* symt_find_type_by_name(const struct module* module, 161 enum SymTagEnum sym_tag, 162 const char* typename) 163{ 164 void* ptr; 165 struct symt_ht* type; 166 struct hash_table_iter hti; 167 168 assert(typename); 169 assert(module); 170 171 hash_table_iter_init(&module->ht_types, &hti, typename); 172 while ((ptr = hash_table_iter_up(&hti))) 173 { 174 type = CONTAINING_RECORD(ptr, struct symt_ht, hash_elt); 175 176 if ((sym_tag == SymTagNull || type->symt.tag == sym_tag) && 177 type->hash_elt.name && !strcmp(type->hash_elt.name, typename)) 178 return &type->symt; 179 } 180 SetLastError(ERROR_INVALID_NAME); /* FIXME ?? */ 181 return NULL; 182} 183 184static void symt_add_type(struct module* module, struct symt* symt) 185{ 186 struct symt** p; 187 p = vector_add(&module->vtypes, &module->pool); 188 assert(p); 189 *p = symt; 190} 191 192struct symt_basic* symt_new_basic(struct module* module, enum BasicType bt, 193 const char* typename, unsigned size) 194{ 195 struct symt_basic* sym; 196 197 if (typename) 198 { 199 sym = (struct symt_basic*)symt_find_type_by_name(module, SymTagBaseType, 200 typename); 201 if (sym && sym->bt == bt && sym->size == size) 202 return sym; 203 } 204 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 205 { 206 sym->symt.tag = SymTagBaseType; 207 if (typename) 208 { 209 sym->hash_elt.name = pool_strdup(&module->pool, typename); 210 hash_table_add(&module->ht_types, &sym->hash_elt); 211 } else sym->hash_elt.name = NULL; 212 sym->bt = bt; 213 sym->size = size; 214 symt_add_type(module, &sym->symt); 215 } 216 return sym; 217} 218 219struct symt_udt* symt_new_udt(struct module* module, const char* typename, 220 unsigned size, enum UdtKind kind) 221{ 222 struct symt_udt* sym; 223 224 TRACE_(dbghelp_symt)("Adding udt %s:%s\n", 225 debugstr_w(module->module.ModuleName), typename); 226 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 227 { 228 sym->symt.tag = SymTagUDT; 229 sym->kind = kind; 230 sym->size = size; 231 if (typename) 232 { 233 sym->hash_elt.name = pool_strdup(&module->pool, typename); 234 hash_table_add(&module->ht_types, &sym->hash_elt); 235 } else sym->hash_elt.name = NULL; 236 vector_init(&sym->vchildren, sizeof(struct symt*), 8); 237 symt_add_type(module, &sym->symt); 238 } 239 return sym; 240} 241 242BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned size) 243{ 244 assert(udt->symt.tag == SymTagUDT); 245 if (vector_length(&udt->vchildren) != 0) 246 { 247 if (udt->size != size) 248 FIXME_(dbghelp_symt)("Changing size for %s from %u to %u\n", 249 udt->hash_elt.name, udt->size, size); 250 return TRUE; 251 } 252 udt->size = size; 253 return TRUE; 254} 255 256/****************************************************************** 257 * symt_add_udt_element 258 * 259 * add an element to a udt (struct, class, union) 260 * the size & offset parameters are expressed in bits (not bytes) so that 261 * we can mix in the single call bytes aligned elements (regular fields) and 262 * the others (bit fields) 263 */ 264BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type, 265 const char* name, struct symt* elt_type, 266 unsigned offset, unsigned size) 267{ 268 struct symt_data* m; 269 struct symt** p; 270 271 assert(udt_type->symt.tag == SymTagUDT); 272 273 TRACE_(dbghelp_symt)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name); 274 if (name) 275 { 276 unsigned int i; 277 for (i=0; i<vector_length(&udt_type->vchildren); i++) 278 { 279 m = *(struct symt_data**)vector_at(&udt_type->vchildren, i); 280 assert(m); 281 assert(m->symt.tag == SymTagData); 282 if (strcmp(m->hash_elt.name, name) == 0) 283 return TRUE; 284 } 285 } 286 287 if ((m = pool_alloc(&module->pool, sizeof(*m))) == NULL) return FALSE; 288 memset(m, 0, sizeof(*m)); 289 m->symt.tag = SymTagData; 290 m->hash_elt.name = name ? pool_strdup(&module->pool, name) : ""; 291 m->hash_elt.next = NULL; 292 293 m->kind = DataIsMember; 294 m->container = &udt_type->symt; 295 m->type = elt_type; 296 m->u.member.offset = offset; 297 m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0; 298 p = vector_add(&udt_type->vchildren, &module->pool); 299 *p = &m->symt; 300 301 return TRUE; 302} 303 304struct symt_enum* symt_new_enum(struct module* module, const char* typename, 305 struct symt* basetype) 306{ 307 struct symt_enum* sym; 308 309 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 310 { 311 sym->symt.tag = SymTagEnum; 312 sym->name = (typename) ? pool_strdup(&module->pool, typename) : NULL; 313 sym->base_type = basetype; 314 vector_init(&sym->vchildren, sizeof(struct symt*), 8); 315 } 316 return sym; 317} 318 319BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type, 320 const char* name, int value) 321{ 322 struct symt_data* e; 323 struct symt** p; 324 325 assert(enum_type->symt.tag == SymTagEnum); 326 e = pool_alloc(&module->pool, sizeof(*e)); 327 if (e == NULL) return FALSE; 328 329 e->symt.tag = SymTagData; 330 e->hash_elt.name = pool_strdup(&module->pool, name); 331 e->hash_elt.next = NULL; 332 e->kind = DataIsConstant; 333 e->container = &enum_type->symt; 334 e->type = enum_type->base_type; 335 e->u.value.n1.n2.vt = VT_I4; 336 e->u.value.n1.n2.n3.lVal = value; 337 338 p = vector_add(&enum_type->vchildren, &module->pool); 339 if (!p) return FALSE; /* FIXME we leak e */ 340 *p = &e->symt; 341 342 return TRUE; 343} 344 345struct symt_array* symt_new_array(struct module* module, int min, int max, 346 struct symt* base, struct symt* index) 347{ 348 struct symt_array* sym; 349 350 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 351 { 352 sym->symt.tag = SymTagArrayType; 353 sym->start = min; 354 sym->end = max; 355 sym->base_type = base; 356 sym->index_type = index; 357 symt_add_type(module, &sym->symt); 358 } 359 return sym; 360} 361 362static inline DWORD symt_array_count(struct module* module, const struct symt_array* array) 363{ 364 if (array->end < 0) 365 { 366 DWORD64 elem_size; 367 /* One could want to also set the array->end field in array, but we won't do it 368 * as long as all the get_type() helpers use const objects 369 */ 370 if (symt_get_info(module, array->base_type, TI_GET_LENGTH, &elem_size) && elem_size) 371 return -array->end / (DWORD)elem_size; 372 return 0; 373 } 374 return array->end - array->start + 1; 375} 376 377struct symt_function_signature* symt_new_function_signature(struct module* module, 378 struct symt* ret_type, 379 enum CV_call_e call_conv) 380{ 381 struct symt_function_signature* sym; 382 383 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 384 { 385 sym->symt.tag = SymTagFunctionType; 386 sym->rettype = ret_type; 387 vector_init(&sym->vchildren, sizeof(struct symt*), 4); 388 sym->call_conv = call_conv; 389 symt_add_type(module, &sym->symt); 390 } 391 return sym; 392} 393 394BOOL symt_add_function_signature_parameter(struct module* module, 395 struct symt_function_signature* sig_type, 396 struct symt* param) 397{ 398 struct symt** p; 399 struct symt_function_arg_type* arg; 400 401 assert(sig_type->symt.tag == SymTagFunctionType); 402 arg = pool_alloc(&module->pool, sizeof(*arg)); 403 if (!arg) return FALSE; 404 arg->symt.tag = SymTagFunctionArgType; 405 arg->arg_type = param; 406 arg->container = &sig_type->symt; 407 p = vector_add(&sig_type->vchildren, &module->pool); 408 if (!p) return FALSE; /* FIXME we leak arg */ 409 *p = &arg->symt; 410 411 return TRUE; 412} 413 414struct symt_pointer* symt_new_pointer(struct module* module, struct symt* ref_type, ULONG_PTR size) 415{ 416 struct symt_pointer* sym; 417 418 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 419 { 420 sym->symt.tag = SymTagPointerType; 421 sym->pointsto = ref_type; 422 sym->size = size; 423 symt_add_type(module, &sym->symt); 424 } 425 return sym; 426} 427 428struct symt_typedef* symt_new_typedef(struct module* module, struct symt* ref, 429 const char* name) 430{ 431 struct symt_typedef* sym; 432 433 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 434 { 435 sym->symt.tag = SymTagTypedef; 436 sym->type = ref; 437 sym->hash_elt.name = pool_strdup(&module->pool, name); 438 hash_table_add(&module->ht_types, &sym->hash_elt); 439 symt_add_type(module, &sym->symt); 440 } 441 return sym; 442} 443 444/****************************************************************** 445 * SymEnumTypes (DBGHELP.@) 446 * 447 */ 448BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll, 449 PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, 450 PVOID UserContext) 451{ 452 struct module_pair pair; 453 char buffer[sizeof(SYMBOL_INFO) + 256]; 454 SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer; 455 const char* tmp; 456 struct symt* type; 457 DWORD64 size; 458 unsigned int i; 459 460 TRACE("(%p %s %p %p)\n", 461 hProcess, wine_dbgstr_longlong(BaseOfDll), EnumSymbolsCallback, 462 UserContext); 463 464 if (!(pair.pcs = process_find_by_handle(hProcess))) return FALSE; 465 pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN); 466 if (!module_get_debug(&pair)) return FALSE; 467 468 sym_info->SizeOfStruct = sizeof(SYMBOL_INFO); 469 sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO); 470 471 for (i=0; i<vector_length(&pair.effective->vtypes); i++) 472 { 473 type = *(struct symt**)vector_at(&pair.effective->vtypes, i); 474 sym_info->TypeIndex = symt_ptr2index(pair.effective, type); 475 sym_info->Index = 0; /* FIXME */ 476 symt_get_info(pair.effective, type, TI_GET_LENGTH, &size); 477 sym_info->Size = size; 478 sym_info->ModBase = pair.requested->module.BaseOfImage; 479 sym_info->Flags = 0; /* FIXME */ 480 sym_info->Value = 0; /* FIXME */ 481 sym_info->Address = 0; /* FIXME */ 482 sym_info->Register = 0; /* FIXME */ 483 sym_info->Scope = 0; /* FIXME */ 484 sym_info->Tag = type->tag; 485 tmp = symt_get_name(type); 486 if (tmp) 487 { 488 sym_info->NameLen = min(strlen(tmp),sym_info->MaxNameLen-1); 489 memcpy(sym_info->Name, tmp, sym_info->NameLen); 490 sym_info->Name[sym_info->NameLen] = '\0'; 491 } 492 else 493 sym_info->Name[sym_info->NameLen = 0] = '\0'; 494 if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break; 495 } 496 return TRUE; 497} 498 499struct enum_types_AtoW 500{ 501 char buffer[sizeof(SYMBOL_INFOW) + 256 * sizeof(WCHAR)]; 502 void* user; 503 PSYM_ENUMERATESYMBOLS_CALLBACKW callback; 504}; 505 506static BOOL CALLBACK enum_types_AtoW(PSYMBOL_INFO si, ULONG addr, PVOID _et) 507{ 508 struct enum_types_AtoW* et = _et; 509 SYMBOL_INFOW* siW = (SYMBOL_INFOW*)et->buffer; 510 511 copy_symbolW(siW, si); 512 return et->callback(siW, addr, et->user); 513} 514 515/****************************************************************** 516 * SymEnumTypesW (DBGHELP.@) 517 * 518 */ 519BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll, 520 PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, 521 PVOID UserContext) 522{ 523 struct enum_types_AtoW et; 524 525 et.callback = EnumSymbolsCallback; 526 et.user = UserContext; 527 528 return SymEnumTypes(hProcess, BaseOfDll, enum_types_AtoW, &et); 529} 530 531/****************************************************************** 532 * symt_get_info 533 * 534 * Retrieves information about a symt (either symbol or type) 535 */ 536BOOL symt_get_info(struct module* module, const struct symt* type, 537 IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo) 538{ 539 unsigned len; 540 541 if (!type) return FALSE; 542 543/* helper to typecast pInfo to its expected type (_t) */ 544#define X(_t) (*((_t*)pInfo)) 545 546 switch (req) 547 { 548 case TI_FINDCHILDREN: 549 { 550 const struct vector* v; 551 struct symt** pt; 552 unsigned i; 553 TI_FINDCHILDREN_PARAMS* tifp = pInfo; 554 555 switch (type->tag) 556 { 557 case SymTagUDT: v = &((const struct symt_udt*)type)->vchildren; break; 558 case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break; 559 case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break; 560 case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break; 561 default: 562 FIXME("Unsupported sym-tag %s for find-children\n", 563 symt_get_tag_str(type->tag)); 564 return FALSE; 565 } 566 for (i = 0; i < tifp->Count; i++) 567 { 568 if (!(pt = vector_at(v, tifp->Start + i))) return FALSE; 569 tifp->ChildId[i] = symt_ptr2index(module, *pt); 570 } 571 } 572 break; 573 574 case TI_GET_ADDRESS: 575 return symt_get_address(type, (ULONG64*)pInfo); 576 577 case TI_GET_BASETYPE: 578 switch (type->tag) 579 { 580 case SymTagBaseType: 581 X(DWORD) = ((const struct symt_basic*)type)->bt; 582 break; 583 case SymTagEnum: 584 X(DWORD) = btInt; 585 break; 586 default: 587 return FALSE; 588 } 589 break; 590 591 case TI_GET_BITPOSITION: 592 if (type->tag == SymTagData && 593 ((const struct symt_data*)type)->kind == DataIsMember && 594 ((const struct symt_data*)type)->u.member.length != 0) 595 X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7; 596 else return FALSE; 597 break; 598 599 case TI_GET_CHILDRENCOUNT: 600 switch (type->tag) 601 { 602 case SymTagUDT: 603 X(DWORD) = vector_length(&((const struct symt_udt*)type)->vchildren); 604 break; 605 case SymTagEnum: 606 X(DWORD) = vector_length(&((const struct symt_enum*)type)->vchildren); 607 break; 608 case SymTagFunctionType: 609 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren); 610 break; 611 case SymTagFunction: 612 X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren); 613 break; 614 case SymTagPointerType: /* MS does it that way */ 615 case SymTagArrayType: /* MS does it that way */ 616 case SymTagThunk: /* MS does it that way */ 617 X(DWORD) = 0; 618 break; 619 default: 620 FIXME("Unsupported sym-tag %s for get-children-count\n", 621 symt_get_tag_str(type->tag)); 622 /* fall through */ 623 case SymTagData: 624 case SymTagPublicSymbol: 625 case SymTagBaseType: 626 return FALSE; 627 } 628 break; 629 630 case TI_GET_COUNT: 631 switch (type->tag) 632 { 633 case SymTagArrayType: 634 X(DWORD) = symt_array_count(module, (const struct symt_array*)type); 635 break; 636 case SymTagFunctionType: 637 /* this seems to be wrong for (future) C++ methods, where 'this' parameter 638 * should be included in this value (and not in GET_CHILDREN_COUNT) 639 */ 640 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren); 641 break; 642 default: return FALSE; 643 } 644 break; 645 646 case TI_GET_DATAKIND: 647 if (type->tag != SymTagData) return FALSE; 648 X(DWORD) = ((const struct symt_data*)type)->kind; 649 break; 650 651 case TI_GET_LENGTH: 652 switch (type->tag) 653 { 654 case SymTagBaseType: 655 X(DWORD64) = ((const struct symt_basic*)type)->size; 656 break; 657 case SymTagFunction: 658 X(DWORD64) = ((const struct symt_function*)type)->size; 659 break; 660 case SymTagPointerType: 661 X(DWORD64) = ((const struct symt_pointer*)type)->size; 662 break; 663 case SymTagUDT: 664 X(DWORD64) = ((const struct symt_udt*)type)->size; 665 break; 666 case SymTagEnum: 667 X(DWORD64) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */ 668 break; 669 case SymTagData: 670 if (((const struct symt_data*)type)->kind != DataIsMember || 671 !((const struct symt_data*)type)->u.member.length) 672 return FALSE; 673 X(DWORD64) = ((const struct symt_data*)type)->u.member.length; 674 break; 675 case SymTagArrayType: 676 if (!symt_get_info(module, ((const struct symt_array*)type)->base_type, 677 TI_GET_LENGTH, pInfo)) 678 return FALSE; 679 X(DWORD64) *= symt_array_count(module, (const struct symt_array*)type); 680 break; 681 case SymTagPublicSymbol: 682 X(DWORD64) = ((const struct symt_public*)type)->size; 683 break; 684 case SymTagTypedef: 685 return symt_get_info(module, ((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo); 686 case SymTagThunk: 687 X(DWORD64) = ((const struct symt_thunk*)type)->size; 688 break; 689 case SymTagLabel: 690 X(DWORD64) = 0; 691 break; 692 default: 693 FIXME("Unsupported sym-tag %s for get-length\n", 694 symt_get_tag_str(type->tag)); 695 /* fall through */ 696 case SymTagFunctionType: 697 return FALSE; 698 } 699 break; 700 701 case TI_GET_LEXICALPARENT: 702 switch (type->tag) 703 { 704 case SymTagBlock: 705 X(DWORD) = symt_ptr2index(module, ((const struct symt_block*)type)->container); 706 break; 707 case SymTagData: 708 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->container); 709 break; 710 case SymTagFunction: 711 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->container); 712 break; 713 case SymTagThunk: 714 X(DWORD) = symt_ptr2index(module, ((const struct symt_thunk*)type)->container); 715 break; 716 case SymTagFunctionArgType: 717 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->container); 718 break; 719 default: 720 FIXME("Unsupported sym-tag %s for get-lexical-parent\n", 721 symt_get_tag_str(type->tag)); 722 return FALSE; 723 } 724 break; 725 726 case TI_GET_NESTED: 727 switch (type->tag) 728 { 729 case SymTagUDT: 730 case SymTagEnum: 731 X(DWORD) = 0; 732 break; 733 default: 734 return FALSE; 735 } 736 break; 737 738 case TI_GET_OFFSET: 739 switch (type->tag) 740 { 741 case SymTagData: 742 switch (((const struct symt_data*)type)->kind) 743 { 744 case DataIsParam: 745 case DataIsLocal: 746 X(ULONG) = ((const struct symt_data*)type)->u.var.offset; 747 break; 748 case DataIsMember: 749 X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3; 750 break; 751 default: 752 FIXME("Unknown kind (%u) for get-offset\n", 753 ((const struct symt_data*)type)->kind); 754 return FALSE; 755 } 756 break; 757 default: 758 FIXME("Unsupported sym-tag %s for get-offset\n", 759 symt_get_tag_str(type->tag)); 760 return FALSE; 761 } 762 break; 763 764 case TI_GET_SYMNAME: 765 { 766 const char* name = symt_get_name(type); 767 if (!name) return FALSE; 768 len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0); 769 X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 770 if (!X(WCHAR*)) return FALSE; 771 MultiByteToWideChar(CP_ACP, 0, name, -1, X(WCHAR*), len); 772 } 773 break; 774 775 case TI_GET_SYMTAG: 776 X(DWORD) = type->tag; 777 break; 778 779 case TI_GET_TYPE: 780 case TI_GET_TYPEID: 781 switch (type->tag) 782 { 783 /* hierarchical => hierarchical */ 784 case SymTagArrayType: 785 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->base_type); 786 break; 787 case SymTagPointerType: 788 X(DWORD) = symt_ptr2index(module, ((const struct symt_pointer*)type)->pointsto); 789 break; 790 case SymTagFunctionType: 791 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_signature*)type)->rettype); 792 break; 793 case SymTagTypedef: 794 X(DWORD) = symt_ptr2index(module, ((const struct symt_typedef*)type)->type); 795 break; 796 /* lexical => hierarchical */ 797 case SymTagData: 798 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->type); 799 break; 800 case SymTagFunction: 801 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->type); 802 break; 803 case SymTagEnum: 804 X(DWORD) = symt_ptr2index(module, ((const struct symt_enum*)type)->base_type); 805 break; 806 case SymTagFunctionArgType: 807 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->arg_type); 808 break; 809 default: 810 FIXME("Unsupported sym-tag %s for get-type\n", 811 symt_get_tag_str(type->tag)); 812 /* fall through */ 813 case SymTagPublicSymbol: 814 case SymTagThunk: 815 case SymTagLabel: 816 return FALSE; 817 } 818 break; 819 820 case TI_GET_UDTKIND: 821 if (type->tag != SymTagUDT) return FALSE; 822 X(DWORD) = ((const struct symt_udt*)type)->kind; 823 break; 824 825 case TI_GET_VALUE: 826 if (type->tag != SymTagData) return FALSE; 827 switch (((const struct symt_data*)type)->kind) 828 { 829 case DataIsConstant: X(VARIANT) = ((const struct symt_data*)type)->u.value; break; 830 case DataIsLocal: 831 case DataIsParam: 832 { 833 struct location loc = ((const struct symt_data*)type)->u.var; 834 unsigned i; 835 struct module_format* modfmt; 836 837 if (loc.kind < loc_user) return FALSE; 838 for (i = 0; i < DFI_LAST; i++) 839 { 840 modfmt = module->format_info[i]; 841 if (modfmt && modfmt->loc_compute) 842 { 843 modfmt->loc_compute(module->process, modfmt, 844 (const struct symt_function*)((const struct symt_data*)type)->container, &loc); 845 break; 846 } 847 } 848 if (loc.kind != loc_absolute) return FALSE; 849 X(VARIANT).n1.n2.vt = VT_UI4; /* FIXME */ 850 X(VARIANT).n1.n2.n3.uiVal = loc.offset; 851 } 852 break; 853 default: return FALSE; 854 } 855 break; 856 857 case TI_GET_CALLING_CONVENTION: 858 if (type->tag != SymTagFunctionType) return FALSE; 859 if (((const struct symt_function_signature*)type)->call_conv == -1) 860 { 861 FIXME("No support for calling convention for this signature\n"); 862 X(DWORD) = CV_CALL_FAR_C; /* FIXME */ 863 } 864 else X(DWORD) = ((const struct symt_function_signature*)type)->call_conv; 865 break; 866 case TI_GET_ARRAYINDEXTYPEID: 867 if (type->tag != SymTagArrayType) return FALSE; 868 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->index_type); 869 break; 870 871 case TI_GET_CLASSPARENTID: 872 /* FIXME: we don't support properly C++ for now, pretend this symbol doesn't 873 * belong to a parent class 874 */ 875 return FALSE; 876 877#undef X 878 879 case TI_GET_ADDRESSOFFSET: 880 case TI_GET_SYMINDEX: 881 case TI_GET_THISADJUST: 882 case TI_GET_VIRTUALBASECLASS: 883 case TI_GET_VIRTUALBASEPOINTEROFFSET: 884 case TI_GET_VIRTUALTABLESHAPEID: 885 case TI_IS_EQUIV_TO: 886 FIXME("Unsupported GetInfo request (%u)\n", req); 887 return FALSE; 888 default: 889 FIXME("Unknown GetInfo request (%u)\n", req); 890 return FALSE; 891 } 892 893 return TRUE; 894} 895 896/****************************************************************** 897 * SymGetTypeInfo (DBGHELP.@) 898 * 899 */ 900BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase, 901 ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType, 902 PVOID pInfo) 903{ 904 struct module_pair pair; 905 906 pair.pcs = process_find_by_handle(hProcess); 907 if (!pair.pcs) return FALSE; 908 909 pair.requested = module_find_by_addr(pair.pcs, ModBase, DMT_UNKNOWN); 910 if (!module_get_debug(&pair)) 911 { 912 FIXME("Someone didn't properly set ModBase (%s)\n", wine_dbgstr_longlong(ModBase)); 913 return FALSE; 914 } 915 916 return symt_get_info(pair.effective, symt_index2ptr(pair.effective, TypeId), GetType, pInfo); 917} 918 919/****************************************************************** 920 * SymGetTypeFromName (DBGHELP.@) 921 * 922 */ 923BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, ULONG64 BaseOfDll, 924 PCSTR Name, PSYMBOL_INFO Symbol) 925{ 926 struct process* pcs = process_find_by_handle(hProcess); 927 struct module_pair pair; 928 struct symt* type; 929 930 if (!pcs) return FALSE; 931 pair.requested = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN); 932 if (!module_get_debug(&pair)) return FALSE; 933 type = symt_find_type_by_name(pair.effective, SymTagNull, Name); 934 if (!type) return FALSE; 935 Symbol->TypeIndex = symt_ptr2index(pair.effective, type); 936 937 return TRUE; 938}