Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Support constants for DW_AT_data_member_location
@ 2007-11-29  9:54 Vladimir Prus
  2007-11-29 19:39 ` Jim Blandy
  0 siblings, 1 reply; 7+ messages in thread
From: Vladimir Prus @ 2007-11-29  9:54 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 237 bytes --]


DWARF standard allows DW_AT_data_member_location value
to be a plain constant, but GDB does not. Is the following OK?

- Volodya

	* dwarf2read.c (dwarf2_add_field): Allow
	the DW_AT_data_member_location to be of 
	DW_FORM_udata form.


[-- Attachment #2: constant_data_member_location.diff --]
[-- Type: text/x-diff, Size: 517 bytes --]

--- dwarf2read.c	(revision 123)
+++ dwarf2read.c	(local)
@@ -3500,8 +3500,11 @@ dwarf2_add_field (struct field_info *fip
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
 	{
-	  FIELD_BITPOS (*fp) =
-	    decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
+	  if (attr->form == DW_FORM_udata)
+	    FIELD_BITPOS (*fp) = 8 * DW_UNSND (attr);
+	  else
+	    FIELD_BITPOS (*fp) =
+	      decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
 	}
       else
 	FIELD_BITPOS (*fp) = 0;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Support constants for DW_AT_data_member_location
  2007-11-29  9:54 Support constants for DW_AT_data_member_location Vladimir Prus
@ 2007-11-29 19:39 ` Jim Blandy
  2007-11-29 20:18   ` Vladimir Prus
  0 siblings, 1 reply; 7+ messages in thread
From: Jim Blandy @ 2007-11-29 19:39 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb-patches


Vladimir Prus <vladimir at codesourcery.com> writes:
> DWARF standard allows DW_AT_data_member_location value
> to be a plain constant, but GDB does not. Is the following OK?

A constant can have other FORMs, too; how about this?

gdb/ChangeLog:
2007-11-29  Jim Blandy  <jimb@codesourcery.com>

	* dwarf2read.c (dwarf2_attr_is_constant): New function.
	(dwarf2_add_field): Use it to recognize DW_AT_data_member_location
	attributes with constant values; use
	dwarf2_get_attr_constant_value to get said values.

diff -r c4f654de59cf gdb/dwarf2read.c
--- a/gdb/dwarf2read.c	Thu Nov 29 11:28:59 2007 -0800
+++ b/gdb/dwarf2read.c	Thu Nov 29 11:33:57 2007 -0800
@@ -1012,6 +1012,8 @@ static void store_in_ref_table (unsigned
 
 static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
 					       struct dwarf2_cu *);
+
+static int dwarf2_attr_is_constant (struct attribute *);
 
 static int dwarf2_get_attr_constant_value (struct attribute *, int);
 
@@ -3380,8 +3382,11 @@ dwarf2_add_field (struct field_info *fip
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
 	{
-	  FIELD_BITPOS (*fp) =
-	    decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
+          if (dwarf2_attr_is_constant (attr))
+            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
+          else
+            FIELD_BITPOS (*fp) =
+              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
 	}
       else
 	FIELD_BITPOS (*fp) = 0;
@@ -9008,6 +9013,26 @@ dwarf2_get_ref_die_offset (struct attrib
   return result;
 }
 
+/* Return non-zero if ATTR's value falls in the 'constant' class, or
+   zero otherwise.  When this function returns true, you can apply
+   dwarf2_get_attr_constant_value to it.  */
+static int
+dwarf2_attr_is_constant (struct attribute *attr)
+{
+  switch (attr->form)
+    {
+    case DW_FORM_sdata:
+    case DW_FORM_udata:
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
 /* Return the constant value held by the given attribute.  Return -1
    if the value held by the attribute is not constant.  */
 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Support constants for DW_AT_data_member_location
  2007-11-29 19:39 ` Jim Blandy
@ 2007-11-29 20:18   ` Vladimir Prus
  2007-12-01  1:48     ` Jim Blandy
  0 siblings, 1 reply; 7+ messages in thread
From: Vladimir Prus @ 2007-11-29 20:18 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches

