fprintf: Add missing closing parens to the align attribute

Noticed while trying to use pfunct's -b option, that will show a
function prototype + the types it uses in its function signature, i.e.:

  $ pfunct -b -f tcp_sendmsg tcp.o
  typedef long long unsigned int __u64;
  typedef __u64 __addrpair;

  typedef unsigned int __u32;
  typedef __u32 __be32;

  typedef short unsigned int __u16;

  typedef __u32 __portpair;

  typedef __u16 __be16;

  struct hlist_node {
  	struct hlist_node *        next;                 /*     0     8 */
  	struct hlist_node * *      pprev;                /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* last cacheline: 16 bytes */
  };

  <SNIP tons of types>

  struct sock {
  	struct sock_common         __sk_common;          /*     0   136 */
  	/* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
  	socket_lock_t              sk_lock;              /*   136    32 */
  	atomic_t                   sk_drops;             /*   168     4 */
  	/* --- cacheline 10 boundary (640 bytes) --- */
<SNIP the rest of the 'struct sock' members>
  	struct sock_cgroup_data    sk_cgrp_data;         /*   640     8 */
  	struct mem_cgroup *        sk_memcg;             /*   648     8 */
  	void                       (*sk_state_change)(struct sock *); /*   656     8 */
  	void                       (*sk_data_ready)(struct sock *); /*   664     8 */
  	void                       (*sk_write_space)(struct sock *); /*   672     8 */
  	void                       (*sk_error_report)(struct sock *); /*   680     8 */
  	int                        (*sk_backlog_rcv)(struct sock *, struct sk_buff *); /*   688     8 */
  	void                       (*sk_destruct)(struct sock *); /*   696     8 */
  	/* --- cacheline 11 boundary (704 bytes) --- */
  	struct sock_reuseport *    sk_reuseport_cb;      /*   704     8 */
  	struct callback_head       sk_rcu __attribute__((__aligned__(8))); /*   712    16 */

  	/* size: 728, cachelines: 12, members: 84 */
  	/* sum members: 715, holes: 4, sum holes: 8 */
  	/* sum bitfield members: 40 bits (5 bytes) */
  	/* paddings: 1, sum paddings: 4 */
  	/* forced alignments: 1 */
  	/* last cacheline: 24 bytes */
  };

<SNIP some more types>

  struct kiocb;

  struct msghdr {
  	void *                     msg_name;             /*     0     8 */
  	int                        msg_namelen;          /*     8     4 */

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

  	struct iov_iter            msg_iter;             /*    16    40 */
  	void *                     msg_control;          /*    56     8 */
  	/* --- cacheline 1 boundary (64 bytes) --- */
  	__kernel_size_t            msg_controllen;       /*    64     8 */
  	unsigned int               msg_flags;            /*    72     4 */

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

  	struct kiocb *             msg_iocb;             /*    80     8 */

  	/* size: 88, cachelines: 2, members: 7 */
  	/* sum members: 80, holes: 2, sum holes: 8 */
  	/* last cacheline: 24 bytes */
  };

  typedef __kernel_size_t size_t;

  int tcp_sendmsg(struct sock * sk, struct msghdr * msg, size_t size);
  $

So if we then redirect the output to a file and if we make it a empty
function instead of a prototype, i.e. if we make the last line above to
become this:

  int tcp_sendmsg(struct sock * sk, struct msghdr * msg, size_t size) {}

then build with gcc -g to have it build as a .o with DWARF info, then we
should be able to see if the struct rebuilt from DWARF matches the
original struct used to generate the DWARF, going full circle:

  $ pfunct -b -f tcp_sendmsg tcp.o > tcp_sendmsg_types.c
  $ gcc -c tcp_sendmsg_types.c -g
  $ file tcp_sendmsg_types.o
  tcp_sendmsg_types.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), with debug_info, not stripped
  $ pahole -E -C sock tcp_sendmsg_types.o > tcp_sendmsg_types.o.pahole
  $ pahole -E -C sock tcp.o > tcp.o.pahole
  $ diff -u tcp_sendmsg_types.o.pahole tcp.o.pahole
  $ wc -l tcp_sendmsg_types.o.pahole
  420 tcp_sendmsg_types.o.pahole
  $

So all the types that come from sock are expanded and all its details
are reconstructed in the same way for both cases.

  $ pahole -C sock tcp.o | tail
	struct sock_reuseport *    sk_reuseport_cb;      /*   704     8 */
	struct callback_head       sk_rcu __attribute__((__aligned__(8))); /*   712    16 */

	/* size: 728, cachelines: 12, members: 84 */
	/* sum members: 715, holes: 4, sum holes: 8 */
	/* sum bitfield members: 40 bits (5 bytes) */
	/* paddings: 1, sum paddings: 4 */
	/* forced alignments: 1 */
	/* last cacheline: 24 bytes */
  };
  $ pahole -C sock tcp_sendmsg_types.o | tail
	struct sock_reuseport *    sk_reuseport_cb;      /*   704     8 */
	struct callback_head       sk_rcu __attribute__((__aligned__(8))); /*   712    16 */

	/* size: 728, cachelines: 12, members: 84 */
	/* sum members: 715, holes: 4, sum holes: 8 */
	/* sum bitfield members: 40 bits (5 bytes) */
	/* paddings: 1, sum paddings: 4 */
	/* forced alignments: 1 */
	/* last cacheline: 24 bytes */
  };
  $

Reported-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andrii Nakryiko <andriin@fb.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2019-04-04 10:48:17 -03:00
parent d83d9f578f
commit a7d9c58cb8
1 changed files with 1 additions and 1 deletions

View File

@ -775,7 +775,7 @@ static size_t class_member__fprintf(struct class_member *member, bool union_memb
}
if (!sconf.suppress_aligned_attribute && member->alignment != 0)
printed += fprintf(fp, " __attribute__((__aligned__(%u))", member->alignment);
printed += fprintf(fp, " __attribute__((__aligned__(%u)))", member->alignment);
fputc(';', fp);
++printed;