[PATCH 06/22] [DbgHelp]: dwarf loclist (infra)

Eric Pouech eric.pouech at wanadoo.fr
Fri Nov 24 15:17:31 CST 2006


- added struct location to help computing a location
- made use of it in dwarf.c to handle correctly variable
  location computation
- split code to handle both location with parse time computation
  (current code) and yet to come run-time computation

A+
---

 dlls/dbghelp/dbghelp_private.h |   21 ++
 dlls/dbghelp/dwarf.c           |  403 ++++++++++++++++++++++------------------
 2 files changed, 246 insertions(+), 178 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index c2082e5..6c80060 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -113,6 +113,27 @@ extern unsigned dbghelp_options;
 /* some more Wine extensions */
 #define SYMOPT_WINE_WITH_ELF_MODULES 0x40000000
 
+enum location_kind {loc_error,          /* reg is the error code */
+                    loc_absolute,       /* offset is the location */
+                    loc_register,       /* reg is the location */
+                    loc_regrel,         /* [reg+offset] is the location */
+                    loc_user,           /* value is debug information dependent,
+                                           reg & offset can be used ad libidem */
+};
+
+enum location_error {loc_err_internal = -1,     /* internal while computing */
+                     loc_err_too_complex = -2,  /* couldn't compute location (even at runtime) */
+                     loc_err_out_of_scope = -3, /* variable isn't available at current address */
+                     loc_err_cant_read = -4,    /* couldn't read memory at given address */
+};
+
+struct location
+{
+    unsigned            kind : 8,
+                        reg;
+    unsigned long       offset;
+};
+
 struct symt
 {
     enum SymTagEnum             tag;
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 8dbe200..6bd0fff 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -185,6 +185,9 @@ struct dwarf2_module_info_s
     dwarf2_section_t            debug_loc;
 };
 
+#define loc_dwarf2_location_list        (loc_user + 0)
+#define loc_dwarf2_block                (loc_user + 1)
+
 /* forward declarations */
 static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* entry);
 
@@ -573,121 +576,196 @@ static void dwarf2_load_one_entry(dwarf2
                                   struct symt_compiland*);
 
 #define Wine_DW_no_register     0x7FFFFFFF
-#define Wine_DW_frame_register  0x7FFFFFFE
-#define Wine_DW_register_deref  0x80000000
 