On Thursday 29 November 2007 22:38:37 you wrote:
> Vladimir Prus <vladimir at codesourcery.com> writes:
> > DWARF standard allows DW_AT_data_member_location value
> > to be a plain constant, but GDB does not. Is the following OK?
>
> A constant can have other FORMs, too; how about this?
>
> gdb/ChangeLog:
> 2007-11-29  Jim Blandy  <jimb@codesourcery.com>
>
> 	* dwarf2read.c (dwarf2_attr_is_constant): New function.
> 	(dwarf2_add_field): Use it to recognize DW_AT_data_member_location
> 	attributes with constant values; use
> 	dwarf2_get_attr_constant_value to get said values.
>
> diff -r c4f654de59cf gdb/dwarf2read.c
> --- a/gdb/dwarf2read.c	Thu Nov 29 11:28:59 2007 -0800
> +++ b/gdb/dwarf2read.c	Thu Nov 29 11:33:57 2007 -0800
> @@ -1012,6 +1012,8 @@ static void store_in_ref_table (unsigned
>
>  static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
>  					       struct dwarf2_cu *);
> +
> +static int dwarf2_attr_is_constant (struct attribute *);
>
>  static int dwarf2_get_attr_constant_value (struct attribute *, int);
>
> @@ -3380,8 +3382,11 @@ dwarf2_add_field (struct field_info *fip
>        attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
>        if (attr)
>  	{
> -	  FIELD_BITPOS (*fp) =
> -	    decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
> +          if (dwarf2_attr_is_constant (attr))
> +            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
> +          else
> +            FIELD_BITPOS (*fp) =
> +              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
>  	}
>        else
>  	FIELD_BITPOS (*fp) = 0;
> @@ -9008,6 +9013,26 @@ dwarf2_get_ref_die_offset (struct attrib
>    return result;
>  }
>
> +/* Return non-zero if ATTR's value falls in the 'constant' class, or
> +   zero otherwise.  When this function returns true, you can apply
> +   dwarf2_get_attr_constant_value to it.  */
> +static int
> +dwarf2_attr_is_constant (struct attribute *attr)
> +{
> +  switch (attr->form)
> +    {
> +    case DW_FORM_sdata:
> +    case DW_FORM_udata:
> +    case DW_FORM_data1:
> +    case DW_FORM_data2:
> +    case DW_FORM_data4:

This is wrong, per DWARF standard:

       Some encodings are members of more than one class; in that case, 
        the list of classes allowed by the applicable attribute in 
        Figure 18 determines the class of the form. DW_FORM_data4 and 
        DW_FORM_data8 may be members of classes constant, lineptr, 
        loclistptr, macptr and  rangelistptr. They are members of the 
        class constant if used for the value of an attribute that allows class
        constant but not class lineptr, loclistptr, macptr or rangelistptr.
        They are members of the class lineptr, loclistptr, macptr or 
        rangelistptr if used for the value of an attribute that allows
        one of those classes.

Referring to Figure 18, I see:

     Attribute name                  Classes
    DW_AT_data_member_location       block, constant, loclistptr

So, DW_FORM_data4 used for DW_AT_data_member_location is never interepreted
as constant. Maybe we should have "is_surely_constant" function?

- Volodya


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Support constants for DW_AT_data_member_location
  2007-11-29 20:18   ` Vladimir Prus
@ 2007-12-01  1:48     ` Jim Blandy
  2007-12-13 17:57       ` Vladimir Prus
  0 siblings, 1 reply; 7+ messages in thread
From: Jim Blandy @ 2007-12-01  1:48 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb-patches


Vladimir Prus <vladimir at codesourcery.com> writes:
> This is wrong, per DWARF standard:
>
>        Some encodings are members of more than one class; in that case, 
>         the list of classes allowed by the applicable attribute in 
>         Figure 18 determines the class of the form. DW_FORM_data4 and 
>         DW_FORM_data8 may be members of classes constant, lineptr, 
>         loclistptr, macptr and  rangelistptr. They are members of the 
>         class constant if used for the value of an attribute that allows class
>         constant but not class lineptr, loclistptr, macptr or rangelistptr.
>         They are members of the class lineptr, loclistptr, macptr or 
>         rangelistptr if used for the value of an attribute that allows
>         one of those classes.
>
> Referring to Figure 18, I see:
>
>      Attribute name                  Classes
>     DW_AT_data_member_location       block, constant, loclistptr
>
> So, DW_FORM_data4 used for DW_AT_data_member_location is never interepreted
> as constant. Maybe we should have "is_surely_constant" function?

Oh --- great catch, thanks.  (We don't support location lists for
DW_AT_data_member_location yet, but we certainly should warn, not
randomly misinterpret the value.)

How's this, then?

gdb/ChangeLog:
2007-11-30  Jim Blandy  <jimb@codesourcery.com>

	* dwarf2read.c (attr_form_is_constant): New function.
	(dwarf2_add_field): Use it and attr_form_is_section_offset to
	recognize DW_AT_data_member_location attributes.  Use
	dwarf2_get_attr_constant_value when the attribute is a constant.

	* dwarf2read.c (attr_form_is_section_offset): New function.
	(dwarf_add_member_fn, read_common_block, read_partial_die)
	(dwarf2_symbol_mark_computed): Use it, instead of writing it out.

diff -r c4f654de59cf gdb/dwarf2read.c
--- a/gdb/dwarf2read.c	Thu Nov 29 11:28:59 2007 -0800
+++ b/gdb/dwarf2read.c	Fri Nov 30 17:32:46 2007 -0800
@@ -1039,6 +1039,10 @@ static void dwarf_decode_macros (struct 
                                  char *, bfd *, struct dwarf2_cu *);
 
 static int attr_form_is_block (struct attribute *);
+
+static int attr_form_is_section_offset (struct attribute *);
+
+static int attr_form_is_constant (struct attribute *);
 
 static void dwarf2_symbol_mark_computed (struct attribute *attr,
 					 struct symbol *sym,
@@ -3380,8 +3384,16 @@ dwarf2_add_field (struct field_info *fip
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
 	{
-	  FIELD_BITPOS (*fp) =
-	    decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
+          if (attr_form_is_section_offset (attr))
+            {
+              dwarf2_complex_location_expr_complaint ();
+              FIELD_BITPOS (*fp) = 0;
+            }
+          else if (attr_form_is_constant (attr))
+            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
+          else
+            FIELD_BITPOS (*fp) =
+              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
 	}
       else
 	FIELD_BITPOS (*fp) = 0;
@@ -3700,7 +3712,7 @@ dwarf2_add_member_fn (struct field_info 
         {
           fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
         }
-      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+      else if (attr_form_is_section_offset (attr))
         {
 	  dwarf2_complex_location_expr_complaint ();
         }
@@ -4416,7 +4428,7 @@ read_common_block (struct die_info *die,
         {
           base = decode_locdesc (DW_BLOCK (attr), cu);
         }
-      else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+      else if (attr_form_is_section_offset (attr))
         {
 	  dwarf2_complex_location_expr_complaint ();
         }
@@ -5598,7 +5610,7 @@ read_partial_die (struct partial_die_inf
             {
 	       part_die->locdesc = DW_BLOCK (&attr);
             }
-          else if (attr.form == DW_FORM_data4 || attr.form == DW_FORM_data8)
+          else if (attr_form_is_section_offset (&attr))
             {
 	      dwarf2_complex_location_expr_complaint ();
             }
@@ -9755,6 +9767,46 @@ attr_form_is_block (struct attribute *at
       || attr->form == DW_FORM_block);
 }
 
+/* Return non-zero if ATTR's value is a section offset (classes
+   lineptr, loclistptr, macptr or rangelistptr).  In this case,
+   you may use DW_UNSND (attr) to retrieve the offset.  */
+static int
+attr_form_is_section_offset (struct attribute *attr)
+{
+  return (attr->form == DW_FORM_data4
+          || attr->form == DW_FORM_data8);
+}
+
+
+/* Return non-zero if ATTR's value falls in the 'constant' class, or
+   zero otherwise.  When this function returns true, you can apply
+   dwarf2_get_attr_constant_value to it.
+
+   However, note that for some attributes you must check
+   attr_form_is_section_offset before using this test.  DW_FORM_data4
+   and DW_FORM_data8 are members of both the constant class, and of
+   the classes that contain offsets into other debug sections
+   (lineptr, loclistptr, macptr or rangelistptr).  The DWARF spec says
+   that, if an attribute's can be either a constant or one of the
+   section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
+   taken as section offsets, not constants.  */
+static int
+attr_form_is_constant (struct attribute *attr)
+{
+  switch (attr->form)
+    {
+    case DW_FORM_sdata:
+    case DW_FORM_udata:
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
 static void
 dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
 			     struct dwarf2_cu *cu)
@@ -9766,7 +9818,7 @@ dwarf2_symbol_mark_computed (struct attr
   if (objfile->separate_debug_objfile_backlink)
     objfile = objfile->separate_debug_objfile_backlink;
 
-  if ((attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+  if (attr_form_is_section_offset (attr)
       /* ".debug_loc" may not exist at all, or the offset may be outside
 	 the section.  If so, fall through to the complaint in the
 	 other branch.  */


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Support constants for DW_AT_data_member_location
  2007-12-01  1:48     ` Jim Blandy
@ 2007-12-13 17:57       ` Vladimir Prus
  2007-12-13 19:29         ` Jim Blandy
  0 siblings, 1 reply; 7+ messages in thread
From: Vladimir Prus @ 2007-12-13 17:57 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches

On Saturday 01 December 2007 04:48:09 Jim Blandy wrote:

> > So, DW_FORM_data4 used for DW_AT_data_member_location is never interepreted
> > as constant. Maybe we should have "is_surely_constant" function?
> 
> Oh --- great catch, thanks.  (We don't support location lists for
> DW_AT_data_member_location yet, but we certainly should warn, not
> randomly misinterpret the value.)
> 
> How's this, then?
> 
> gdb/ChangeLog:
> 2007-11-30  Jim Blandy  <jimb@codesourcery.com>
> 
>         * dwarf2read.c (attr_form_is_constant): New function.
>         (dwarf2_add_field): Use it and attr_form_is_section_offset to
>         recognize DW_AT_data_member_location attributes.  Use
>         dwarf2_get_attr_constant_value when the attribute is a constant.
> 
>         * dwarf2read.c (attr_form_is_section_offset): New function.
>         (dwarf_add_member_fn, read_common_block, read_partial_die)
>         (dwarf2_symbol_mark_computed): Use it, instead of writing it out.
> 
> diff -r c4f654de59cf gdb/dwarf2read.c
> --- a/gdb/dwarf2read.c  Thu Nov 29 11:28:59 2007 -0800
> +++ b/gdb/dwarf2read.c  Fri Nov 30 17:32:46 2007 -0800
> @@ -1039,6 +1039,10 @@ static void dwarf_decode_macros (struct 
>                                   char *, bfd *, struct dwarf2_cu *);
>  
>  static int attr_form_is_block (struct attribute *);
> +
> +static int attr_form_is_section_offset (struct attribute *);
> +
> +static int attr_form_is_constant (struct attribute *);
>  
>  static void dwarf2_symbol_mark_computed (struct attribute *attr,
>                                          struct symbol *sym,
> @@ -3380,8 +3384,16 @@ dwarf2_add_field (struct field_info *fip
>        attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
>        if (attr)
>         {
> -         FIELD_BITPOS (*fp) =
> -           decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
> +          if (attr_form_is_section_offset (attr))
> +            {
> +              dwarf2_complex_location_expr_complaint ();
> +              FIELD_BITPOS (*fp) = 0;
> +            }
> +          else if (attr_form_is_constant (attr))
> +            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);

You need "* 8" above, since the value of data_member_location is offset
in bytes.

> +          else
> +            FIELD_BITPOS (*fp) =
> +              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;

Or, if we really want GDB to support processors with 9-bit bytes, you
need "* bits_per_byte".


> +/* Return non-zero if ATTR's value is a section offset (classes
> +   lineptr, loclistptr, macptr or rangelistptr). 

I'd also note here that in all cases, an attribute value
may fall to only one class listed above.

> In this case, 
> +   you may use DW_UNSND (attr) to retrieve the offset.  */
> +static int
> +attr_form_is_section_offset (struct attribute *attr)
> +{
> +  return (attr->form == DW_FORM_data4
> +          || attr->form == DW_FORM_data8);

I'd probably add a comment here saying that in DWARF standand,
those are only two forms that can encode those classes. Not being
DWARF expert, it took me a bit of looking to verify that.  If you
explicitly mention this, then future readers can just trust the
comment ;-)

With the "* bits_per_byte" change, this patch fixes the problem I saw.
Assuming there are no regressions, can you check it in?

Thanks,
Volodya


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Support constants for DW_AT_data_member_location
  2007-12-13 17:57       ` Vladimir Prus
@ 2007-12-13 19:29         ` Jim Blandy
  2007-12-17 19:30           ` Jim Blandy
  0 siblings, 1 reply; 7+ messages in thread
From: Jim Blandy @ 2007-12-13 19:29 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb-patches


Sorry --- I committed, and then saw your review.  I'll revise this.

Vladimir Prus <vladimir at codesourcery.com> writes:
> On Saturday 01 December 2007 04:48:09 Jim Blandy wrote:
>
>> > So, DW_FORM_data4 used for DW_AT_data_member_location is never interepreted
>> > as constant. Maybe we should have "is_surely_constant" function?
>> 
>> Oh --- great catch, thanks.  (We don't support location lists for
>> DW_AT_data_member_location yet, but we certainly should warn, not
>> randomly misinterpret the value.)
>> 
>> How's this, then?
>> 
>> gdb/ChangeLog:
>> 2007-11-30  Jim Blandy  <jimb@codesourcery.com>
>> 
>>         * dwarf2read.c (attr_form_is_constant): New function.
>>         (dwarf2_add_field): Use it and attr_form_is_section_offset to
>>         recognize DW_AT_data_member_location attributes.  Use
>>         dwarf2_get_attr_constant_value when the attribute is a constant.
>> 
>>         * dwarf2read.c (attr_form_is_section_offset): New function.
>>         (dwarf_add_member_fn, read_common_block, read_partial_die)
>>         (dwarf2_symbol_mark_computed): Use it, instead of writing it out.
>> 
>> diff -r c4f654de59cf gdb/dwarf2read.c
>> --- a/gdb/dwarf2read.c  Thu Nov 29 11:28:59 2007 -0800
>> +++ b/gdb/dwarf2read.c  Fri Nov 30 17:32:46 2007 -0800
>> @@ -1039,6 +1039,10 @@ static void dwarf_decode_macros (struct 
>>                                   char *, bfd *, struct dwarf2_cu *);
>>  
>>  static int attr_form_is_block (struct attribute *);
>> +
>> +static int attr_form_is_section_offset (struct attribute *);
>> +
>> +static int attr_form_is_constant (struct attribute *);
>>  
>>  static void dwarf2_symbol_mark_computed (struct attribute *attr,
>>                                          struct symbol *sym,
>> @@ -3380,8 +3384,16 @@ dwarf2_add_field (struct field_info *fip
>>        attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
>>        if (attr)
>>         {
>> -         FIELD_BITPOS (*fp) =
>> -           decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
>> +          if (attr_form_is_section_offset (attr))
>> +            {
>> +              dwarf2_complex_location_expr_complaint ();
>> +              FIELD_BITPOS (*fp) = 0;
>> +            }
>> +          else if (attr_form_is_constant (attr))
>> +            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
>
> You need "* 8" above, since the value of data_member_location is offset
> in bytes.

Fixed --- thanks.

>> +          else
>> +            FIELD_BITPOS (*fp) =
>> +              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
>
> Or, if we really want GDB to support processors with 9-bit bytes, you
> need "* bits_per_byte".

That's what I used.  I'm not sure what read_memory would return on
such processors, but... :)

>> +/* Return non-zero if ATTR's value is a section offset (classes
>> +   lineptr, loclistptr, macptr or rangelistptr). 
>
> I'd also note here that in all cases, an attribute value
> may fall to only one class listed above.

I've added a note citing 7.5.4, which says this (after the list of
classes).

>> In this case, 
>> +   you may use DW_UNSND (attr) to retrieve the offset.  */
>> +static int
>> +attr_form_is_section_offset (struct attribute *attr)
>> +{
>> +  return (attr->form == DW_FORM_data4
>> +          || attr->form == DW_FORM_data8);
>
> I'd probably add a comment here saying that in DWARF standand,
> those are only two forms that can encode those classes. Not being
> DWARF expert, it took me a bit of looking to verify that.  If you
> explicitly mention this, then future readers can just trust the
> comment ;-)

Hmm.  If I look through the class definitions in 7.5.4, each paragraph
ends with "It is either form DW_FORM_data4 or form DW_FORM_data8."  I
feel odd putting in a comment saying "Those classes use only these
forms", because if that weren't true, then the comment saying what the
function does wouldn't be accurate; it'd be missing cases.

> With the "* bits_per_byte" change, this patch fixes the problem I saw.
> Assuming there are no regressions, can you check it in?

Thanks for checking this.  I did run the tests before I committed, but
I didn't notice any failures.  I must be using a compiler that never
generates anything but expressions.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Support constants for DW_AT_data_member_location
  2007-12-13 19:29         ` Jim Blandy
@ 2007-12-17 19:30           ` Jim Blandy
  0 siblings, 0 replies; 7+ messages in thread
From: Jim Blandy @ 2007-12-17 19:30 UTC (permalink / raw)
  To: Vladimir Prus; +Cc: gdb-patches


I've committed the following.

gdb/ChangeLog:
2007-12-17  Jim Blandy  <jimb@codesourcery.com>

	* dwarf2read.c (dwarf2_add_field): Correctly scale all byte
	offsets obtained from DW_AT_data_member_location before recording
	them in FIELD_BITPOS (*fp).

	* dwarf2read.c (attr_form_is_section_offset): Doc fixes.

diff -r ac45448af75b -r 946effe2c5c8 gdb/dwarf2read.c
--- a/gdb/dwarf2read.c	Mon Dec 17 10:34:43 2007 -0800
+++ b/gdb/dwarf2read.c	Mon Dec 17 10:39:13 2007 -0800
@@ -3478,16 +3478,19 @@ dwarf2_add_field (struct field_info *fip
       attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
       if (attr)
 	{
+          int byte_offset;
+
           if (attr_form_is_section_offset (attr))
             {
               dwarf2_complex_location_expr_complaint ();
-              FIELD_BITPOS (*fp) = 0;
+              byte_offset = 0;
             }
           else if (attr_form_is_constant (attr))
-            FIELD_BITPOS (*fp) = dwarf2_get_attr_constant_value (attr, 0);
+            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
           else
-            FIELD_BITPOS (*fp) =
-              decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte;
+            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+
+          FIELD_BITPOS (*fp) = byte_offset * bits_per_byte;
 	}
       else
 	FIELD_BITPOS (*fp) = 0;
@@ -9734,9 +9737,14 @@ attr_form_is_block (struct attribute *at
       || attr->form == DW_FORM_block);
 }
 
-/* Return non-zero if ATTR's value is a section offset (classes
-   lineptr, loclistptr, macptr or rangelistptr).  In this case,
-   you may use DW_UNSND (attr) to retrieve the offset.  */
+/* Return non-zero if ATTR's value is a section offset --- classes
+   lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise.
+   You may use DW_UNSND (attr) to retrieve such offsets.
+
+   Section 7.5.4, "Attribute Encodings", explains that no attribute
+   may have a value that belongs to more than one of these classes; it
+   would be ambiguous if we did, because we use the same forms for all
+   of them.  */
 static int
 attr_form_is_section_offset (struct attribute *attr)
 {


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-12-17 18:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-29  9:54 Support constants for DW_AT_data_member_location Vladimir Prus
2007-11-29 19:39 ` Jim Blandy
2007-11-29 20:18   ` Vladimir Prus
2007-12-01  1:48     ` Jim Blandy
2007-12-13 17:57       ` Vladimir Prus
2007-12-13 19:29         ` Jim Blandy
2007-12-17 19:30           ` Jim Blandy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox