]> www.infradead.org Git - users/jedix/linux-maple.git/commit
ctf: spot non-struct/union/enum children of DW_TAG_structure_type
authorNick Alcock <nick.alcock@oracle.com>
Thu, 23 Jan 2014 23:23:00 +0000 (23:23 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Tue, 21 Jul 2015 14:29:30 +0000 (15:29 +0100)
commit9bfab8638e8d089f7e0c03d0c995a0dafa1641ef
tree9f8585c658926f35c1933f90666209001b42faf7
parent15de1732f33faa494b71c1819d17c39800662b52
ctf: spot non-struct/union/enum children of DW_TAG_structure_type

One of the jobs of the dwarf2ctf duplicate detector is to trace the members of
structures and unions in every kernel module, one by one, and recursively mark
the types of every such member as used in that module; any such types used in
more than one module are promoted to the shared type repository (and marked as
used in that in the same way). In conjunction with a variety of other rules,
this ensures that types in per-module type repositories can refer to types in
the shared type repository, but that the shared repository is self-contained:
DTrace userspace can then load any module's type repository, set its parent to
be the shared type repository, and be sure that it can fully characterize any
type in that module.

dwarf2ctf was aborting because a type was missed by the duplicate detector but
then emitted by the type generation phase.  The type in question is found in
drivers/message/i2o/i2o_proc.c:

typedef struct _i2o_user_table {
[...]
} i2o_user_table;

struct {
[...]
i2o_user_table user[64];
} *result;

The array is represented as the following:

 [  beca]      structure_type
 [  bf2f]  member
 name       (strp) "user"
 type       (ref4) [ bfa9]

 [  bfa9]    array_type
     type   (ref4) [  bebe]
     sibling   (ref4) [  bfb9]

 [  bebe]      typedef
       name     (strp) "i2o_user_table"
       decl_file     (data1) 1
       decl_line     (data2) 1114
       type     (ref4) [  be6f]

 [  be6f]      structure_type
       name     (strp) "_i2o_user_table"
       byte_size     (data1) 8
       decl_file     (data1) 1
       decl_line     (data2) 1108
       sibling     (ref4) [  bebe]

As the indentation makes clear, in GCC 4.4.x the array_type is at the top level,
where it is always spotted by the duplicate detector as a matter of course.  In
fact, in GCC 4.4.x *no* types other than aggregates are ever emitted as children
of structure_types: they're all at the top level and thus trivially detected by
the walk through top-level types that the duplicate detector does as a matter of
course: so this part of the scanning phase only needs to look at the types of
structures, unions and enumerations, to handle perverse cases like

       struct foo {
   struct {
       int womble;
   } *baz;
       };

in which the innermost struct's DIE (but *not* the pointer to it) is represented
as a child of the outer one's, even in GCC 4.4.x.

In GCC 4.8.x this is no longer true: the array_type DIE above is emitted as a
direct child of the structure_type here shown as [ beca], and indeed you can see
all sorts of types as children of structure_types, even basic types like 'int'
if they happen not to be used anywhere else in the translation unit.  So we must
mark them all as seen.

-- or almost all.  We do not bother marking types we will not later emit CTF
for, and we do not mark structure or union members themselves, because structure
members are not types and cannot be referenced by another member.  (Since
members are very numerous and cannot be duplicated across kernel modules unless
their containing structure is also duplicated, not marking them as seen also
saves a great deal of memory.)

Thankfully the emission phase does not care what the parent of DIEs is except if
they are things like structures or unions which have parents in CTF too.  So
arrays, basic types, and the like inside structure_type DIEs do not disturb the
actual emission of types: once we have fixed the duplicate detector, all is
well.

Orabug: 18117464
Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
Reviewed-by: Chuck Anderson <chuck.anderson@oracle.com>
Documentation/dwarf2ctf
scripts/dwarf2ctf/dwarf2ctf.c