-static BOOL dwarf2_compute_location(dwarf2_parse_context_t* ctx,
-                                    dwarf2_debug_info_t* di,
-                                    unsigned long dw,
-                                    unsigned long* offset, int* in_register)
+static unsigned dwarf2_map_register(int regno)
 {
-    unsigned long loc[64];
+    unsigned    reg;
+
+    switch (regno)
+    {
+    case Wine_DW_no_register: FIXME("What the heck map reg 0x%x\n",regno); 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 BOOL compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
+                             const struct location* frame)
+{
+    unsigned long stack[64];
     unsigned stk;
+    unsigned char op;
+    BOOL piece_found = FALSE;
+
+    stack[stk = 0] = 0;
+
+    loc->kind = loc_absolute;
+    loc->reg = Wine_DW_no_register;
+
+    while (ctx->data < ctx->end_data)
+    {
+        op = dwarf2_parse_byte(ctx);
+        switch (op)
+        {
+        case DW_OP_addr:    stack[++stk] = dwarf2_parse_addr(ctx); break;
+        case DW_OP_const1u: stack[++stk] = dwarf2_parse_byte(ctx); break;
+        case DW_OP_const1s: stack[++stk] = (long)(signed char)dwarf2_parse_byte(ctx); break;
+        case DW_OP_const2u: stack[++stk] = dwarf2_parse_u2(ctx); break;
+        case DW_OP_const2s: stack[++stk] = (long)(short)dwarf2_parse_u2(ctx); break;
+        case DW_OP_const4u: stack[++stk] = dwarf2_parse_u4(ctx); break;
+        case DW_OP_const4s: stack[++stk] = dwarf2_parse_u4(ctx); break;
+        case DW_OP_constu:  stack[++stk] = dwarf2_leb128_as_unsigned(ctx); break;
+        case DW_OP_consts:  stack[++stk] = dwarf2_leb128_as_signed(ctx); break;
+        case DW_OP_plus_uconst:
+            stack[stk] += dwarf2_leb128_as_unsigned(ctx); break;
+        case DW_OP_reg0:  case DW_OP_reg1:  case DW_OP_reg2:  case DW_OP_reg3:
+        case DW_OP_reg4:  case DW_OP_reg5:  case DW_OP_reg6:  case DW_OP_reg7:
+        case DW_OP_reg8:  case DW_OP_reg9:  case DW_OP_reg10: case DW_OP_reg11:
+        case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15:
+        case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19:
+        case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
+        case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27:
+        case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31:
+        case DW_OP_breg0:  case DW_OP_breg1:  case DW_OP_breg2:  case DW_OP_breg3:
+        case DW_OP_breg4:  case DW_OP_breg5:  case DW_OP_breg6:  case DW_OP_breg7:
+        case DW_OP_breg8:  case DW_OP_breg9:  case DW_OP_breg10: case DW_OP_breg11:
+        case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15:
+        case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19:
+        case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
+        case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27:
+        case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31:
+            /* dbghelp APIs don't know how to cope with this anyway
+             * (for example 'long long' stored in two registers)
+             * FIXME: We should tell winedbg how to deal with it (sigh)
+             */
+            if (!piece_found || (op - DW_OP_reg0 != loc->reg + 1))
+            {
+                if (loc->reg != Wine_DW_no_register)
+                    FIXME("Only supporting one reg (%d -> %d)\n", 
+                          loc->reg, op - DW_OP_reg0);
+                loc->reg = dwarf2_map_register(op - DW_OP_reg0);
+            }
+            if (op >= DW_OP_breg0 && op <= DW_OP_breg31)
+            {
+                stack[++stk] = dwarf2_leb128_as_signed(ctx);
+                loc->kind = loc_regrel;
+            }
+            else
+                loc->kind = loc_register;
+            break;
+        case DW_OP_fbreg:
+            if (loc->reg != Wine_DW_no_register)
+                FIXME("Only supporting one reg (%d -> -2)\n", loc->reg);
+            if (frame && frame->kind == loc_register)
+            {
+                loc->kind = loc_regrel;
+                loc->reg = frame->reg;
+                stack[++stk] = dwarf2_leb128_as_signed(ctx);
+            }
+            else if (frame && frame->kind == loc_regrel)
+            {
+                loc->kind = loc_regrel;
+                loc->reg = frame->reg;
+                stack[++stk] = dwarf2_leb128_as_signed(ctx) + frame->offset;
+            }
+            else
+            {
+                /* FIXME: this could be later optimized by not recomputing
+                 * this very location expression
+                 */
+                loc->kind = loc_dwarf2_block;
+                stack[++stk] = dwarf2_leb128_as_signed(ctx);
+            }
+            break;
+        case DW_OP_piece:
+            {
+                unsigned sz = dwarf2_leb128_as_unsigned(ctx);
+                WARN("Not handling OP_piece directly (size=%d)\n", sz);
+                piece_found = TRUE;
+            }
+            break;
+        default:
+            FIXME("Unhandled attr op: %x\n", op);
+            loc->offset = 0;
+            return FALSE;
+        }
+    }
+    loc->offset = stack[stk];
+    return TRUE;
+}
+
+static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx,
+                                         dwarf2_debug_info_t* di,
+                                         unsigned long dw,
+                                         struct location* loc,
+                                         const struct location* frame)
+{
     struct attribute xloc;
 
     if (!dwarf2_find_attribute(ctx, di, dw, &xloc)) return FALSE;
 
-    if (in_register) *in_register = Wine_DW_no_register;
-
     switch (xloc.form)
     {
     case DW_FORM_data1: case DW_FORM_data2:
-    case DW_FORM_data4: case DW_FORM_data8:
     case DW_FORM_udata: case DW_FORM_sdata:
-        /* we've got a constant */
-        *offset = xloc.u.uvalue;
+        loc->kind = loc_absolute;
+        loc->reg = 0;
+        loc->offset = xloc.u.uvalue;
+        return TRUE;
+    case DW_FORM_data4: case DW_FORM_data8:
+        loc->kind = loc_dwarf2_location_list;
+        loc->reg = Wine_DW_no_register;
+        loc->offset = xloc.u.uvalue;
         return TRUE;
     }
+
     /* assume we have a block form */
-    loc[stk = 0] = 0;
 
     if (xloc.u.block.size)
     {
         dwarf2_traverse_context_t  lctx;
-        unsigned char op;
-        BOOL piece_found = FALSE;
 
         lctx.data = xloc.u.block.ptr;
         lctx.end_data = xloc.u.block.ptr + xloc.u.block.size;
         lctx.word_size = ctx->word_size;
 
-        while (lctx.data < lctx.end_data)
-        {
-            op = dwarf2_parse_byte(&lctx);
-            switch (op)
-            {
-            case DW_OP_addr:    loc[++stk] = dwarf2_parse_addr(&lctx); break;
-            case DW_OP_const1u: loc[++stk] = dwarf2_parse_byte(&lctx); break;
-            case DW_OP_const1s: loc[++stk] = (long)(signed char)dwarf2_parse_byte(&lctx); break;
-            case DW_OP_const2u: loc[++stk] = dwarf2_parse_u2(&lctx); break;
-            case DW_OP_const2s: loc[++stk] = (long)(short)dwarf2_parse_u2(&lctx); break;
-            case DW_OP_const4u: loc[++stk] = dwarf2_parse_u4(&lctx); break;
-            case DW_OP_const4s: loc[++stk] = dwarf2_parse_u4(&lctx); break;
-            case DW_OP_constu:  loc[++stk] = dwarf2_leb128_as_unsigned(&lctx); break;
-            case DW_OP_consts:  loc[++stk] = dwarf2_leb128_as_signed(&lctx); break;
-            case DW_OP_plus_uconst:
-                                loc[stk] += dwarf2_leb128_as_unsigned(&lctx); break;
-            case DW_OP_reg0:  case DW_OP_reg1:  case DW_OP_reg2:  case DW_OP_reg3:
-            case DW_OP_reg4:  case DW_OP_reg5:  case DW_OP_reg6:  case DW_OP_reg7:
-            case DW_OP_reg8:  case DW_OP_reg9:  case DW_OP_reg10: case DW_OP_reg11:
-            case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15:
-            case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19:
-            case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
-            case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27:
-            case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31:
-            case DW_OP_breg0:  case DW_OP_breg1:  case DW_OP_breg2:  case DW_OP_breg3:
-            case DW_OP_breg4:  case DW_OP_breg5:  case DW_OP_breg6:  case DW_OP_breg7:
-            case DW_OP_breg8:  case DW_OP_breg9:  case DW_OP_breg10: case DW_OP_breg11:
-            case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15:
-            case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19:
-            case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
-            case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27:
-            case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31:
-                if (in_register)
-                {
-                    /* dbghelp APIs don't know how to cope with this anyway
-                     * (for example 'long long' stored in two registers)
-                     * FIXME: We should tell winedbg how to deal with it (sigh)
-                     */
-                    if (!piece_found || (op - DW_OP_reg0 != *in_register + 1))
-                    {
-                        if (*in_register != Wine_DW_no_register)
-                            FIXME("Only supporting one reg (%d -> %d)\n", 
-                                  *in_register, op - DW_OP_reg0);
-                        *in_register = op - DW_OP_reg0;
-                    }
-                }
-                else FIXME("Found register, while not expecting it\n");
-                if (op >= DW_OP_breg0 && op <= DW_OP_breg31)
-                {
-                    loc[++stk] = dwarf2_leb128_as_signed(&lctx);
-                    if (in_register) *in_register |= Wine_DW_register_deref;
-                }
-                break;
-            case DW_OP_fbreg:
-                if (in_register)
-                {
-                    if (*in_register != Wine_DW_no_register)
-                        FIXME("Only supporting one reg (%d -> -2)\n", *in_register);
-                    *in_register = Wine_DW_frame_register | Wine_DW_register_deref;
-                }
-                else FIXME("Found register, while not expecting it\n");
-                loc[++stk] = dwarf2_leb128_as_signed(&lctx);
-                break;
-            case DW_OP_piece:
-                {
-                    unsigned sz = dwarf2_leb128_as_unsigned(&lctx);
-                    WARN("Not handling OP_piece directly (size=%d)\n", sz);
-                    piece_found = TRUE;
-                }
-                break;
-            default:
-                FIXME("Unhandled attr op: %x\n", op);
-                return loc[stk];
-            }
-        }
+        compute_location(&lctx, loc, frame);
     }
-    *offset = loc[stk];
     return TRUE;
 }
 
