[Dwarf-Discuss] EXTERNAL: Corner-cases with bitfields
Todd Allen
todd.allen@concurrent-rt.com
Fri May 6 20:08:45 GMT 2022
>
> Dear all,
>
> During our work on debugging support of compute workloads on AMDGPU[1],
> we (at AMD) have been seeing two cases regarding description of
> bitfields in DWARF for which we do not find definitive answers in the
> DWARF documentation. For those cases, when experiencing with usual CPU
> targets we observe different behaviors on different toolchains. As a
> consequence, we would like to discuss those points here to gather
> feedbacks. If deemed necessary, we will submit a formal clarification
> issue to the dwarf committee.
>
> Both of the cases we present below impact how arguments are passed
> during function calls in the ABI for at least our target (AMDGPU).
> However, the debug information available to the debugger does not give
> enough information to decide how to handle the type and the spec does
> not really say what debug information should be generated to properly
> describe those cases. Also note that in both case, the DWARF
> information we have is sufficient to describe the memory layout of the
> types.
>
> 1 - Bitfield member with a size matching its underlying type:
>
> The first point we would like to discuss is the one of bitfield members
> whose sizes match their underlying type. Let's consider the following
> example:
>
> struct Foo
> {
> char a :???8;
> char b : 8;
> };
>
> If we compile such example with GCC it will add the `DW_AT_bit_size` and
> `DW_AT_bit_offset` attributes to the `a` and `b` DIEs.
>
> Clang on the other hand will not produce those attributes.
>
> On the debugger side, GDB currently considers a struct member as being
> packed (i.e. part of a bitfield) if it has the `DW_AT_bit_size`
> attribute present and is non-0. Therefore, GDB will "understand"
> what GCC produces, but not what Clang produces.
>
> What Clang does seems to be a reasonable thing to do if one is only
> interested in the memory layout of the type. This however is not
> sufficient in our case to decide how to handle such type when
> placing/inspecting arguments in registers in the context of function
> calls. In our ABI, bitfield members are passed packed together, while
> two chars in a struct would be placed in separate registers.
>
> To clarify this situation, it would be helpful that a producer always
> includes the DW_AT_bit_size attribute for bit field, which the standard
> does not suggest nor require.
>
It sounds like your ABI is basing its decision on a boolean: is the field a bit
field or not. And you're trying to deduce this from DW_AT_bit_offset. Perhaps
a better solution would be to make this explicit in the DWARF, some new
DW_AT_bitfield flag. There's very little that the DWARF standard can do to
mandate such an attribute. (Permissive standard yadda yadda.) But if it's
necessary for debuggers to work correctly in a given ABI, compilers should be
well-motivated to produce it when generating code for that ABI.
> 2 - Unnamed zero sized bitfield
>
> Another case we met is related to unnamed fields with a size of 0 bits.
> Such field is defined in the c++ standard as (in 9.6 Bit-Fields):
>
> > As a special case, an unnamed bit-field with a width of zero
> > specifies alignment of the next bit-field at an allocation unit
> > boundary
>
> If we now consider an extended version of our previous example:
>
> struct Foo
> {
> char a : 8;
> char : 0;
> char b :???8,
> };
>
> Neither GCC nor Clang give any information about the unnamed bitfield.
> As for the previous case, the presence of such field impacts how
> arguments are passed during function calls on our target, leaving the
> debugger unable to properly decide how to handle such cases.
>
> As for the previous case, both compilers can properly describe Foo's
> memory layout using DW_AT_bit_offset.
>
> It seems that such 0-sized field also has impact on ABI on other targets
> such as armv7hl and aarch64 as discussed in [2]. Should the DWARF
> specification give some guidance on how to handle such situation?
>
> All thoughts on those cases are welcome.
>
I'm agreeing with Michael that describing the unnamed bitfield seems dubious.
If it does impact the ABI, I'm wondering if that impact is indirect: that is,
the presence of this 0-width bit field changes an attribute of the next field,
and that attribute is responsible for difference in the behavior. If so, is
there any way other than a 0-width bit field to cause the same behavior? This
might be another case where describing the attribute that's directly responsible
might be better.
--
Todd Allen
Concurrent Real-Time
More information about the Dwarf-discuss
mailing list