aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/attribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/attribute.c')
-rw-r--r--gdb/dwarf2/attribute.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c
index 1278f97..8ff0353 100644
--- a/gdb/dwarf2/attribute.c
+++ b/gdb/dwarf2/attribute.c
@@ -73,7 +73,8 @@ attribute::form_is_string () const
|| form == DW_FORM_strx3
|| form == DW_FORM_strx4
|| form == DW_FORM_GNU_str_index
- || form == DW_FORM_GNU_strp_alt);
+ || form == DW_FORM_GNU_strp_alt
+ || form == DW_FORM_strp_sup);
}
/* See attribute.h. */
@@ -185,11 +186,43 @@ attribute::unsigned_constant () const
/* See attribute.h. */
+std::optional<LONGEST>
+attribute::signed_constant () const
+{
+ if (form_is_strictly_signed ())
+ return u.snd;
+
+ switch (form)
+ {
+ case DW_FORM_data8:
+ case DW_FORM_udata:
+ /* Not sure if DW_FORM_udata should be handled or not. Anyway
+ for DW_FORM_data8, there's no need to sign-extend. */
+ return u.snd;
+
+ case DW_FORM_data1:
+ return sign_extend (u.unsnd, 8);
+ case DW_FORM_data2:
+ return sign_extend (u.unsnd, 16);
+ case DW_FORM_data4:
+ return sign_extend (u.unsnd, 32);
+ }
+
+ /* For DW_FORM_data16 see attribute::form_is_constant. */
+ complaint (_("Attribute value is not a constant (%s)"),
+ dwarf_form_name (form));
+ return {};
+}
+
+/* See attribute.h. */
+
bool
attribute::form_is_unsigned () const
{
return (form == DW_FORM_ref_addr
|| form == DW_FORM_GNU_ref_alt
+ || form == DW_FORM_ref_sup4
+ || form == DW_FORM_ref_sup8
|| form == DW_FORM_data2
|| form == DW_FORM_data4
|| form == DW_FORM_data8
@@ -293,5 +326,8 @@ attribute::as_boolean () const
return true;
else if (form == DW_FORM_flag)
return u.unsnd != 0;
- return constant_value (0) != 0;
+ /* Using signed_constant here will work even for the weird case
+ where a negative value is provided. Probably doesn't matter but
+ also seems harmless. */
+ return signed_constant ().value_or (0) != 0;
}