dbghelp: dwarf: Properly handle function formal parameters.

This commit is contained in:
Eric Pouech 2006-06-18 21:32:00 +02:00 committed by Alexandre Julliard
parent cff41cf9f2
commit 7476f8c840
1 changed files with 74 additions and 8 deletions

View File

@ -59,6 +59,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_dwarf);
* o unspecified parameters * o unspecified parameters
* o inlined functions * o inlined functions
* o line numbers * o line numbers
* o Debug{Start|End}Point
* - Udt * - Udt
* o proper types loading (addresses, bitfield, nesting) * o proper types loading (addresses, bitfield, nesting)
*/ */
@ -955,20 +956,85 @@ static void dwarf2_parse_variable(dwarf2_parse_context_t* ctx,
if (di->abbrev->have_child) FIXME("Unsupported children\n"); if (di->abbrev->have_child) FIXME("Unsupported children\n");
} }
static unsigned dwarf2_map_register(int regno)
{
unsigned reg;
switch (regno)
{
case -1:
/* FIXME: this is a dirty hack */
case -2: reg = 0; break;
case 0: reg = CV_REG_EAX; break;
case 1: reg = CV_REG_ECX; break;
case 2: reg = CV_REG_EDX; break;
case 3: reg = CV_REG_EBX; break;
case 4: reg = CV_REG_ESP; break;
case 5: reg = CV_REG_EBP; break;
case 6: reg = CV_REG_ESI; break;
case 7: reg = CV_REG_EDI; break;
case 8: reg = CV_REG_EIP; break;
case 9: reg = CV_REG_EFLAGS; break;
case 10: reg = CV_REG_CS; break;
case 11: reg = CV_REG_SS; break;
case 12: reg = CV_REG_DS; break;
case 13: reg = CV_REG_ES; break;
case 14: reg = CV_REG_FS; break;
case 15: reg = CV_REG_GS; break;
case 16: case 17: case 18: case 19:
case 20: case 21: case 22: case 23:
reg = CV_REG_ST0 + regno - 16; break;
case 24: reg = CV_REG_CTRL; break;
case 25: reg = CV_REG_STAT; break;
case 26: reg = CV_REG_TAG; break;
/*
reg: fiseg 27
reg: fioff 28
reg: foseg 29
reg: fooff 30
reg: fop 31
*/
case 32: case 33: case 34: case 35:
case 36: case 37: case 38: case 39:
reg = CV_REG_XMM0 + regno - 32; break;
case 40: reg = CV_REG_MXCSR; break;
default:
FIXME("Don't know how to map register %d\n", regno);
return 0;
}
return reg;
}
static void dwarf2_parse_subprogram_parameter(dwarf2_parse_context_t* ctx, static void dwarf2_parse_subprogram_parameter(dwarf2_parse_context_t* ctx,
dwarf2_debug_info_t* di, struct symt_function* func,
struct symt_function_signature* sig_type) struct symt_block* block,
dwarf2_debug_info_t* di)
{ {
struct symt* param_type; struct symt* param_type;
union attribute name; union attribute loc;
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
param_type = dwarf2_lookup_type(ctx, di); param_type = dwarf2_lookup_type(ctx, di);
dwarf2_find_name(ctx, di, &name, "parameter"); if (dwarf2_find_attribute(di, DW_AT_location, &loc))
/* DW_AT_location */ {
if (sig_type) symt_add_function_signature_parameter(ctx->module, sig_type, param_type); union attribute name;
/* FIXME: add variable to func_type */ unsigned long offset;
int in_reg;
dwarf2_find_name(ctx, di, &name, "parameter");
offset = dwarf2_compute_location(ctx, loc.block, &in_reg);
TRACE("found parameter %s/%ld (reg=%d) at %s\n",
name.string, offset, in_reg, dwarf2_debug_ctx(ctx));
symt_add_func_local(ctx->module, func,
DataIsParam, dwarf2_map_register(in_reg), offset,
block, param_type, name.string);
}
if (func && func->type)
symt_add_function_signature_parameter(ctx->module,
(struct symt_function_signature*)func->type,
param_type);
if (di->abbrev->have_child) FIXME("Unsupported children\n"); if (di->abbrev->have_child) FIXME("Unsupported children\n");
} }
@ -1137,7 +1203,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
switch (child->abbrev->tag) switch (child->abbrev->tag)
{ {
case DW_TAG_formal_parameter: case DW_TAG_formal_parameter:
dwarf2_parse_subprogram_parameter(ctx, child, sig_type); dwarf2_parse_subprogram_parameter(ctx, func, NULL, child);
break; break;
case DW_TAG_lexical_block: case DW_TAG_lexical_block:
dwarf2_parse_subprogram_block(ctx, child, func); dwarf2_parse_subprogram_block(ctx, child, func);