diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 12911623514..8d8cb7025a9 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -220,6 +220,7 @@ struct symt_function_signature struct symt symt; struct symt* rettype; struct vector vchildren; + enum CV_call_e call_conv; }; struct symt_function_arg_type @@ -472,7 +473,8 @@ extern struct symt_array* struct symt* base); extern struct symt_function_signature* symt_new_function_signature(struct module* module, - struct symt* ret_type); + struct symt* ret_type, + enum CV_call_e call_conv); extern BOOL symt_add_function_signature_parameter(struct module* module, struct symt_function_signature* sig, struct symt* param); diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index f16dd63bc7f..946852e3802 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -443,6 +443,17 @@ typedef enum dwarf_operation_e { DW_OP_nop = 0x96 } dwarf_operation_t; +enum dwarf_calling_convention +{ + DW_CC_normal = 0x1, + DW_CC_program = 0x2, + DW_CC_nocall = 0x3 +}; + +#define DW_CC_lo_user 0x40 +#define DW_CC_hi_user 0xff + + /** * Parsers */ @@ -1876,6 +1887,8 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar unsigned char decl_line = 0; dwarf2_abbrev_entry_attr_t* attr = NULL; unsigned long next_sibling = 0; + enum CV_call_e call_conv = CV_CALL_FAR_C; /* FIXME: assuming C source code */ + unsigned cc; TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), entry->entry_code); @@ -1908,6 +1921,14 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar case DW_AT_inline: inl_flags = dwarf2_parse_byte(ctx); break; + case DW_AT_calling_convention: + switch (cc = dwarf2_parse_byte(ctx)) + { + case DW_CC_normal: break; + case DW_CC_nocall: call_conv = -1; + default: FIXME("Unsupported calling convention %d\n", cc); + } + break; /* not work yet, need parsing .debug_line and using Compil Unit stmt_list case DW_AT_decl_file: decl_file = dwarf2_parse_byte(ctx); @@ -1921,7 +1942,7 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar dwarf2_parse_attr(attr, ctx); } } - sig_type = symt_new_function_signature(module, ret_type); + sig_type = symt_new_function_signature(module, ret_type, call_conv); if (!is_decl) { func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt); if (low_pc && high_pc) { diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 054f27b44a7..93f04746a90 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -726,11 +726,12 @@ static int codeview_add_type_struct(struct module* module, unsigned int typeno, } static int codeview_new_func_signature(struct module* module, unsigned typeno, - unsigned ret_type) + unsigned ret_type, enum CV_call_e call_conv) { struct symt* symt; symt = &symt_new_function_signature(module, - codeview_get_type(ret_type, FALSE))->symt; + codeview_get_type(ret_type, FALSE), + call_conv)->symt; return codeview_add_type(typeno, symt); } @@ -916,25 +917,29 @@ static int codeview_parse_type_table(struct module* module, const BYTE* table, break; case LF_PROCEDURE_V1: retv = codeview_new_func_signature(module, curr_type, - type->procedure_v1.rvtype); + type->procedure_v1.rvtype, + type->procedure_v1.call); break; case LF_PROCEDURE_V2: retv = codeview_new_func_signature(module, curr_type, - type->procedure_v2.rvtype); + type->procedure_v2.rvtype, + type->procedure_v2.call); break; case LF_MFUNCTION_V1: /* FIXME: for C++, this is plain wrong, but as we don't use arg types * nor class information, this would just do for now */ retv = codeview_new_func_signature(module, curr_type, - type->mfunction_v1.rvtype); + type->mfunction_v1.rvtype, + type->mfunction_v1.call); break; case LF_MFUNCTION_V2: /* FIXME: for C++, this is plain wrong, but as we don't use arg types * nor class information, this would just do for now */ retv = codeview_new_func_signature(module, curr_type, - type->mfunction_v2.rvtype); + type->mfunction_v2.rvtype, + type->mfunction_v2.call); break; case LF_ARGLIST_V1: case LF_ARGLIST_V2: diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c index f29f552f448..76629b7e915 100644 --- a/dlls/dbghelp/stabs.c +++ b/dlls/dbghelp/stabs.c @@ -848,7 +848,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ break; case 'f': PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); - new_dt = &symt_new_function_signature(ptd->module, ref_dt)->symt; + new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt; break; case 'e': new_dt = &symt_new_enum(ptd->module, typename)->symt; @@ -930,7 +930,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ { ptd->ptr++; PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); - new_dt = &symt_new_function_signature(ptd->module, ref_dt)->symt; + new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt; } else { @@ -940,7 +940,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &cls_dt) == -1); PTS_ABORTIF(ptd, *ptd->ptr++ != ','); PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); - new_dt = &symt_new_function_signature(ptd->module, ref_dt)->symt; + new_dt = &symt_new_function_signature(ptd->module, ref_dt, -1)->symt; while (*ptd->ptr == ',') { ptd->ptr++; @@ -1422,7 +1422,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, (load_offset + stab_ptr->n_value - curr_func->address) : 0); } func_type = symt_new_function_signature(module, - stabs_parse_type(ptr)); + stabs_parse_type(ptr), -1); curr_func = symt_new_function(module, compiland, symname, load_offset + stab_ptr->n_value, 0, &func_type->symt); diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index fba6942816a..a62d50a749f 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -298,7 +298,8 @@ struct symt_array* symt_new_array(struct module* module, int min, int max, } struct symt_function_signature* symt_new_function_signature(struct module* module, - struct symt* ret_type) + struct symt* ret_type, + enum CV_call_e call_conv) { struct symt_function_signature* sym; @@ -307,6 +308,7 @@ struct symt_function_signature* symt_new_function_signature(struct module* modul sym->symt.tag = SymTagFunctionType; sym->rettype = ret_type; vector_init(&sym->vchildren, sizeof(struct symt*), 4); + sym->call_conv = call_conv; symt_add_type(module, &sym->symt); } return sym; @@ -735,11 +737,20 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req, X(VARIANT) = ((const struct symt_data*)type)->u.value; break; + case TI_GET_CALLING_CONVENTION: + if (type->tag != SymTagFunctionType) return FALSE; + if (((const struct symt_function_signature*)type)->call_conv == -1) + { + FIXME("No support for calling convention for this signature\n"); + X(DWORD) = CV_CALL_FAR_C; /* FIXME */ + } + else X(DWORD) = ((const struct symt_function_signature*)type)->call_conv; + break; + #undef X case TI_GET_ADDRESSOFFSET: case TI_GET_ARRAYINDEXTYPEID: - case TI_GET_CALLING_CONVENTION: case TI_GET_CLASSPARENTID: case TI_GET_SYMINDEX: case TI_GET_THISADJUST: @@ -749,6 +760,9 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req, case TI_IS_EQUIV_TO: FIXME("Unsupported GetInfo request (%u)\n", req); return FALSE; + default: + FIXME("Unknown GetInfo request (%u)\n", req); + return FALSE; } return TRUE;