@@ -956,9 +1034,9 @@ static void dwarf2_parse_udt_member(dwar
 {
     struct symt* elt_type;
     struct attribute name;
-    unsigned long offset = 0;
     struct attribute bit_size;
     struct attribute bit_offset;
+    struct location  loc;
 
     assert(parent);
 
@@ -966,8 +1044,19 @@ static void dwarf2_parse_udt_member(dwar
 
     dwarf2_find_name(ctx, di, &name, "udt_member");
     elt_type = dwarf2_lookup_type(ctx, di);
-    if (dwarf2_compute_location(ctx, di, DW_AT_data_member_location, &offset, NULL))
-	TRACE("found member_location at %s -> %lu\n", dwarf2_debug_ctx(ctx), offset);
+    if (dwarf2_compute_location_attr(ctx, di, DW_AT_data_member_location, &loc, NULL))
+    {
+        if (loc.kind != loc_absolute)
+        {
+           FIXME("Found register, while not expecting it\n");
+           loc.offset = 0;
+        }
+        else
+            TRACE("found member_location at %s -> %lu\n",
+                  dwarf2_debug_ctx(ctx), loc.offset);
+    }
+    else
+        loc.offset = 0;
     if (!dwarf2_find_attribute(ctx, di, DW_AT_bit_size, &bit_size))   bit_size.u.uvalue = 0;
     if (dwarf2_find_attribute(ctx, di, DW_AT_bit_offset, &bit_offset))
     {
@@ -984,7 +1073,8 @@ static void dwarf2_parse_udt_member(dwar
     }
     else bit_offset.u.uvalue = 0;
     symt_add_udt_element(ctx->module, parent, name.u.string, elt_type,    
-                         (offset << 3) + bit_offset.u.uvalue, bit_size.u.uvalue);
+                         (loc.offset << 3) + bit_offset.u.uvalue,
+                         bit_size.u.uvalue);
 
     if (di->abbrev->have_child) FIXME("Unsupported children\n");
 }
@@ -1094,63 +1184,13 @@ static struct symt* dwarf2_parse_enumera
     return di->symt;
 }
 
-static unsigned dwarf2_map_register(int regno)
-{
-    unsigned    reg;
-
-    switch (regno)
-    {
-    case Wine_DW_no_register: FIXME("What the heck map reg 0x%x\n",regno); reg = 0; break;
-    /* FIXME: this is a dirty hack */
-    case Wine_DW_frame_register: 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;
-}
-
 /* structure used to pass information around when parsing a subprogram */
 typedef struct dwarf2_subprogram_s
 {
     dwarf2_parse_context_t*     ctx;
     struct symt_compiland*      compiland;
     struct symt_function*       func;
-    unsigned long               frame_offset;
-    int                         frame_reg;
+    struct location             frame;
 } dwarf2_subprogram_t;
 
 /******************************************************************
@@ -1164,47 +1204,60 @@ static void dwarf2_parse_variable(dwarf2
 {
     struct symt* param_type;
     struct attribute name, value;
-    unsigned long offset;
-    int in_reg;
+    struct location loc;
     BOOL is_pmt = di->abbrev->tag == DW_TAG_formal_parameter;
 
     TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
 
     param_type = dwarf2_lookup_type(subpgm->ctx, di);
     dwarf2_find_name(subpgm->ctx, di, &name, "parameter");
-    if (dwarf2_compute_location(subpgm->ctx, di, DW_AT_location, &offset, &in_reg))
+    if (dwarf2_compute_location_attr(subpgm->ctx, di, DW_AT_location,
+                                     &loc, &subpgm->frame))
     {
         struct attribute ext;
 
+        if (loc.kind >= loc_user)
+        {
+            FIXME("Unsupported yet location list in %s on variable %s\n",
+                  subpgm->func->hash_elt.name, name.u.string);
+            return;
+        }
+
+        if (subpgm->frame.kind >= loc_user)
+        {
+            FIXME("Unsupported yet location list in %s on frame for var %s\n",
+                  subpgm->func->hash_elt.name, name.u.string);
+            return;
+        }
+
 	TRACE("found parameter %s/%ld (reg=%d) at %s\n",
-              name.u.string, offset, in_reg, dwarf2_debug_ctx(subpgm->ctx));
-        switch (in_reg & ~Wine_DW_register_deref)
+              name.u.string, loc.offset, loc.reg,
+              dwarf2_debug_ctx(subpgm->ctx));
+        switch (loc.kind)
         {
-        case Wine_DW_no_register:
+        case loc_absolute:
             /* it's a global variable */
             /* FIXME: we don't handle it's scope yet */
             if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_external, &ext))
                 ext.u.uvalue = 0;
             symt_new_global_variable(subpgm->ctx->module, subpgm->compiland,
                                      name.u.string, !ext.u.uvalue,
-                                     subpgm->ctx->module->module.BaseOfImage + offset,
+                                     subpgm->ctx->module->module.BaseOfImage + loc.offset,
                                      0, param_type);
             break;
