Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentype.c
Go to the documentation of this file.
00001 /* 00002 * File types.c - management of types (hierarchical tree) 00003 * 00004 * Copyright (C) 1997, Eric Youngdale. 00005 * 2004, Eric Pouech. 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 * 00021 * Note: This really doesn't do much at the moment, but it forms the framework 00022 * upon which full support for datatype handling will eventually be built. 00023 */ 00024 00025 #define NONAMELESSUNION 00026 00027 #include "config.h" 00028 #include <stdlib.h> 00029 #include <stdarg.h> 00030 #include <assert.h> 00031 00032 #include "windef.h" 00033 #include "winbase.h" 00034 #include "winnls.h" 00035 #include "wine/debug.h" 00036 #include "dbghelp_private.h" 00037 00038 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); 00039 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt); 00040 00041 static const char* symt_get_tag_str(DWORD tag) 00042 { 00043 switch (tag) 00044 { 00045 case SymTagNull: return "SymTagNull"; 00046 case SymTagExe: return "SymTagExe"; 00047 case SymTagCompiland: return "SymTagCompiland"; 00048 case SymTagCompilandDetails: return "SymTagCompilandDetails"; 00049 case SymTagCompilandEnv: return "SymTagCompilandEnv"; 00050 case SymTagFunction: return "SymTagFunction"; 00051 case SymTagBlock: return "SymTagBlock"; 00052 case SymTagData: return "SymTagData"; 00053 case SymTagAnnotation: return "SymTagAnnotation"; 00054 case SymTagLabel: return "SymTagLabel"; 00055 case SymTagPublicSymbol: return "SymTagPublicSymbol"; 00056 case SymTagUDT: return "SymTagUDT"; 00057 case SymTagEnum: return "SymTagEnum"; 00058 case SymTagFunctionType: return "SymTagFunctionType"; 00059 case SymTagPointerType: return "SymTagPointerType"; 00060 case SymTagArrayType: return "SymTagArrayType"; 00061 case SymTagBaseType: return "SymTagBaseType"; 00062 case SymTagTypedef: return "SymTagTypedef,"; 00063 case SymTagBaseClass: return "SymTagBaseClass"; 00064 case SymTagFriend: return "SymTagFriend"; 00065 case SymTagFunctionArgType: return "SymTagFunctionArgType,"; 00066 case SymTagFuncDebugStart: return "SymTagFuncDebugStart,"; 00067 case SymTagFuncDebugEnd: return "SymTagFuncDebugEnd"; 00068 case SymTagUsingNamespace: return "SymTagUsingNamespace,"; 00069 case SymTagVTableShape: return "SymTagVTableShape"; 00070 case SymTagVTable: return "SymTagVTable"; 00071 case SymTagCustom: return "SymTagCustom"; 00072 case SymTagThunk: return "SymTagThunk"; 00073 case SymTagCustomType: return "SymTagCustomType"; 00074 case SymTagManagedType: return "SymTagManagedType"; 00075 case SymTagDimension: return "SymTagDimension"; 00076 default: return "---"; 00077 } 00078 } 00079 00080 const char* symt_get_name(const struct symt* sym) 00081 { 00082 switch (sym->tag) 00083 { 00084 /* lexical tree */ 00085 case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name; 00086 case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name; 00087 case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name; 00088 case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name; 00089 case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name; 00090 case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name; 00091 /* hierarchy tree */ 00092 case SymTagEnum: return ((const struct symt_enum*)sym)->name; 00093 case SymTagTypedef: return ((const struct symt_typedef*)sym)->hash_elt.name; 00094 case SymTagUDT: return ((const struct symt_udt*)sym)->hash_elt.name; 00095 default: 00096 FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag)); 00097 /* fall through */ 00098 case SymTagArrayType: 00099 case SymTagPointerType: 00100 case SymTagFunctionType: 00101 return NULL; 00102 } 00103 } 00104 00105 BOOL symt_get_address(const struct symt* type, ULONG64* addr) 00106 { 00107 switch (type->tag) 00108 { 00109 case SymTagData: 00110 switch (((const struct symt_data*)type)->kind) 00111 { 00112 case DataIsGlobal: 00113 case DataIsFileStatic: 00114 *addr = ((const struct symt_data*)type)->u.var.offset; 00115 break; 00116 default: return FALSE; 00117 } 00118 break; 00119 case SymTagFunction: 00120 *addr = ((const struct symt_function*)type)->address; 00121 break; 00122 case SymTagPublicSymbol: 00123 *addr = ((const struct symt_public*)type)->address; 00124 break; 00125 case SymTagFuncDebugStart: 00126 case SymTagFuncDebugEnd: 00127 case SymTagLabel: 00128 if (!((const struct symt_hierarchy_point*)type)->parent || 00129 !symt_get_address(((const struct symt_hierarchy_point*)type)->parent, addr)) 00130 return FALSE; 00131 *addr += ((const struct symt_hierarchy_point*)type)->loc.offset; 00132 break; 00133 case SymTagThunk: 00134 *addr = ((const struct symt_thunk*)type)->address; 00135 break; 00136 case SymTagCompiland: 00137 *addr = ((const struct symt_compiland*)type)->address; 00138 break; 00139 default: 00140 FIXME("Unsupported sym-tag %s for get-address\n", symt_get_tag_str(type->tag)); 00141 return FALSE; 00142 } 00143 return TRUE; 00144 } 00145 00146 static struct symt* symt_find_type_by_name(const struct module* module, 00147 enum SymTagEnum sym_tag, 00148 const char* typename) 00149 { 00150 void* ptr; 00151 struct symt_ht* type; 00152 struct hash_table_iter hti; 00153 00154 assert(typename); 00155 assert(module); 00156 00157 hash_table_iter_init(&module->ht_types, &hti, typename); 00158 while ((ptr = hash_table_iter_up(&hti))) 00159 { 00160 type = GET_ENTRY(ptr, struct symt_ht, hash_elt); 00161 00162 if ((sym_tag == SymTagNull || type->symt.tag == sym_tag) && 00163 type->hash_elt.name && !strcmp(type->hash_elt.name, typename)) 00164 return &type->symt; 00165 } 00166 SetLastError(ERROR_INVALID_NAME); /* FIXME ?? */ 00167 return NULL; 00168 } 00169 00170 static void symt_add_type(struct module* module, struct symt* symt) 00171 { 00172 struct symt** p; 00173 p = vector_add(&module->vtypes, &module->pool); 00174 assert(p); 00175 *p = symt; 00176 } 00177 00178 struct symt_basic* symt_new_basic(struct module* module, enum BasicType bt, 00179 const char* typename, unsigned size) 00180 { 00181 struct symt_basic* sym; 00182 00183 if (typename) 00184 { 00185 sym = (struct symt_basic*)symt_find_type_by_name(module, SymTagBaseType, 00186 typename); 00187 if (sym && sym->bt == bt && sym->size == size) 00188 return sym; 00189 } 00190 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 00191 { 00192 sym->symt.tag = SymTagBaseType; 00193 if (typename) 00194 { 00195 sym->hash_elt.name = pool_strdup(&module->pool, typename); 00196 hash_table_add(&module->ht_types, &sym->hash_elt); 00197 } else sym->hash_elt.name = NULL; 00198 sym->bt = bt; 00199 sym->size = size; 00200 symt_add_type(module, &sym->symt); 00201 } 00202 return sym; 00203 } 00204 00205 struct symt_udt* symt_new_udt(struct module* module, const char* typename, 00206 unsigned size, enum UdtKind kind) 00207 { 00208 struct symt_udt* sym; 00209 00210 TRACE_(dbghelp_symt)("Adding udt %s:%s\n", 00211 debugstr_w(module->module.ModuleName), typename); 00212 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 00213 { 00214 sym->symt.tag = SymTagUDT; 00215 sym->kind = kind; 00216 sym->size = size; 00217 if (typename) 00218 { 00219 sym->hash_elt.name = pool_strdup(&module->pool, typename); 00220 hash_table_add(&module->ht_types, &sym->hash_elt); 00221 } else sym->hash_elt.name = NULL; 00222 vector_init(&sym->vchildren, sizeof(struct symt*), 8); 00223 symt_add_type(module, &sym->symt); 00224 } 00225 return sym; 00226 } 00227 00228 BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned size) 00229 { 00230 assert(udt->symt.tag == SymTagUDT); 00231 if (vector_length(&udt->vchildren) != 0) 00232 { 00233 if (udt->size != size) 00234 FIXME_(dbghelp_symt)("Changing size for %s from %u to %u\n", 00235 udt->hash_elt.name, udt->size, size); 00236 return TRUE; 00237 } 00238 udt->size = size; 00239 return TRUE; 00240 } 00241 00242 /****************************************************************** 00243 * symt_add_udt_element 00244 * 00245 * add an element to a udt (struct, class, union) 00246 * the size & offset parameters are expressed in bits (not bytes) so that 00247 * we can mix in the single call bytes aligned elements (regular fields) and 00248 * the others (bit fields) 00249 */ 00250 BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type, 00251 const char* name, struct symt* elt_type, 00252 unsigned offset, unsigned size) 00253 { 00254 struct symt_data* m; 00255 struct symt** p; 00256 00257 assert(udt_type->symt.tag == SymTagUDT); 00258 00259 TRACE_(dbghelp_symt)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name); 00260 if (name) 00261 { 00262 unsigned int i; 00263 for (i=0; i<vector_length(&udt_type->vchildren); i++) 00264 { 00265 m = *(struct symt_data**)vector_at(&udt_type->vchildren, i); 00266 assert(m); 00267 assert(m->symt.tag == SymTagData); 00268 if (strcmp(m->hash_elt.name, name) == 0) 00269 return TRUE; 00270 } 00271 } 00272 00273 if ((m = pool_alloc(&module->pool, sizeof(*m))) == NULL) return FALSE; 00274 memset(m, 0, sizeof(*m)); 00275 m->symt.tag = SymTagData; 00276 m->hash_elt.name = name ? pool_strdup(&module->pool, name) : ""; 00277 m->hash_elt.next = NULL; 00278 00279 m->kind = DataIsMember; 00280 m->container = &udt_type->symt; 00281 m->type = elt_type; 00282 m->u.member.offset = offset; 00283 m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0; 00284 p = vector_add(&udt_type->vchildren, &module->pool); 00285 *p = &m->symt; 00286 00287 return TRUE; 00288 } 00289 00290 struct symt_enum* symt_new_enum(struct module* module, const char* typename, 00291 struct symt* basetype) 00292 { 00293 struct symt_enum* sym; 00294 00295 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 00296 { 00297 sym->symt.tag = SymTagEnum; 00298 sym->name = (typename) ? pool_strdup(&module->pool, typename) : NULL; 00299 sym->base_type = basetype; 00300 vector_init(&sym->vchildren, sizeof(struct symt*), 8); 00301 } 00302 return sym; 00303 } 00304 00305 BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type, 00306 const char* name, int value) 00307 { 00308 struct symt_data* e; 00309 struct symt** p; 00310 00311 assert(enum_type->symt.tag == SymTagEnum); 00312 e = pool_alloc(&module->pool, sizeof(*e)); 00313 if (e == NULL) return FALSE; 00314 00315 e->symt.tag = SymTagData; 00316 e->hash_elt.name = pool_strdup(&module->pool, name); 00317 e->hash_elt.next = NULL; 00318 e->kind = DataIsConstant; 00319 e->container = &enum_type->symt; 00320 e->type = enum_type->base_type; 00321 e->u.value.n1.n2.vt = VT_I4; 00322 e->u.value.n1.n2.n3.lVal = value; 00323 00324 p = vector_add(&enum_type->vchildren, &module->pool); 00325 if (!p) return FALSE; /* FIXME we leak e */ 00326 *p = &e->symt; 00327 00328 return TRUE; 00329 } 00330 00331 struct symt_array* symt_new_array(struct module* module, int min, int max, 00332 struct symt* base, struct symt* index) 00333 { 00334 struct symt_array* sym; 00335 00336 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 00337 { 00338 sym->symt.tag = SymTagArrayType; 00339 sym->start = min; 00340 sym->end = max; 00341 sym->base_type = base; 00342 sym->index_type = index; 00343 symt_add_type(module, &sym->symt); 00344 } 00345 return sym; 00346 } 00347 00348 static inline DWORD symt_array_count(struct module* module, const struct symt_array* array) 00349 { 00350 if (array->end < 0) 00351 { 00352 DWORD64 elem_size; 00353 /* One could want to also set the array->end field in array, but we won't do it 00354 * as long as all the get_type() helpers use const objects 00355 */ 00356 if (symt_get_info(module, array->base_type, TI_GET_LENGTH, &elem_size) && elem_size) 00357 return -array->end / (DWORD)elem_size; 00358 return 0; 00359 } 00360 return array->end - array->start + 1; 00361 } 00362 00363 struct symt_function_signature* symt_new_function_signature(struct module* module, 00364 struct symt* ret_type, 00365 enum CV_call_e call_conv) 00366 { 00367 struct symt_function_signature* sym; 00368 00369 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 00370 { 00371 sym->symt.tag = SymTagFunctionType; 00372 sym->rettype = ret_type; 00373 vector_init(&sym->vchildren, sizeof(struct symt*), 4); 00374 sym->call_conv = call_conv; 00375 symt_add_type(module, &sym->symt); 00376 } 00377 return sym; 00378 } 00379 00380 BOOL symt_add_function_signature_parameter(struct module* module, 00381 struct symt_function_signature* sig_type, 00382 struct symt* param) 00383 { 00384 struct symt** p; 00385 struct symt_function_arg_type* arg; 00386 00387 assert(sig_type->symt.tag == SymTagFunctionType); 00388 arg = pool_alloc(&module->pool, sizeof(*arg)); 00389 if (!arg) return FALSE; 00390 arg->symt.tag = SymTagFunctionArgType; 00391 arg->arg_type = param; 00392 arg->container = &sig_type->symt; 00393 p = vector_add(&sig_type->vchildren, &module->pool); 00394 if (!p) return FALSE; /* FIXME we leak arg */ 00395 *p = &arg->symt; 00396 00397 return TRUE; 00398 } 00399 00400 struct symt_pointer* symt_new_pointer(struct module* module, struct symt* ref_type, unsigned long size) 00401 { 00402 struct symt_pointer* sym; 00403 00404 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 00405 { 00406 sym->symt.tag = SymTagPointerType; 00407 sym->pointsto = ref_type; 00408 sym->size = size; 00409 symt_add_type(module, &sym->symt); 00410 } 00411 return sym; 00412 } 00413 00414 struct symt_typedef* symt_new_typedef(struct module* module, struct symt* ref, 00415 const char* name) 00416 { 00417 struct symt_typedef* sym; 00418 00419 if ((sym = pool_alloc(&module->pool, sizeof(*sym)))) 00420 { 00421 sym->symt.tag = SymTagTypedef; 00422 sym->type = ref; 00423 sym->hash_elt.name = pool_strdup(&module->pool, name); 00424 hash_table_add(&module->ht_types, &sym->hash_elt); 00425 symt_add_type(module, &sym->symt); 00426 } 00427 return sym; 00428 } 00429 00430 /****************************************************************** 00431 * SymEnumTypes (DBGHELP.@) 00432 * 00433 */ 00434 BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll, 00435 PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, 00436 PVOID UserContext) 00437 { 00438 struct module_pair pair; 00439 char buffer[sizeof(SYMBOL_INFO) + 256]; 00440 SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer; 00441 const char* tmp; 00442 struct symt* type; 00443 DWORD64 size; 00444 unsigned int i; 00445 00446 TRACE("(%p %s %p %p)\n", 00447 hProcess, wine_dbgstr_longlong(BaseOfDll), EnumSymbolsCallback, 00448 UserContext); 00449 00450 if (!(pair.pcs = process_find_by_handle(hProcess))) return FALSE; 00451 pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN); 00452 if (!module_get_debug(&pair)) return FALSE; 00453 00454 sym_info->SizeOfStruct = sizeof(SYMBOL_INFO); 00455 sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO); 00456 00457 for (i=0; i<vector_length(&pair.effective->vtypes); i++) 00458 { 00459 type = *(struct symt**)vector_at(&pair.effective->vtypes, i); 00460 sym_info->TypeIndex = symt_ptr2index(pair.effective, type); 00461 sym_info->info = 0; /* FIXME */ 00462 symt_get_info(pair.effective, type, TI_GET_LENGTH, &size); 00463 sym_info->Size = size; 00464 sym_info->ModBase = pair.requested->module.BaseOfImage; 00465 sym_info->Flags = 0; /* FIXME */ 00466 sym_info->Value = 0; /* FIXME */ 00467 sym_info->Address = 0; /* FIXME */ 00468 sym_info->Register = 0; /* FIXME */ 00469 sym_info->Scope = 0; /* FIXME */ 00470 sym_info->Tag = type->tag; 00471 tmp = symt_get_name(type); 00472 if (tmp) 00473 { 00474 sym_info->NameLen = min(strlen(tmp),sym_info->MaxNameLen-1); 00475 memcpy(sym_info->Name, tmp, sym_info->NameLen); 00476 sym_info->Name[sym_info->NameLen] = '\0'; 00477 } 00478 else 00479 sym_info->Name[sym_info->NameLen = 0] = '\0'; 00480 if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break; 00481 } 00482 return TRUE; 00483 } 00484 00485 struct enum_types_AtoW 00486 { 00487 char buffer[sizeof(SYMBOL_INFOW) + 256 * sizeof(WCHAR)]; 00488 void* user; 00489 PSYM_ENUMERATESYMBOLS_CALLBACKW callback; 00490 }; 00491 00492 static BOOL CALLBACK enum_types_AtoW(PSYMBOL_INFO si, ULONG addr, PVOID _et) 00493 { 00494 struct enum_types_AtoW* et = _et; 00495 SYMBOL_INFOW* siW = (SYMBOL_INFOW*)et->buffer; 00496 00497 copy_symbolW(siW, si); 00498 return et->callback(siW, addr, et->user); 00499 } 00500 00501 /****************************************************************** 00502 * SymEnumTypesW (DBGHELP.@) 00503 * 00504 */ 00505 BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll, 00506 PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, 00507 PVOID UserContext) 00508 { 00509 struct enum_types_AtoW et; 00510 00511 et.callback = EnumSymbolsCallback; 00512 et.user = UserContext; 00513 00514 return SymEnumTypes(hProcess, BaseOfDll, enum_types_AtoW, &et); 00515 } 00516 00517 /****************************************************************** 00518 * symt_get_info 00519 * 00520 * Retrieves information about a symt (either symbol or type) 00521 */ 00522 BOOL symt_get_info(struct module* module, const struct symt* type, 00523 IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo) 00524 { 00525 unsigned len; 00526 00527 if (!type) return FALSE; 00528 00529 /* helper to typecast pInfo to its expected type (_t) */ 00530 #define X(_t) (*((_t*)pInfo)) 00531 00532 switch (req) 00533 { 00534 case TI_FINDCHILDREN: 00535 { 00536 const struct vector* v; 00537 struct symt** pt; 00538 unsigned i; 00539 TI_FINDCHILDREN_PARAMS* tifp = pInfo; 00540 00541 switch (type->tag) 00542 { 00543 case SymTagUDT: v = &((const struct symt_udt*)type)->vchildren; break; 00544 case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break; 00545 case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break; 00546 case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break; 00547 default: 00548 FIXME("Unsupported sym-tag %s for find-children\n", 00549 symt_get_tag_str(type->tag)); 00550 return FALSE; 00551 } 00552 for (i = 0; i < tifp->Count; i++) 00553 { 00554 if (!(pt = vector_at(v, tifp->Start + i))) return FALSE; 00555 tifp->ChildId[i] = symt_ptr2index(module, *pt); 00556 } 00557 } 00558 break; 00559 00560 case TI_GET_ADDRESS: 00561 return symt_get_address(type, (ULONG64*)pInfo); 00562 00563 case TI_GET_BASETYPE: 00564 switch (type->tag) 00565 { 00566 case SymTagBaseType: 00567 X(DWORD) = ((const struct symt_basic*)type)->bt; 00568 break; 00569 case SymTagEnum: 00570 X(DWORD) = btInt; 00571 break; 00572 default: 00573 return FALSE; 00574 } 00575 break; 00576 00577 case TI_GET_BITPOSITION: 00578 if (type->tag == SymTagData && 00579 ((const struct symt_data*)type)->kind == DataIsMember && 00580 ((const struct symt_data*)type)->u.member.length != 0) 00581 X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7; 00582 else return FALSE; 00583 break; 00584 00585 case TI_GET_CHILDRENCOUNT: 00586 switch (type->tag) 00587 { 00588 case SymTagUDT: 00589 X(DWORD) = vector_length(&((const struct symt_udt*)type)->vchildren); 00590 break; 00591 case SymTagEnum: 00592 X(DWORD) = vector_length(&((const struct symt_enum*)type)->vchildren); 00593 break; 00594 case SymTagFunctionType: 00595 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren); 00596 break; 00597 case SymTagFunction: 00598 X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren); 00599 break; 00600 case SymTagPointerType: /* MS does it that way */ 00601 case SymTagArrayType: /* MS does it that way */ 00602 case SymTagThunk: /* MS does it that way */ 00603 X(DWORD) = 0; 00604 break; 00605 default: 00606 FIXME("Unsupported sym-tag %s for get-children-count\n", 00607 symt_get_tag_str(type->tag)); 00608 /* fall through */ 00609 case SymTagData: 00610 case SymTagPublicSymbol: 00611 case SymTagBaseType: 00612 return FALSE; 00613 } 00614 break; 00615 00616 case TI_GET_COUNT: 00617 switch (type->tag) 00618 { 00619 case SymTagArrayType: 00620 X(DWORD) = symt_array_count(module, (const struct symt_array*)type); 00621 break; 00622 case SymTagFunctionType: 00623 /* this seems to be wrong for (future) C++ methods, where 'this' parameter 00624 * should be included in this value (and not in GET_CHILDREN_COUNT) 00625 */ 00626 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren); 00627 break; 00628 default: return FALSE; 00629 } 00630 break; 00631 00632 case TI_GET_DATAKIND: 00633 if (type->tag != SymTagData) return FALSE; 00634 X(DWORD) = ((const struct symt_data*)type)->kind; 00635 break; 00636 00637 case TI_GET_LENGTH: 00638 switch (type->tag) 00639 { 00640 case SymTagBaseType: 00641 X(DWORD64) = ((const struct symt_basic*)type)->size; 00642 break; 00643 case SymTagFunction: 00644 X(DWORD64) = ((const struct symt_function*)type)->size; 00645 break; 00646 case SymTagPointerType: 00647 X(DWORD64) = ((const struct symt_pointer*)type)->size; 00648 break; 00649 case SymTagUDT: 00650 X(DWORD64) = ((const struct symt_udt*)type)->size; 00651 break; 00652 case SymTagEnum: 00653 X(DWORD64) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */ 00654 break; 00655 case SymTagData: 00656 if (((const struct symt_data*)type)->kind != DataIsMember || 00657 !((const struct symt_data*)type)->u.member.length) 00658 return FALSE; 00659 X(DWORD64) = ((const struct symt_data*)type)->u.member.length; 00660 break; 00661 case SymTagArrayType: 00662 if (!symt_get_info(module, ((const struct symt_array*)type)->base_type, 00663 TI_GET_LENGTH, pInfo)) 00664 return FALSE; 00665 X(DWORD64) *= symt_array_count(module, (const struct symt_array*)type); 00666 break; 00667 case SymTagPublicSymbol: 00668 X(DWORD64) = ((const struct symt_public*)type)->size; 00669 break; 00670 case SymTagTypedef: 00671 return symt_get_info(module, ((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo); 00672 case SymTagThunk: 00673 X(DWORD64) = ((const struct symt_thunk*)type)->size; 00674 break; 00675 case SymTagLabel: 00676 X(DWORD64) = 0; 00677 break; 00678 default: 00679 FIXME("Unsupported sym-tag %s for get-length\n", 00680 symt_get_tag_str(type->tag)); 00681 /* fall through */ 00682 case SymTagFunctionType: 00683 return 0; 00684 } 00685 break; 00686 00687 case TI_GET_LEXICALPARENT: 00688 switch (type->tag) 00689 { 00690 case SymTagBlock: 00691 X(DWORD) = symt_ptr2index(module, ((const struct symt_block*)type)->container); 00692 break; 00693 case SymTagData: 00694 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->container); 00695 break; 00696 case SymTagFunction: 00697 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->container); 00698 break; 00699 case SymTagThunk: 00700 X(DWORD) = symt_ptr2index(module, ((const struct symt_thunk*)type)->container); 00701 break; 00702 case SymTagFunctionArgType: 00703 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->container); 00704 break; 00705 default: 00706 FIXME("Unsupported sym-tag %s for get-lexical-parent\n", 00707 symt_get_tag_str(type->tag)); 00708 return FALSE; 00709 } 00710 break; 00711 00712 case TI_GET_NESTED: 00713 switch (type->tag) 00714 { 00715 case SymTagUDT: 00716 case SymTagEnum: 00717 X(DWORD) = 0; 00718 break; 00719 default: 00720 return FALSE; 00721 } 00722 break; 00723 00724 case TI_GET_OFFSET: 00725 switch (type->tag) 00726 { 00727 case SymTagData: 00728 switch (((const struct symt_data*)type)->kind) 00729 { 00730 case DataIsParam: 00731 case DataIsLocal: 00732 X(ULONG) = ((const struct symt_data*)type)->u.var.offset; 00733 break; 00734 case DataIsMember: 00735 X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3; 00736 break; 00737 default: 00738 FIXME("Unknown kind (%u) for get-offset\n", 00739 ((const struct symt_data*)type)->kind); 00740 return FALSE; 00741 } 00742 break; 00743 default: 00744 FIXME("Unsupported sym-tag %s for get-offset\n", 00745 symt_get_tag_str(type->tag)); 00746 return FALSE; 00747 } 00748 break; 00749 00750 case TI_GET_SYMNAME: 00751 { 00752 const char* name = symt_get_name(type); 00753 if (!name) return FALSE; 00754 len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0); 00755 X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00756 if (!X(WCHAR*)) return FALSE; 00757 MultiByteToWideChar(CP_ACP, 0, name, -1, X(WCHAR*), len); 00758 } 00759 break; 00760 00761 case TI_GET_SYMTAG: 00762 X(DWORD) = type->tag; 00763 break; 00764 00765 case TI_GET_TYPE: 00766 case TI_GET_TYPEID: 00767 switch (type->tag) 00768 { 00769 /* hierarchical => hierarchical */ 00770 case SymTagArrayType: 00771 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->base_type); 00772 break; 00773 case SymTagPointerType: 00774 X(DWORD) = symt_ptr2index(module, ((const struct symt_pointer*)type)->pointsto); 00775 break; 00776 case SymTagFunctionType: 00777 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_signature*)type)->rettype); 00778 break; 00779 case SymTagTypedef: 00780 X(DWORD) = symt_ptr2index(module, ((const struct symt_typedef*)type)->type); 00781 break; 00782 /* lexical => hierarchical */ 00783 case SymTagData: 00784 X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->type); 00785 break; 00786 case SymTagFunction: 00787 X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->type); 00788 break; 00789 case SymTagEnum: 00790 X(DWORD) = symt_ptr2index(module, ((const struct symt_enum*)type)->base_type); 00791 break; 00792 case SymTagFunctionArgType: 00793 X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->arg_type); 00794 break; 00795 default: 00796 FIXME("Unsupported sym-tag %s for get-type\n", 00797 symt_get_tag_str(type->tag)); 00798 /* fall through */ 00799 case SymTagPublicSymbol: 00800 case SymTagThunk: 00801 case SymTagLabel: 00802 return FALSE; 00803 } 00804 break; 00805 00806 case TI_GET_UDTKIND: 00807 if (type->tag != SymTagUDT) return FALSE; 00808 X(DWORD) = ((const struct symt_udt*)type)->kind; 00809 break; 00810 00811 case TI_GET_VALUE: 00812 if (type->tag != SymTagData) return FALSE; 00813 switch (((const struct symt_data*)type)->kind) 00814 { 00815 case DataIsConstant: X(VARIANT) = ((const struct symt_data*)type)->u.value; break; 00816 case DataIsLocal: 00817 case DataIsParam: 00818 { 00819 struct location loc = ((const struct symt_data*)type)->u.var; 00820 unsigned i; 00821 struct module_format* modfmt; 00822 00823 if (loc.kind < loc_user) return FALSE; 00824 for (i = 0; i < DFI_LAST; i++) 00825 { 00826 modfmt = module->format_info[i]; 00827 if (modfmt && modfmt->loc_compute) 00828 { 00829 modfmt->loc_compute(module->process, modfmt, 00830 (const struct symt_function*)((const struct symt_data*)type)->container, &loc); 00831 break; 00832 } 00833 } 00834 if (loc.kind != loc_absolute) return FALSE; 00835 X(VARIANT).n1.n2.vt = VT_UI4; /* FIXME */ 00836 X(VARIANT).n1.n2.n3.uiVal = loc.offset; 00837 } 00838 break; 00839 default: return FALSE; 00840 } 00841 break; 00842 00843 case TI_GET_CALLING_CONVENTION: 00844 if (type->tag != SymTagFunctionType) return FALSE; 00845 if (((const struct symt_function_signature*)type)->call_conv == -1) 00846 { 00847 FIXME("No support for calling convention for this signature\n"); 00848 X(DWORD) = CV_CALL_FAR_C; /* FIXME */ 00849 } 00850 else X(DWORD) = ((const struct symt_function_signature*)type)->call_conv; 00851 break; 00852 case TI_GET_ARRAYINDEXTYPEID: 00853 if (type->tag != SymTagArrayType) return FALSE; 00854 X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->index_type); 00855 break; 00856 00857 case TI_GET_CLASSPARENTID: 00858 /* FIXME: we don't support properly C++ for now, pretend this symbol doesn't 00859 * belong to a parent class 00860 */ 00861 return FALSE; 00862 00863 #undef X 00864 00865 case TI_GET_ADDRESSOFFSET: 00866 case TI_GET_SYMINDEX: 00867 case TI_GET_THISADJUST: 00868 case TI_GET_VIRTUALBASECLASS: 00869 case TI_GET_VIRTUALBASEPOINTEROFFSET: 00870 case TI_GET_VIRTUALTABLESHAPEID: 00871 case TI_IS_EQUIV_TO: 00872 FIXME("Unsupported GetInfo request (%u)\n", req); 00873 return FALSE; 00874 default: 00875 FIXME("Unknown GetInfo request (%u)\n", req); 00876 return FALSE; 00877 } 00878 00879 return TRUE; 00880 } 00881 00882 /****************************************************************** 00883 * SymGetTypeInfo (DBGHELP.@) 00884 * 00885 */ 00886 BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase, 00887 ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType, 00888 PVOID pInfo) 00889 { 00890 struct module_pair pair; 00891 00892 pair.pcs = process_find_by_handle(hProcess); 00893 if (!pair.pcs) return FALSE; 00894 00895 pair.requested = module_find_by_addr(pair.pcs, ModBase, DMT_UNKNOWN); 00896 if (!module_get_debug(&pair)) 00897 { 00898 FIXME("Someone didn't properly set ModBase (%s)\n", wine_dbgstr_longlong(ModBase)); 00899 return FALSE; 00900 } 00901 00902 return symt_get_info(pair.effective, symt_index2ptr(pair.effective, TypeId), GetType, pInfo); 00903 } 00904 00905 /****************************************************************** 00906 * SymGetTypeFromName (DBGHELP.@) 00907 * 00908 */ 00909 BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, ULONG64 BaseOfDll, 00910 PCSTR Name, PSYMBOL_INFO Symbol) 00911 { 00912 struct process* pcs = process_find_by_handle(hProcess); 00913 struct module_pair pair; 00914 struct symt* type; 00915 00916 if (!pcs) return FALSE; 00917 pair.requested = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN); 00918 if (!module_get_debug(&pair)) return FALSE; 00919 type = symt_find_type_by_name(pair.effective, SymTagNull, Name); 00920 if (!type) return FALSE; 00921 Symbol->TypeIndex = symt_ptr2index(pair.effective, type); 00922 00923 return TRUE; 00924 } Generated on Sun May 27 2012 04:18:17 for ReactOS by
1.7.6.1
|