Commit be849dec authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: First stab at supporting calling convention in function signature.

parent 750575cc
...@@ -220,6 +220,7 @@ struct symt_function_signature ...@@ -220,6 +220,7 @@ struct symt_function_signature
struct symt symt; struct symt symt;
struct symt* rettype; struct symt* rettype;
struct vector vchildren; struct vector vchildren;
enum CV_call_e call_conv;
}; };
struct symt_function_arg_type struct symt_function_arg_type
...@@ -472,7 +473,8 @@ extern struct symt_array* ...@@ -472,7 +473,8 @@ extern struct symt_array*
struct symt* base); struct symt* base);
extern struct symt_function_signature* extern struct symt_function_signature*
symt_new_function_signature(struct module* module, 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, extern BOOL symt_add_function_signature_parameter(struct module* module,
struct symt_function_signature* sig, struct symt_function_signature* sig,
struct symt* param); struct symt* param);
......
...@@ -443,6 +443,17 @@ typedef enum dwarf_operation_e { ...@@ -443,6 +443,17 @@ typedef enum dwarf_operation_e {
DW_OP_nop = 0x96 DW_OP_nop = 0x96
} dwarf_operation_t; } 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 * Parsers
*/ */
...@@ -1876,6 +1887,8 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar ...@@ -1876,6 +1887,8 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar
unsigned char decl_line = 0; unsigned char decl_line = 0;
dwarf2_abbrev_entry_attr_t* attr = NULL; dwarf2_abbrev_entry_attr_t* attr = NULL;
unsigned long next_sibling = 0; 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); 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 ...@@ -1908,6 +1921,14 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar
case DW_AT_inline: case DW_AT_inline:
inl_flags = dwarf2_parse_byte(ctx); inl_flags = dwarf2_parse_byte(ctx);
break; 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 /* not work yet, need parsing .debug_line and using Compil Unit stmt_list
case DW_AT_decl_file: case DW_AT_decl_file:
decl_file = dwarf2_parse_byte(ctx); decl_file = dwarf2_parse_byte(ctx);
...@@ -1921,7 +1942,7 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar ...@@ -1921,7 +1942,7 @@ static struct symt_function* dwarf2_parse_subprogram(struct module* module, dwar
dwarf2_parse_attr(attr, ctx); 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) { if (!is_decl) {
func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt); func_type = symt_new_function(module, compiland, name, addr, size, &sig_type->symt);
if (low_pc && high_pc) { if (low_pc && high_pc) {
......
...@@ -726,11 +726,12 @@ static int codeview_add_type_struct(struct module* module, unsigned int typeno, ...@@ -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, 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; struct symt* symt;
symt = &symt_new_function_signature(module, 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); return codeview_add_type(typeno, symt);
} }
...@@ -916,25 +917,29 @@ static int codeview_parse_type_table(struct module* module, const BYTE* table, ...@@ -916,25 +917,29 @@ static int codeview_parse_type_table(struct module* module, const BYTE* table,
break; break;
case LF_PROCEDURE_V1: case LF_PROCEDURE_V1:
retv = codeview_new_func_signature(module, curr_type, retv = codeview_new_func_signature(module, curr_type,
type->procedure_v1.rvtype); type->procedure_v1.rvtype,
type->procedure_v1.call);
break; break;
case LF_PROCEDURE_V2: case LF_PROCEDURE_V2:
retv = codeview_new_func_signature(module, curr_type, retv = codeview_new_func_signature(module, curr_type,
type->procedure_v2.rvtype); type->procedure_v2.rvtype,
type->procedure_v2.call);
break; break;
case LF_MFUNCTION_V1: case LF_MFUNCTION_V1:
/* FIXME: for C++, this is plain wrong, but as we don't use arg types /* FIXME: for C++, this is plain wrong, but as we don't use arg types
* nor class information, this would just do for now * nor class information, this would just do for now
*/ */
retv = codeview_new_func_signature(module, curr_type, retv = codeview_new_func_signature(module, curr_type,
type->mfunction_v1.rvtype); type->mfunction_v1.rvtype,
type->mfunction_v1.call);
break; break;
case LF_MFUNCTION_V2: case LF_MFUNCTION_V2:
/* FIXME: for C++, this is plain wrong, but as we don't use arg types /* FIXME: for C++, this is plain wrong, but as we don't use arg types
* nor class information, this would just do for now * nor class information, this would just do for now
*/ */
retv = codeview_new_func_signature(module, curr_type, retv = codeview_new_func_signature(module, curr_type,
type->mfunction_v2.rvtype); type->mfunction_v2.rvtype,
type->mfunction_v2.call);
break; break;
case LF_ARGLIST_V1: case LF_ARGLIST_V1:
case LF_ARGLIST_V2: case LF_ARGLIST_V2:
......
...@@ -848,7 +848,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ ...@@ -848,7 +848,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ
break; break;
case 'f': case 'f':
PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); 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; break;
case 'e': case 'e':
new_dt = &symt_new_enum(ptd->module, typename)->symt; 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 ...@@ -930,7 +930,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ
{ {
ptd->ptr++; ptd->ptr++;
PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); 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 else
{ {
...@@ -940,7 +940,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ ...@@ -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, stabs_pts_read_type_def(ptd, NULL, &cls_dt) == -1);
PTS_ABORTIF(ptd, *ptd->ptr++ != ','); PTS_ABORTIF(ptd, *ptd->ptr++ != ',');
PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &ref_dt) == -1); 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 == ',') while (*ptd->ptr == ',')
{ {
ptd->ptr++; ptd->ptr++;
...@@ -1422,7 +1422,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, ...@@ -1422,7 +1422,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
(load_offset + stab_ptr->n_value - curr_func->address) : 0); (load_offset + stab_ptr->n_value - curr_func->address) : 0);
} }
func_type = symt_new_function_signature(module, func_type = symt_new_function_signature(module,
stabs_parse_type(ptr)); stabs_parse_type(ptr), -1);
curr_func = symt_new_function(module, compiland, symname, curr_func = symt_new_function(module, compiland, symname,
load_offset + stab_ptr->n_value, 0, load_offset + stab_ptr->n_value, 0,
&func_type->symt); &func_type->symt);
......
...@@ -298,7 +298,8 @@ struct symt_array* symt_new_array(struct module* module, int min, int max, ...@@ -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_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; struct symt_function_signature* sym;
...@@ -307,6 +308,7 @@ struct symt_function_signature* symt_new_function_signature(struct module* modul ...@@ -307,6 +308,7 @@ struct symt_function_signature* symt_new_function_signature(struct module* modul
sym->symt.tag = SymTagFunctionType; sym->symt.tag = SymTagFunctionType;
sym->rettype = ret_type; sym->rettype = ret_type;
vector_init(&sym->vchildren, sizeof(struct symt*), 4); vector_init(&sym->vchildren, sizeof(struct symt*), 4);
sym->call_conv = call_conv;
symt_add_type(module, &sym->symt); symt_add_type(module, &sym->symt);
} }
return sym; return sym;
...@@ -735,11 +737,20 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req, ...@@ -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; X(VARIANT) = ((const struct symt_data*)type)->u.value;
break; 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 #undef X
case TI_GET_ADDRESSOFFSET: case TI_GET_ADDRESSOFFSET:
case TI_GET_ARRAYINDEXTYPEID: case TI_GET_ARRAYINDEXTYPEID:
case TI_GET_CALLING_CONVENTION:
case TI_GET_CLASSPARENTID: case TI_GET_CLASSPARENTID:
case TI_GET_SYMINDEX: case TI_GET_SYMINDEX:
case TI_GET_THISADJUST: case TI_GET_THISADJUST:
...@@ -749,6 +760,9 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req, ...@@ -749,6 +760,9 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
case TI_IS_EQUIV_TO: case TI_IS_EQUIV_TO:
FIXME("Unsupported GetInfo request (%u)\n", req); FIXME("Unsupported GetInfo request (%u)\n", req);
return FALSE; return FALSE;
default:
FIXME("Unknown GetInfo request (%u)\n", req);
return FALSE;
} }
return TRUE; return TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment