]> www.infradead.org Git - users/jedix/linux-maple.git/commit
ctf: bitfield support
authorNick Alcock <nick.alcock@oracle.com>
Thu, 2 Feb 2017 00:22:05 +0000 (00:22 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 26 May 2017 00:06:09 +0000 (01:06 +0100)
commite5ab1239e6c938587ad9ca754bde1a735d65a230
tree0ae70686b84005fd12eb44a7ed8683f250af4eaf
parente9f8f51638a159fe9e2d87bcc01be5d510034861
ctf: bitfield support

Support for bitfields in dwarf2ctf was embryonic and largely untested
before now due to bugs in libdtrace-ctf: with a fix for those in hand,
we can fix bitfields here too.

Bitfields in DWARF and CTF have annoyingly different representations.
In DWARF, a bitfield is represented something like this:

 [ 16561]      member
               name                 (string) "ihl"
               decl_file            (data1) 225
               decl_line            (data1) 87
               type                 (ref4) [    38]
               byte_size            (data1) 1
               bit_size             (data1) 4
               bit_offset           (data1) 4
               data_member_location (sdata) 0
[...]
 [    38]    typedef
             name                 (strp) "__u8"
             decl_file            (data1) 36
             decl_line            (data1) 20
             type                 (ref4) [    43]

i.e. the padding, size, and starting location are all represented in the
member, where you would conceptually expect it to be.

In CTF, the starting location of the conceptual containing type of a
bitfield is encoded in the member: but the size and starting location of
the bitfield itself is represented in the dependent type, which is added
as a "non-root" type (which cannot be looked up by name) so that it can
have the same name as the un-bitfielded base type without causing a name
clash.

We use the new DIE attribute override mechanism added in commit 8935199962
to override DW_AT_bit_size and DW_AT_bit_offset for such members (fixing
a pre-existing bug in the process: we were looking for the DW_AT_bit_size
on the structure as a whole!), and in the base-type emission function
 checking for the existence of a DW_AT_bit_size/offset and responding to
them by overriding the size and offset derived from DW_AT_byte_size and
noting that this is a non-root type.  (The override needed, annoyingly,
is endian-dependent, because CTF consumers assume that on little-endian
systems the offset relates to the least-significant edge of the bitfield,
counting from the LSB, while DWARF assumes the opposite).

But this is not enough: unless more is done, this type will appear
to have the same type ID as its non-bitfield equivalent, leading to
confusion about which CTF file it should appear in and quite possibly
leading to it ending up in a CTF file that the structure containing the
bitfield cannot even see.  So augment type_id()'s representation of
base types from e.g. 'int' to something like 'int:4' if and only if
a DW_AT_bit_size or an override of it is present and that override is
a different size from the native bitness of the type itself (the
DW_AT_byte_size).  We encode the bit_offset only if there is also a
bit_size, as something like int:4:2.  (That's unambiguous because
these attributes always arrive in pairs in bitfields and never appear
in anything else in C-generated DWARF.)

Finally, this breaks an optimization in the deduplicator, which was that
all structure members reference some top-level type, so when marking a
type as seen, structure members could just be skipped.  Now, they have
to be chased iff they are bitfields using the same override trickery as
above to change the DW_AT_bit_size/offset in the member's type DIE, and
that bitfield override needs to be passed down to type_id() when finally
marking duplicated types as shared too.  (Avoid code duplication by
factoring out some related code from a horrible conditional in
detect_duplicates() into a new type_needs_sharing() function.)

Orabug: 25815129
Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
Reviewed-by: tomas.jedlicka@oracle.com
scripts/dwarf2ctf/dwarf2ctf.c