-        case Wine_DW_frame_register:
-            in_reg = subpgm->frame_reg | Wine_DW_register_deref;
-            offset += subpgm->frame_offset;
-            /* fall through */
-        default:
+        case loc_register:
+        case loc_regrel:
             /* either a pmt/variable relative to frame pointer or
              * pmt/variable in a register
              */
             assert(subpgm->func);
             symt_add_func_local(subpgm->ctx->module, subpgm->func, 
                                 is_pmt ? DataIsParam : DataIsLocal,
-                                dwarf2_map_register(in_reg & ~Wine_DW_register_deref),
-                                in_reg & Wine_DW_register_deref,
-                                offset, block, param_type, name.u.string);
+                                loc.reg, loc.kind == loc_regrel,
+                                loc.offset, block, param_type, name.u.string);
             break;
+        default:
+            FIXME("Unsupported\n");
         }
     }
     if (dwarf2_find_attribute(subpgm->ctx, di, DW_AT_const_value, &value))
@@ -1399,20 +1452,13 @@ static struct symt* dwarf2_parse_subprog
 
     subpgm.ctx = ctx;
     subpgm.compiland = compiland;
-    if (dwarf2_compute_location(ctx, di, DW_AT_frame_base, &subpgm.frame_offset, &subpgm.frame_reg)) {
-        TRACE("For %s got %ld/%d\n", name.u.string, subpgm.frame_offset, subpgm.frame_reg);
-	if (subpgm.frame_reg == Wine_DW_no_register) {
-	   /* Likely a constant, meaning a location list offset.
-	      We do not handle those yet. */
-           /*FIXME("need to handle location lists\n"); */
-           subpgm.frame_reg = 0;
-           subpgm.frame_offset = 0;
-	}
-    }
-    else /* on stack !! */
+    if (!dwarf2_compute_location_attr(ctx, di, DW_AT_frame_base,
+                                      &subpgm.frame, NULL))
     {
-        subpgm.frame_reg = 0;
-        subpgm.frame_offset = 0;
+        /* on stack !! */
+        subpgm.frame.kind = loc_regrel;
+        subpgm.frame.reg = 0;
+        subpgm.frame.offset = 0;
     }
 
     if (di->abbrev->have_child) /** any interest to not have child ? */
