mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-19 01:19:41 +08:00
Introduce attribute::signed_constant
This introduces a new method, attribute::signed_constant. This should be used wherever DWARF specifies a signed integer constant, or where this is implied by the context. It properly handles sign-extension for DW_FORM_data*. To my surprise, there doesn't seem to be a pre-existing sign-extension function. I've added one to common-utils.h alongside the align functions. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32680
This commit is contained in:
@@ -186,6 +186,36 @@ attribute::unsigned_constant () const
|
|||||||
|
|
||||||
/* See attribute.h. */
|
/* 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
|
bool
|
||||||
attribute::form_is_unsigned () const
|
attribute::form_is_unsigned () const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -114,6 +114,15 @@ struct attribute
|
|||||||
returned. */
|
returned. */
|
||||||
std::optional<ULONGEST> unsigned_constant () const;
|
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 non-zero if ATTR's value falls in the 'constant' class, or
|
/* Return non-zero if ATTR's value falls in the 'constant' class, or
|
||||||
zero otherwise. When this function returns true, you can apply
|
zero otherwise. When this function returns true, you can apply
|
||||||
the constant_value method to it.
|
the constant_value method to it.
|
||||||
|
|||||||
@@ -196,6 +196,16 @@ in_inclusive_range (T value, T low, T high)
|
|||||||
extern ULONGEST align_up (ULONGEST v, int n);
|
extern ULONGEST align_up (ULONGEST v, int n);
|
||||||
extern ULONGEST align_down (ULONGEST v, int n);
|
extern ULONGEST align_down (ULONGEST v, int n);
|
||||||
|
|
||||||
|
/* Sign-extend the value V, using N as the number of valid bits. That
|
||||||
|
is, bit N-1 is the sign bit. The higher-order bits (those outside
|
||||||
|
0..N-1) must be zero. */
|
||||||
|
static inline ULONGEST
|
||||||
|
sign_extend (ULONGEST v, int n)
|
||||||
|
{
|
||||||
|
ULONGEST mask = (ULONGEST) 1 << (n - 1);
|
||||||
|
return (v ^ mask) - mask;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert hex digit A to a number, or throw an exception. */
|
/* Convert hex digit A to a number, or throw an exception. */
|
||||||
extern int fromhex (int a);
|
extern int fromhex (int a);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user