ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

type.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.