From a7d9c58cb81a946fcc1d7d974acd8faaca2bf886 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 4 Apr 2019 10:48:17 -0300 Subject: [PATCH] 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 */ }; 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) --- */ 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 */ }; 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 Cc: Andrii Nakryiko Cc: Alexei Starovoitov Cc: Yonghong Song Signed-off-by: Arnaldo Carvalho de Melo --- dwarves_fprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index fbe0479..d6468a1 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -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;