@@ -1558,8 +1604,9 @@ static void dwarf2_load_one_entry(dwarf2
             subpgm.ctx = ctx;
             subpgm.compiland = compiland;
             subpgm.func = NULL;
-            subpgm.frame_offset = 0;
-            subpgm.frame_reg = 0;
+            subpgm.frame.kind = loc_absolute;
+            subpgm.frame.offset = 0;
+            subpgm.frame.reg = Wine_DW_no_register;
             dwarf2_parse_variable(&subpgm, NULL, di);
         }
         break;
@@ -1856,7 +1903,7 @@ BOOL dwarf2_parse(struct module* module,
 		  const unsigned char* loclist, unsigned int loclist_size)
 {
     dwarf2_section_t    section[section_max];
-    char*               ptr;
+    unsigned char*      ptr;
     const unsigned char*comp_unit_cursor = debug;
     const unsigned char*end_debug = debug + debug_size;
 
@@ -1877,7 +1924,7 @@ BOOL dwarf2_parse(struct module* module,
          */
         module->dwarf2_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*module->dwarf2_info) + loclist_size);
         if (!module->dwarf2_info) return FALSE;
-        ptr = (char*)(module->dwarf2_info + 1);
+        ptr = (unsigned char*)(module->dwarf2_info + 1);
         memcpy(ptr, loclist, loclist_size);
         module->dwarf2_info->debug_loc.address = ptr;
         module->dwarf2_info->debug_loc.size    = loclist_size;



More information about the wine-patches mailing list