]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ctf: handle the bit_offset in members with a DW_FORM_block data_member_location
authorNick Alcock <nick.alcock@oracle.com>
Tue, 4 Jul 2017 00:09:01 +0000 (01:09 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Mon, 18 Sep 2017 21:31:29 +0000 (22:31 +0100)
When building a SPARC kernel with GCC 6, the following failure is observed at
CTF generation time:

Internal error: within file arch/sparc/built-in.o, module vmlinux, type at
DIE offset 3fe447 with ID ////unsigned int:23:0  was not already noted by
detect_duplicates().

This is because the bit-field in question
(include/math-emu/single.h:_FP_UNION_S.frac) is at offset 1, not 0: the type
ID being emitted should be ////unsigned int:23:1.  We are not correctly
handling the case where a bit-field at nonzero offset has its
data_member_location represented by a DW_FORM_block: we were erroneously only
considering the bit offset when the form was DW_FORM_*data* (i.e. a simple
constant), because I assumed that in this situation the
DW_AT_data_member_location would track the location at bit granularity.
This is obviously wrong: no matter what form it's in, the
data_member_location is a count of bytes.  It can't suddenly turn into a
count of bits just because it's not being represented as a simple
constant!

So promote the bit-offset handling to apply to all
data_member_locations, regardless of form.

Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
Reviewed-by: Tomas Jedlicka <tomas.jedlicka@oracle.com>
Orabug: 26387109

scripts/dwarf2ctf/dwarf2ctf.c

index 96272364067d9d7d9b51f4f2322658d5012cfe48..59f3ad02c88faeab797c24e6d6d12dc6abc3934d 100644 (file)
@@ -3888,16 +3888,6 @@ static ctf_id_t assemble_ctf_su_member(const char *module_name,
                                dwarf_formudata(&location_attr, &location);
                                offset = location * 8;
                        }
-
-                       if (private_dwarf_hasattr(die, DW_AT_bit_offset)) {
-                               Dwarf_Attribute bit_attr;
-                               Dwarf_Word bit;
-
-                               private_dwarf_attr(die, DW_AT_bit_offset,
-                                          &bit_attr);
-                               dwarf_formudata(&bit_attr, &bit);
-                               bit_offset = bit;
-                       }
                        break;
                }
                case DW_FORM_block1:
@@ -3958,7 +3948,20 @@ static ctf_id_t assemble_ctf_su_member(const char *module_name,
                        exit(1);
                }
                }
-               /* Fall through. */
+
+               /*
+                * Handle the bit offset.
+                */
+               if (private_dwarf_hasattr(die, DW_AT_bit_offset)) {
+                       Dwarf_Attribute bit_attr;
+                       Dwarf_Word bit;
+
+                       private_dwarf_attr(die, DW_AT_bit_offset,
+                                          &bit_attr);
+                       dwarf_formudata(&bit_attr, &bit);
+                       bit_offset = bit;
+               }
+
        } else { /* No offset beyond any override.  */
                die_override_t *o;