diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 0a014095b84..4faae4d0344 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -246,7 +246,7 @@ struct symt_array { struct symt symt; int start; - int end; + int end; /* end index if > 0, or -array_len (in bytes) if < 0 */ struct symt* base_type; struct symt* index_type; }; diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index d31dd712dba..34de9164796 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -586,15 +586,8 @@ static struct symt* codeview_add_type_array(struct codeview_type_parse* ctp, { struct symt* elem = codeview_fetch_type(ctp, elemtype, FALSE); struct symt* index = codeview_fetch_type(ctp, indextype, FALSE); - DWORD arr_max = 0; - if (elem) - { - DWORD64 elem_size; - symt_get_info(elem, TI_GET_LENGTH, &elem_size); - if (elem_size) arr_max = arr_len / (DWORD)elem_size; - } - return &symt_new_array(ctp->module, 0, arr_max, elem, index)->symt; + return &symt_new_array(ctp->module, 0, -arr_len, elem, index)->symt; } static int codeview_add_type_enum_field_list(struct module* module, diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index 947eb49095e..3955815356d 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -304,6 +304,21 @@ struct symt_array* symt_new_array(struct module* module, int min, int max, return sym; } +static inline DWORD symt_array_count(const struct symt_array* array) +{ + if (array->end < 0) + { + DWORD64 elem_size; + /* One could want to also set the array->end field in array, but we won't do it + * as long as all the get_type() helpers use const objects + */ + if (symt_get_info(array->base_type, TI_GET_LENGTH, &elem_size) && elem_size) + return -array->end / (DWORD)elem_size; + return 0; + } + return array->end - array->start + 1; +} + struct symt_function_signature* symt_new_function_signature(struct module* module, struct symt* ret_type, enum CV_call_e call_conv) @@ -597,8 +612,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req, switch (type->tag) { case SymTagArrayType: - X(DWORD) = ((const struct symt_array*)type)->end - - ((const struct symt_array*)type)->start + 1; + X(DWORD) = symt_array_count((const struct symt_array*)type); break; case SymTagFunctionType: /* this seems to be wrong for (future) C++ methods, where 'this' parameter @@ -643,8 +657,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req, if (!symt_get_info(((const struct symt_array*)type)->base_type, TI_GET_LENGTH, pInfo)) return FALSE; - X(DWORD64) *= ((const struct symt_array*)type)->end - - ((const struct symt_array*)type)->start + 1; + X(DWORD64) *= symt_array_count((const struct symt_array*)type); break; case SymTagPublicSymbol: X(DWORD64) = ((const struct symt_public*)type)->size;