[PATCH 5/6] [DbgHelp]: dwarf location

Eric Pouech eric.pouech at wanadoo.fr
Mon Sep 25 15:41:27 CDT 2006


- fix location computation when attribute has a constant form 
  instead of a block form
- restructured the code to more cleanly handle all the computation
  forms

A+
---

 dlls/dbghelp/dwarf.c |   54 ++++++++++++++++++++++++++++----------------------
 1 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 0a606ac..f36ce89 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -571,24 +571,39 @@ #define Wine_DW_no_register     0x7FFFFF
 #define Wine_DW_frame_register  0x7FFFFFFE
 #define Wine_DW_register_deref  0x80000000
 
-static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx,
-                                             struct dwarf2_block* block,
-                                             int* in_register)
+static BOOL dwarf2_compute_location(dwarf2_parse_context_t* ctx,
+                                    dwarf2_debug_info_t* di,
+                                    unsigned long dw,
+                                    unsigned long* offset, int* in_register)
 {
     unsigned long loc[64];
     unsigned stk;
+    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;
+        return TRUE;
+    }
+    /* assume we have a block form */
     loc[stk = 0] = 0;
 
-    if (block->size)
+    if (xloc.u.block.size)
     {
         dwarf2_traverse_context_t  lctx;
         unsigned char op;
         BOOL piece_found = FALSE;
 
-        lctx.data = block->ptr;
-        lctx.end_data = block->ptr + block->size;
+        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)
@@ -667,7 +682,8 @@ static unsigned long dwarf2_compute_loca
             }
         }
     }
-    return loc[stk];
+    *offset = loc[stk];
+    return TRUE;
 }
 
 static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx,
@@ -919,7 +935,6 @@ static void dwarf2_parse_udt_member(dwar
 {
     struct symt* elt_type;
     struct attribute name;
-    struct attribute loc;
     unsigned long offset = 0;
     struct attribute bit_size;
     struct attribute bit_offset;
@@ -930,12 +945,8 @@ static void dwarf2_parse_udt_member(dwar
 
     dwarf2_find_name(ctx, di, &name, "udt_member");
     elt_type = dwarf2_lookup_type(ctx, di);
-    if (dwarf2_find_attribute(ctx, di, DW_AT_data_member_location, &loc))
-    {
-	TRACE("found member_location at %s\n", dwarf2_debug_ctx(ctx));
-        offset = dwarf2_compute_location(ctx, &loc.u.block, NULL);
-        TRACE("found offset:%lu\n", offset); 		  
-    }
+    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_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))
     {
@@ -1131,20 +1142,19 @@ static void dwarf2_parse_variable(dwarf2
                                   dwarf2_debug_info_t* di)
 {
     struct symt* param_type;
-    struct attribute name, loc, value;
+    struct attribute name, value;
+    long offset;
+    int in_reg;
     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_find_attribute(subpgm->ctx, di, DW_AT_location, &loc))
+    if (dwarf2_compute_location(subpgm->ctx, di, DW_AT_location, &offset, &in_reg))
     {
         struct attribute ext;
-        long offset;
-        int in_reg;
 
-        offset = dwarf2_compute_location(subpgm->ctx, &loc.u.block, &in_reg);
 	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)
@@ -1331,7 +1341,6 @@ static struct symt* dwarf2_parse_subprog
     struct attribute high_pc;
     struct attribute is_decl;
     struct attribute inline_flags;
-    struct attribute frame;
     struct symt* ret_type;
     struct symt_function_signature* sig_type;
     dwarf2_subprogram_t subpgm;
@@ -1368,11 +1377,8 @@ static struct symt* dwarf2_parse_subprog
 
     subpgm.ctx = ctx;
     subpgm.compiland = compiland;
-    if (dwarf2_find_attribute(ctx, di, DW_AT_frame_base, &frame))
-    {
-        subpgm.frame_offset = dwarf2_compute_location(ctx, &frame.u.block, &subpgm.frame_reg);
+    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);
-    }
     else /* on stack !! */
     {
         subpgm.frame_reg = 0;



More information about the wine-patches mailing list