aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/attribute.h
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/attribute.h')
-rw-r--r--gdb/dwarf2/attribute.h97
1 files changed, 69 insertions, 28 deletions
diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index 3b971ad..234de4e 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -1,6 +1,6 @@
/* DWARF attributes
- Copyright (C) 1994-2024 Free Software Foundation, Inc.
+ Copyright (C) 1994-2025 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
@@ -29,7 +29,6 @@
#include "dwarf2.h"
#include "dwarf2/types.h"
-#include <optional>
/* Blocks are a bunch of untyped bytes. */
struct dwarf_block
@@ -70,7 +69,7 @@ struct attribute
form. */
LONGEST as_signed () const
{
- gdb_assert (form_is_signed ());
+ gdb_assert (form_is_strictly_signed ());
return u.snd;
}
@@ -92,28 +91,6 @@ struct attribute
return u.unsnd;
}
- /* Return true if the value is nonnegative. Requires that that
- reprocessing not be needed. */
- bool is_nonnegative () const
- {
- if (form_is_unsigned ())
- return true;
- if (form_is_signed ())
- return as_signed () >= 0;
- return false;
- }
-
- /* Return the nonnegative value. Requires that that reprocessing not be
- needed. */
- ULONGEST as_nonnegative () const
- {
- if (form_is_unsigned ())
- return as_unsigned ();
- if (form_is_signed ())
- return (ULONGEST)as_signed ();
- gdb_assert (false);
- }
-
/* Return non-zero if ATTR's value is a section offset --- classes
lineptr, loclistptr, macptr or rangelistptr --- or zero, otherwise.
You may use the as_unsigned method to retrieve such offsets.
@@ -125,6 +102,46 @@ struct attribute
bool form_is_section_offset () const;
+ /* Return an unsigned constant value. This only handles constant
+ forms (i.e., form_is_constant -- and not the extended list of
+ "unsigned" forms) and assumes an unsigned value is desired. This
+ can be used with DWARF-defined enumerations like DW_CC_* or
+ DW_INL_*, but also in situations where a nonnegative constant
+ integer is specified by DWARF.
+
+ If a signed form and negative value is used, or if a non-constant
+ form is used, then complaint is issued and an empty value is
+ returned. */
+ std::optional<ULONGEST> unsigned_constant () const;
+
+ /* Return a signed constant value. This only handles constant forms
+ (i.e., form_is_constant -- and not the extended list of
+ "unsigned" forms) and assumes a signed value is desired. This
+ function will sign-extend DW_FORM_data* values.
+
+ If non-constant form is used, then complaint is issued and an
+ empty value is returned. */
+ std::optional<LONGEST> signed_constant () const;
+
+ /* Return a signed constant value. However, for narrow forms like
+ DW_FORM_data1, sign extension is not done.
+
+ DWARF advises compilers to generally use DW_FORM_[su]data to
+ avoid ambiguity. However, both GCC and LLVM ignore this for
+ certain attributes. Furthermore in DWARF, whether a narrower
+ form causes sign-extension depends on the attribute -- for
+ attributes that can only assume non-negative values, sign
+ extension is not done.
+
+ Unfortunately, both compilers also emit certain attributes in a
+ "confused" way, using DW_FORM_sdata for signed values, and
+ possibly choosing a narrow form (e.g., DW_FORM_data1) otherwise
+ -- assuming that sign-extension will not be done.
+
+ This method should only be called when this "confused" treatment
+ is necessary. */
+ std::optional<LONGEST> confused_constant () const;
+
/* Return non-zero if ATTR's value falls in the 'constant' class, or
zero otherwise. When this function returns true, you can apply
the constant_value method to it.
@@ -155,7 +172,9 @@ struct attribute
|| form == DW_FORM_ref4
|| form == DW_FORM_ref8
|| form == DW_FORM_ref_udata
- || form == DW_FORM_GNU_ref_alt);
+ || form == DW_FORM_GNU_ref_alt
+ || form == DW_FORM_ref_sup4
+ || form == DW_FORM_ref_sup8);
}
/* Check if the attribute's form is a DW_FORM_block*
@@ -169,13 +188,35 @@ struct attribute
/* Check if the attribute's form is an unsigned integer form. */
bool form_is_unsigned () const;
- /* Check if the attribute's form is a signed integer form. */
- bool form_is_signed () const;
+ /* Check if the attribute's form is a signed integer form. This
+ only returns true for forms that are strictly signed -- that is,
+ for a context-dependent form like DW_FORM_data1, this returns
+ false. */
+ bool form_is_strictly_signed () const;
+
+ /* Check if the attribute's form is an unsigned constant form. This
+ only returns true for forms that are strictly unsigned -- that
+ is, for a context-dependent form like DW_FORM_data1, this returns
+ false. */
+ bool form_is_strictly_unsigned () const
+ {
+ return form == DW_FORM_udata;
+ }
/* Check if the attribute's form is a form that requires
"reprocessing". */
bool form_requires_reprocessing () const;
+ /* Check if attribute's form refers to the separate "dwz" file.
+ This is only useful for references to the .debug_info section,
+ not to the supplementary .debug_str section. */
+ bool form_is_alt () const
+ {
+ return (form == DW_FORM_GNU_ref_alt
+ || form == DW_FORM_ref_sup4
+ || form == DW_FORM_ref_sup8);
+ }
+
/* Return DIE offset of this attribute. Return 0 with complaint if
the attribute is not of the required kind. */