aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2020-12-09 14:12:58 -0700
committerTom Tromey <tromey@adacore.com>2020-12-09 14:12:58 -0700
commit5cde1d8222a849256f684363f38a6423dea9be74 (patch)
tree6a527c12bcbaf7e4529561f682e49b23124da977 /gdb/dwarf2
parentd9c3a9c03692c12b472c555f71fe7a2444a24d46 (diff)
downloadgdb-5cde1d8222a849256f684363f38a6423dea9be74.zip
gdb-5cde1d8222a849256f684363f38a6423dea9be74.tar.gz
gdb-5cde1d8222a849256f684363f38a6423dea9be74.tar.bz2
Handle 128-bit constants for fixed point
In some cases, GNAT can emit 128-bit constants for fixed-point types. This patch changes gdb to handle this scenario, by changing the low-level rational-reading functions in dwarf2/read.c to work directly with gdb_mpz values. (I'm not sure offhand if these 128-bit patches have gone into upstream GCC yet -- but they will eventually, and meanwhile I think it should be clear that this patch is otherwise harmless.) gdb/ChangeLog 2020-12-09 Tom Tromey <tromey@adacore.com> * dwarf2/read.c (get_dwarf2_rational_constant): Change "numerator" and "denominator" to gdb_mpz. Handle block forms. (get_dwarf2_unsigned_rational_constant): Change "numerator" and "denominator" to gdb_mpz. (finish_fixed_point_type): Update. (has_zero_over_zero_small_attribute): Update.
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r--gdb/dwarf2/read.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 9468b91..2bf1453 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18194,7 +18194,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
static void
get_dwarf2_rational_constant (struct die_info *die, struct dwarf2_cu *cu,
- LONGEST *numerator, LONGEST *denominator)
+ gdb_mpz *numerator, gdb_mpz *denominator)
{
struct attribute *num_attr, *denom_attr;
@@ -18211,8 +18211,25 @@ get_dwarf2_rational_constant (struct die_info *die, struct dwarf2_cu *cu,
if (num_attr == nullptr || denom_attr == nullptr)
return;
- *numerator = num_attr->constant_value (1);
- *denominator = denom_attr->constant_value (1);
+ if (num_attr->form_is_block ())
+ {
+ dwarf_block *blk = num_attr->as_block ();
+ mpz_import (numerator->val, blk->size,
+ bfd_big_endian (cu->per_objfile->objfile->obfd) ? 1 : -1,
+ 1, 0, 0, blk->data);
+ }
+ else
+ *numerator = gdb_mpz (num_attr->constant_value (1));
+
+ if (denom_attr->form_is_block ())
+ {
+ dwarf_block *blk = denom_attr->as_block ();
+ mpz_import (denominator->val, blk->size,
+ bfd_big_endian (cu->per_objfile->objfile->obfd) ? 1 : -1,
+ 1, 0, 0, blk->data);
+ }
+ else
+ *denominator = gdb_mpz (denom_attr->constant_value (1));
}
/* Same as get_dwarf2_rational_constant, but extracting an unsigned
@@ -18224,25 +18241,26 @@ get_dwarf2_rational_constant (struct die_info *die, struct dwarf2_cu *cu,
static void
get_dwarf2_unsigned_rational_constant (struct die_info *die,
struct dwarf2_cu *cu,
- ULONGEST *numerator,
- ULONGEST *denominator)
+ gdb_mpz *numerator,
+ gdb_mpz *denominator)
{
- LONGEST num = 1, denom = 1;
+ gdb_mpz num (1);
+ gdb_mpz denom (1);
get_dwarf2_rational_constant (die, cu, &num, &denom);
- if (num < 0 && denom < 0)
+ if (mpz_sgn (num.val) == -1 && mpz_sgn (denom.val) == -1)
{
- num = -num;
- denom = -denom;
+ mpz_neg (num.val, num.val);
+ mpz_neg (denom.val, denom.val);
}
- else if (num < 0)
+ else if (mpz_sgn (num.val) == -1)
{
complaint (_("unexpected negative value for DW_AT_GNU_numerator"
" in DIE at %s"),
sect_offset_str (die->sect_off));
return;
}
- else if (denom < 0)
+ else if (mpz_sgn (denom.val) == -1)
{
complaint (_("unexpected negative value for DW_AT_GNU_denominator"
" in DIE at %s"),
@@ -18250,8 +18268,8 @@ get_dwarf2_unsigned_rational_constant (struct die_info *die,
return;
}
- *numerator = num;
- *denominator = denom;
+ *numerator = std::move (num);
+ *denominator = std::move (denom);
}
/* Assuming DIE corresponds to a fixed point type, finish the creation
@@ -18263,14 +18281,6 @@ finish_fixed_point_type (struct type *type, struct die_info *die,
struct dwarf2_cu *cu)
{
struct attribute *attr;
- /* Numerator and denominator of our fixed-point type's scaling factor.
- The default is a scaling factor of 1, which we use as a fallback
- when we are not able to decode it (problem with the debugging info,
- unsupported forms, bug in GDB, etc...). Using that as the default
- allows us to at least print the unscaled value, which might still
- be useful to a user. */
- ULONGEST scale_num = 1;
- ULONGEST scale_denom = 1;
gdb_assert (type->code () == TYPE_CODE_FIXED_POINT
&& TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FIXED_POINT);
@@ -18281,6 +18291,15 @@ finish_fixed_point_type (struct type *type, struct die_info *die,
if (!attr)
attr = dwarf2_attr (die, DW_AT_small, cu);
+ /* Numerator and denominator of our fixed-point type's scaling factor.
+ The default is a scaling factor of 1, which we use as a fallback
+ when we are not able to decode it (problem with the debugging info,
+ unsupported forms, bug in GDB, etc...). Using that as the default
+ allows us to at least print the unscaled value, which might still
+ be useful to a user. */
+ gdb_mpz scale_num (1);
+ gdb_mpz scale_denom (1);
+
if (attr == nullptr)
{
/* Scaling factor not found. Assume a scaling factor of 1,
@@ -18292,16 +18311,16 @@ finish_fixed_point_type (struct type *type, struct die_info *die,
else if (attr->name == DW_AT_binary_scale)
{
LONGEST scale_exp = attr->constant_value (0);
- ULONGEST *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom;
+ gdb_mpz *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom;
- *num_or_denom = 1 << std::abs (scale_exp);
+ mpz_mul_2exp (num_or_denom->val, num_or_denom->val, std::abs (scale_exp));
}
else if (attr->name == DW_AT_decimal_scale)
{
LONGEST scale_exp = attr->constant_value (0);
- ULONGEST *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom;
+ gdb_mpz *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom;
- *num_or_denom = uinteger_pow (10, std::abs (scale_exp));
+ mpz_ui_pow_ui (num_or_denom->val, 10, std::abs (scale_exp));
}
else if (attr->name == DW_AT_small)
{
@@ -18326,13 +18345,8 @@ finish_fixed_point_type (struct type *type, struct die_info *die,
}
gdb_mpq &scaling_factor = type->fixed_point_info ().scaling_factor;
-
- gdb_mpz tmp_z (scale_num);
- mpz_set (mpq_numref (scaling_factor.val), tmp_z.val);
-
- tmp_z = scale_denom;
- mpz_set (mpq_denref (scaling_factor.val), tmp_z.val);
-
+ mpz_set (mpq_numref (scaling_factor.val), scale_num.val);
+ mpz_set (mpq_denref (scaling_factor.val), scale_denom.val);
mpq_canonicalize (scaling_factor.val);
}
@@ -18398,9 +18412,9 @@ has_zero_over_zero_small_attribute (struct die_info *die,
if (scale_die->tag != DW_TAG_constant)
return false;
- LONGEST num = 1, denom = 1;
+ gdb_mpz num (1), denom (1);
get_dwarf2_rational_constant (scale_die, cu, &num, &denom);
- return (num == 0 && denom == 0);
+ return mpz_sgn (num.val) == 0 && mpz_sgn (denom.val) == 0;
}
/* Initialise and return a floating point type of size BITS suitable for