mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 22:54:07 +00:00
dbghelp: Fix conversion of dwarf's basic types into dbghelp's basic types.
Signed-off-by: Eric Pouech <eric.pouech@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
14462bbeab
commit
d94f4747e8
|
@ -213,6 +213,7 @@ typedef struct dwarf2_parse_context_s
|
|||
dwarf2_cuhead_t head;
|
||||
enum unit_status status;
|
||||
dwarf2_traverse_context_t traverse_DIE;
|
||||
unsigned language;
|
||||
} dwarf2_parse_context_t;
|
||||
|
||||
/* stored in the dbghelp's module internal structure for later reuse */
|
||||
|
@ -1450,16 +1451,43 @@ static struct vector* dwarf2_get_di_children(dwarf2_debug_info_t* di)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* reconstruct whether integer is long (contains 'long' only once) */
|
||||
static BOOL is_long(const char* name)
|
||||
{
|
||||
/* we assume name is made only of basic C keywords:
|
||||
* int long short unsigned signed void float double char _Bool _Complex
|
||||
*/
|
||||
const char* p = strstr(name, "long");
|
||||
return p && strstr(p + 4, "long") == NULL;
|
||||
}
|
||||
|
||||
static BOOL is_c_language(dwarf2_parse_context_t* unit_ctx)
|
||||
{
|
||||
return unit_ctx->language == DW_LANG_C ||
|
||||
unit_ctx->language == DW_LANG_C89 ||
|
||||
unit_ctx->language == DW_LANG_C99;
|
||||
}
|
||||
|
||||
static BOOL is_cpp_language(dwarf2_parse_context_t* unit_ctx)
|
||||
{
|
||||
return unit_ctx->language == DW_LANG_C_plus_plus;
|
||||
}
|
||||
|
||||
static struct symt* dwarf2_parse_base_type(dwarf2_debug_info_t* di)
|
||||
{
|
||||
struct attribute name;
|
||||
struct attribute size;
|
||||
struct attribute encoding;
|
||||
enum BasicType bt;
|
||||
BOOL c_language, cpp_language;
|
||||
|
||||
if (di->symt) return di->symt;
|
||||
|
||||
TRACE("%s\n", dwarf2_debug_di(di));
|
||||
|
||||
c_language = is_c_language(di->unit_ctx);
|
||||
cpp_language = is_cpp_language(di->unit_ctx);
|
||||
|
||||
if (!dwarf2_find_attribute(di, DW_AT_name, &name))
|
||||
name.u.string = NULL;
|
||||
if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 0;
|
||||
|
@ -1472,10 +1500,19 @@ static struct symt* dwarf2_parse_base_type(dwarf2_debug_info_t* di)
|
|||
case DW_ATE_boolean: bt = btBool; break;
|
||||
case DW_ATE_complex_float: bt = btComplex; break;
|
||||
case DW_ATE_float: bt = btFloat; break;
|
||||
case DW_ATE_signed: bt = btInt; break;
|
||||
case DW_ATE_unsigned: bt = btUInt; break;
|
||||
case DW_ATE_signed_char: bt = btChar; break;
|
||||
case DW_ATE_unsigned_char: bt = btChar; break;
|
||||
case DW_ATE_signed: bt = ((c_language || cpp_language) && is_long(name.u.string)) ? btLong : btInt; break;
|
||||
case DW_ATE_unsigned:
|
||||
if ((c_language || cpp_language) && is_long(name.u.string)) bt = btULong;
|
||||
else if (cpp_language && !strcmp(name.u.string, "wchar_t")) bt = btWChar;
|
||||
else if (cpp_language && !strcmp(name.u.string, "char8_t")) bt = btChar8;
|
||||
else if (cpp_language && !strcmp(name.u.string, "char16_t")) bt = btChar16;
|
||||
else if (cpp_language && !strcmp(name.u.string, "char32_t")) bt = btChar32;
|
||||
else bt = btUInt;
|
||||
break;
|
||||
/* on Windows, in C, char == signed char, but not in C++ */
|
||||
case DW_ATE_signed_char: bt = (cpp_language && !strcmp(name.u.string, "signed char")) ? btInt : btChar; break;
|
||||
case DW_ATE_unsigned_char: bt = btUInt; break;
|
||||
case DW_ATE_UTF: bt = (size.u.uvalue == 1) ? btChar8 : (size.u.uvalue == 2 ? btChar16 : btChar32); break;
|
||||
default: bt = btNoType; break;
|
||||
}
|
||||
di->symt = &symt_get_basic(bt, size.u.uvalue)->symt;
|
||||
|
@ -1497,7 +1534,15 @@ static struct symt* dwarf2_parse_typedef(dwarf2_debug_info_t* di)
|
|||
ref_type = dwarf2_lookup_type(di);
|
||||
|
||||
if (name.u.string)
|
||||
{
|
||||
/* Note: The MS C compiler has tweaks for WCHAR support.
|
||||
* Even if WCHAR is a typedef to wchar_t, wchar_t is emitted as btUInt/2 (it's defined as
|
||||
* unsigned short, so far so good), while WCHAR is emitted as btWChar/2).
|
||||
*/
|
||||
if ((is_c_language(di->unit_ctx) || is_cpp_language(di->unit_ctx)) && !strcmp(name.u.string, "WCHAR"))
|
||||
ref_type = &symt_get_basic(btWChar, 2)->symt;
|
||||
di->symt = &symt_new_typedef(di->unit_ctx->module_ctx->module, ref_type, name.u.string)->symt;
|
||||
}
|
||||
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
|
||||
return di->symt;
|
||||
}
|
||||
|
@ -2917,6 +2962,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx)
|
|||
unsigned int i;
|
||||
struct attribute stmt_list, low_pc;
|
||||
struct attribute comp_dir;
|
||||
struct attribute language;
|
||||
|
||||
if (!dwarf2_find_attribute(di, DW_AT_name, &name))
|
||||
name.u.string = NULL;
|
||||
|
@ -2927,6 +2973,12 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx)
|
|||
|
||||
if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc))
|
||||
low_pc.u.uvalue = 0;
|
||||
|
||||
if (!dwarf2_find_attribute(di, DW_AT_language, &language))
|
||||
language.u.uvalue = DW_LANG_C;
|
||||
|
||||
ctx->language = language.u.uvalue;
|
||||
|
||||
ctx->compiland = symt_new_compiland(ctx->module_ctx->module, ctx->module_ctx->load_offset + low_pc.u.uvalue,
|
||||
source_new(ctx->module_ctx->module, comp_dir.u.string, name.u.string));
|
||||
dwarf2_cache_cuhead(ctx->module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx->compiland, &ctx->head);
|
||||
|
|
Loading…
Reference in a new issue