fprintf: Add unnamed bitfield padding at the end to rebuild original type

Just like the 'struct timex' in the linux kernel UAPI, that is now
correctly reconstructed as:

  $ pahole -IC timex /home/acme/git/build/v5.0-rc2+/kernel/time/posix-clock.o | tail -32
          __kernel_long_t            ppsfreq;              /*    96     8 */
          __kernel_long_t            jitter;               /*   104     8 */
          int                        shift;                /*   112     4 */

          /* XXX 4 bytes hole, try to pack */

          __kernel_long_t            stabil;               /*   120     8 */
          /* --- cacheline 2 boundary (128 bytes) --- */
          __kernel_long_t            jitcnt;               /*   128     8 */
          __kernel_long_t            calcnt;               /*   136     8 */
          __kernel_long_t            errcnt;               /*   144     8 */
          __kernel_long_t            stbcnt;               /*   152     8 */
          int                        tai;                  /*   160     4 */

          /* Force padding: */
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;
          int                        :32;

          /* size: 208, cachelines: 4, members: 20 */
          /* sum members: 152, holes: 3, sum holes: 12 */
          /* padding: 44 */
          /* last cacheline: 16 bytes */
  };
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2019-04-09 21:38:21 -03:00
parent ccd67bdb20
commit 13e5b9fc00
1 changed files with 18 additions and 1 deletions

View File

@ -1544,6 +1544,24 @@ static size_t __class__fprintf(struct class *class, const struct cu *cu,
last = pos;
}
if (class->padding != 0) {
tag_pos = cu__type(cu, last->tag.type);
size = tag__size(tag_pos, cu);
if (is_power_of_2(size) && class->padding > cu->addr_size) {
int added_padding;
int bit_size = size * 8;
printed += fprintf(fp, "\n%.*s/* Force padding: */\n", cconf.indent, tabs);
for (added_padding = 0; added_padding < class->padding; added_padding += size) {
printed += fprintf(fp, "%.*s", cconf.indent, tabs);
printed += type__fprintf(tag_pos, cu, "", &cconf, fp);
printed += fprintf(fp, ":%u;\n", bit_size);
}
}
}
if (!cconf.show_only_data_members)
class__vtable_fprintf(class, cu, &cconf, fp);
@ -1620,7 +1638,6 @@ static size_t __class__fprintf(struct class *class, const struct cu *cu,
cconf.indent, tabs,
type->size, sum_bytes, sum_bits, sum_holes, sum_bit_holes, size_diff);
out:
printed += fprintf(fp, "%.*s}%s%s", indent, tabs, cconf.suffix ? " ": "", cconf.suffix ?: "");
if (type->alignment != 0)