aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2019-11-30 10:05:23 -0700
committerTom Tromey <tom@tromey.com>2019-11-30 20:47:44 -0700
commit489dbda6a8d6d54bbc349c7048553fc5f791cb41 (patch)
treef2e6fa591fdec540aa51bf967003548d033be018
parent425124817eef869ad3595a03aaa999cbb1504bb6 (diff)
downloadbinutils-489dbda6a8d6d54bbc349c7048553fc5f791cb41.zip
binutils-489dbda6a8d6d54bbc349c7048553fc5f791cb41.tar.gz
binutils-489dbda6a8d6d54bbc349c7048553fc5f791cb41.tar.bz2
Correctly compute length of DW_TAG_variant_part union
Currently, gdb internally transforms DW_TAG_variant_part into a union (with some special attbributes). When doing so, it computes the length of this union from the length of the fields. However, this computation didn't include the offset of these fields, resulting in the length being too short. This is not a problem given the way the code currently works. However, I have a patch series to switch gdb to value-based printing, where this does have an impact. Tested on x86-64 Fedora 28; and, considering that this only affects Rust, I am checking it in. gdb/ChangeLog 2019-11-30 Tom Tromey <tom@tromey.com> * dwarf2read.c (dwarf2_add_field): Include field offset when computing variant part length. Change-Id: I25d84fc237eb3c1e7f11f6eaf35ffe198efde6cc
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/dwarf2read.c11
2 files changed, 13 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 96efdb0..621cbbb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2019-11-30 Tom Tromey <tom@tromey.com>
+
+ * dwarf2read.c (dwarf2_add_field): Include field offset when
+ computing variant part length.
+
2019-11-30 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* NEWS: Mention define-prefix. Tell that command names can now
contain a . character.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 40626a1..fd7d21c 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -15252,13 +15252,18 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
/* Normally a DW_TAG_variant_part won't have a size, but our
representation requires one, so set it to the maximum of the
- child sizes. */
+ child sizes, being sure to account for the offset at which
+ each child is seen. */
if (TYPE_LENGTH (fp->type) == 0)
{
unsigned max = 0;
for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i)
- if (TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)) > max)
- max = TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i));
+ {
+ unsigned len = ((TYPE_FIELD_BITPOS (fp->type, i) + 7) / 8
+ + TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)));
+ if (len > max)
+ max = len;
+ }
TYPE_LENGTH (fp->type) = max;
}
}