From: Jim Blandy <jimb@codesourcery.com>
To: Vladimir Prus <vladimir@codesourcery.com>
Cc: gdb-patches@sources.redhat.com
Subject: Re: Support constants for DW_AT_data_member_location
Date: Sat, 01 Dec 2007 01:48:00 -0000 [thread overview]
Message-ID: <m3mysvtcbq.fsf@codesourcery.com> (raw)
In-Reply-To: <200711292317.53967.vladimir@codesourcery.com> (Vladimir Prus's message of "Thu, 29 Nov 2007 23:17:53 +0300")
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. */
next prev parent reply other threads:[~2007-12-01 1:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-29 9:54 Vladimir Prus
2007-11-29 19:39 ` Jim Blandy
2007-11-29 20:18 ` Vladimir Prus
2007-12-01 1:48 ` Jim Blandy [this message]
2007-12-13 17:57 ` Vladimir Prus
2007-12-13 19:29 ` Jim Blandy
2007-12-17 19:30 ` Jim Blandy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3mysvtcbq.fsf@codesourcery.com \
--to=jimb@codesourcery.com \
--cc=gdb-patches@sources.redhat.com \
--cc=vladimir@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox