210dffe0d1
26 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Arnaldo Carvalho de Melo
|
e0773683fa |
dwarves: Allow setting a struct/class member as the source of sizeof()
This one just allows that to be set, i.e.: $ pahole -C perf_event_header ~/bin/perf struct perf_event_header { __u32 type; /* 0 4 */ __u16 misc; /* 4 2 */ __u16 size; /* 6 2 */ /* size: 8, cachelines: 1, members: 3 */ /* last cacheline: 8 bytes */ }; $ pahole -C 'perf_event_header(sizeof=size)' --seek_bytes=0x348 --count 1 ~/bin/perf < perf.data { .type = 0xa, .misc = 0x2, .size = 0x68, }, $ But: $ pahole -C 'perf_event_header(sizeof=bla)' --seek_bytes=0x348 --count 1 ~/bin/perf < perf.data pahole: the sizeof member 'bla' not found in the 'perf_event_header' type $ And: $ pahole -C 'perf_event_header(size=misc)' --seek_bytes=0x348 --count 1 ~/bin/perf < perf.data pahole: invalid arg 'size' in 'perf_event_header(size=misc)' (known args: sizeof=member) $ The next cset will implement sizeof(type) with that modifier, using the stdin bytes to obtain the size (0x68) in the above case, and then we'll be able to print a sequence of variable-sized records correctly. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
ccf3eebfcd |
btf_loader: Add support for BTF_KIND_FUNC
Some changes to the fprintf routines were needed, as BTF has as the function type just a BTF_KIND_FUNC_PROTO, while DWARF has as the type for a function its return value type. With a function->btf flag this was overcome and all the other goodies in pfunct are present, for instance: $ pahole -JV examples/tcp.o | grep -w FUNC | head [4068] FUNC tcp_init type_id=4067 [4070] FUNC tcp_abort type_id=4069 [4072] FUNC tcp_done type_id=4071 [4074] FUNC tcp_md5_hash_key type_id=4073 [4076] FUNC tcp_md5_hash_skb_data type_id=4075 [4078] FUNC tcp_get_md5sig_pool type_id=4077 [4080] FUNC tcp_alloc_md5sig_pool type_id=4079 [4082] FUNC compat_tcp_getsockopt type_id=4081 [4084] FUNC tcp_getsockopt type_id=4083 [4086] FUNC tcp_get_timestamping_opt_stats type_id=4085 $ $ pfunct -F btf examples/tcp.o | head memset memcpy tcp_enter_memory_pressure tcp_leave_memory_pressure tcp_init_sock tcp_init_transfer tcp_poll tcp_ioctl tcp_splice_read sk_stream_alloc_skb $ $ pfunct --prototype -F btf examples/tcp.o | head void * memset(void * p, int c, __kernel_size_t size); void * memcpy(void * p, const void * q, __kernel_size_t size); void tcp_enter_memory_pressure(struct sock * sk); void tcp_leave_memory_pressure(struct sock * sk); void tcp_init_sock(struct sock * sk); void tcp_init_transfer(struct sock * sk, int bpf_op); __poll_t tcp_poll(struct file * file, struct socket * sock, poll_table * wait); int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg); ssize_t tcp_splice_read(struct socket * sock, loff_t * ppos, struct pipe_inode_info * pipe, size_t len, unsigned int flags); struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule); $ Now to ask just for the 'struct sock' 'methods', i.e. functions that have as one of its arguments a pointer to the given 'class' name: $ pfunct --class sock -F btf examples/tcp.o | head tcp_abort tcp_done compat_tcp_getsockopt tcp_getsockopt tcp_get_info compat_tcp_setsockopt tcp_setsockopt tcp_disconnect tcp_write_queue_purge tcp_close $ Then ask for the prototypes, which requires -V, should have that fixed: $ pfunct -V --prototypes --class sock -F btf examples/tcp.o | head int tcp_abort(struct sock * sk, int err); void tcp_done(struct sock * sk); int compat_tcp_getsockopt(struct sock * sk, int level, int optname, char * optval, int * optlen); int tcp_getsockopt(struct sock * sk, int level, int optname, char * optval, int * optlen); void tcp_get_info(struct sock * sk, struct tcp_info * info); int compat_tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen); int tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen); int tcp_disconnect(struct sock * sk, int flags); void tcp_write_queue_purge(struct sock * sk); void tcp_close(struct sock * sk, long int timeout); $ Don't like prototypes with parm names, got you covered: $ pfunct --no_parm_names -V --prototypes --class sock -F btf examples/tcp.o | head int tcp_abort(struct sock *, int); void tcp_done(struct sock *); int compat_tcp_getsockopt(struct sock *, int, int, char *, int *); int tcp_getsockopt(struct sock *, int, int, char *, int *); void tcp_get_info(struct sock *, struct tcp_info *); int compat_tcp_setsockopt(struct sock *, int, int, char *, unsigned int); int tcp_setsockopt(struct sock *, int, int, char *, unsigned int); int tcp_disconnect(struct sock *, int); void tcp_write_queue_purge(struct sock *); void tcp_close(struct sock *, long int); $ Don't like long options and want just one function? $ pfunct -f tcp_setsockopt -F btf examples/tcp.o int tcp_setsockopt(struct sock * sk, int level, int optname, char * optval, unsigned int optlen); $ Want to generate compileable code for all of those functions, full with the necessary types, etc? $ pfunct -F btf --compile examples/tcp.o > a.c $ gcc -c -o a.o a.c $ pfunct -F dwarf --prototypes --class sock a.o | head pfunct: a.o: No debugging information found $ gcc -g -c -o a.o a.c $ pfunct -V -F dwarf --prototypes --class sock a.o | head void tcp_enter_memory_pressure(struct sock * sk); void tcp_leave_memory_pressure(struct sock * sk); void tcp_init_sock(struct sock * sk); void tcp_init_transfer(struct sock * sk, int bpf_op); int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg); struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule); ssize_t do_tcp_sendpages(struct sock * sk, struct page * page, int offset, size_t size, int flags); int tcp_sendpage_locked(struct sock * sk, struct page * page, int offset, size_t size, int flags); int tcp_sendpage(struct sock * sk, struct page * page, int offset, size_t size, int flags); int tcp_sendmsg_locked(struct sock * sk, struct msghdr * msg, size_t size); $ Now lets go full circle and encode BTF for this a.o generated from source code generated from the original BTF info in that examples/tcp.o file: $ pahole -JV a.o | tail [465] FUNC_PROTO (anon) return=35 args=(392 hp, 393 skb, 5 header_len) [466] FUNC tcp_md5_hash_skb_data type_id=465 [467] FUNC_PROTO (anon) return=35 args=(392 hp, 394 key) [468] FUNC tcp_md5_hash_key type_id=467 [469] FUNC_PROTO (anon) return=0 args=(49 sk) [470] FUNC tcp_done type_id=469 [471] FUNC_PROTO (anon) return=35 args=(49 sk, 35 err) [472] FUNC tcp_abort type_id=471 [473] FUNC_PROTO (anon) return=0 args=(void) [474] FUNC tcp_init type_id=473 $ $ pfunct -F btf -V --prototypes --class=sock a.o | head void tcp_enter_memory_pressure(struct sock * sk); void tcp_leave_memory_pressure(struct sock * sk); void tcp_init_sock(struct sock * sk); void tcp_init_transfer(struct sock * sk, int bpf_op); int tcp_ioctl(struct sock * sk, int cmd, long unsigned int arg); struct sk_buff * sk_stream_alloc_skb(struct sock * sk, int size, gfp_t gfp, bool force_schedule); ssize_t do_tcp_sendpages(struct sock * sk, struct page * page, int offset, size_t size, int flags); int tcp_sendpage_locked(struct sock * sk, struct page * page, int offset, size_t size, int flags); int tcp_sendpage(struct sock * sk, struct page * page, int offset, size_t size, int flags); int tcp_sendmsg_locked(struct sock * sk, struct msghdr * msg, size_t size); $ Curious about the code generated by 'pfunct -F btf --compile examples/tcp.o? http://vger.kernel.org/~acme/pahole/pfunct-F-BTF--compile-examples-tcp.o.txt Cc: Alexei Starovoitov <ast@fb.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com> Cc: Andrii Nakryiko <andriin@fb.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
910e060b5c |
btf_loader: Skip BTF_KIND_DATASEC entries
Just skip them, we have no use for them so far, skipping them will allow us to process the other kinds we have use for. Cc: Andrii Nakryiko <andriin@fb.com> Cc: Daniel Bristot de Oliveira <bristot@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
96235a74a3 |
btf_loader: Replace if/else series with a proper switch {}
A switch is the right thing here, use it. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
a4ba2234ff |
btf_loader: Support BTF_KIND_VAR
Now the output for DWARF and BTF match, modulo warnings about some BTF_KIND_ still not supported: [root@quaco tracebuffer]# pglobal -F dwarf -v bristot.o struct ____btf_map_tracebuffer__bristot ____btf_map_tracebuffer__bristot;; /* 0 */ char _license[4];; /* 0 */ int _version;; /* 0 */ struct bpf_map tracebuffer__bristot;; /* 0 */ [root@quaco tracebuffer]# pglobal -F btf -v bristot.o BTF: idx: 17, off: 352, Unknown kind 15 BTF: idx: 18, off: 364, Unknown kind 0 BTF: idx: 19, off: 376, Unknown kind 15 BTF: idx: 20, off: 388, Unknown kind 0 BTF: idx: 21, off: 400, Unknown kind 15 BTF: idx: 22, off: 412, Unknown kind 0 BTF: idx: 23, off: 424, Unknown kind 15 BTF: idx: 24, off: 436, Unknown kind 0 struct ____btf_map_tracebuffer__bristot ____btf_map_tracebuffer__bristot;; /* 0 */ char _license[4];; /* 0 */ int _version;; /* 0 */ struct bpf_map tracebuffer__bristot;; /* 0 */ [root@quaco tracebuffer]# Cc: Andrii Nakryiko <andriin@fb.com> Cc: Daniel Bristot de Oliveira <bristot@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
173911ac38 |
btf_loader: Show the unknown kind numbers
Instead of just telling that some unknown BTF_KIND_ was found in a file, show the number to help in debugging. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
092fffe567 |
btf_loader: Enum values are s32, cast before calling btf_elf__get32()
Addressing this compiler warning: /home/acme/git/pahole/btf_loader.c:279:41: error: pointer targets in passing argument 2 of ‘btf_elf__get32’ differ in signedness [-Werror=pointer-sign] uint32_t value = btf_elf__get32(btfe, &ep[i].val); ^~~~~~~~~~ In file included from /home/acme/git/pahole/btf_loader.c:27: /home/acme/git/pahole/libbtf.h:63:10: note: expected ‘uint32_t *’ {aka ‘unsigned int *’} but argument is of type ‘__s32 *’ {aka ‘int *’} uint32_t btf_elf__get32(struct btf_elf *btf, uint32_t *p); ^~~~~~~~~~~~~~ cc1: all warnings being treated as errors Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
de5e72bc15 |
btf_loader: Plug leak when bailing out due to unknown tag
Fixes this coverity report:
Error: RESOURCE_LEAK (CWE-772): [#def2]
dwarves-1.13/btf_loader.c:342: alloc_fn: Storage is returned from allocation function "zalloc".
dwarves-1.13/btf_loader.c:342: var_assign: Assigning: "tag" = storage returned from "zalloc(40UL)".
dwarves-1.13/btf_loader.c:354: leaked_storage: Variable "tag" going out of scope leaks the storage it points to.
# 352| default:
# 353| printf("%s: FOO %d\n\n", __func__, type);
# 354|-> return 0;
# 355| }
# 356|
Reported-by: William Cohen <wcohen@redhat.com>
Fixes:
|
||
Andrii Nakryiko
|
c0fdc5e685 |
dwarf_loader: Use DWARF recommended uniform bit offset scheme
Use uniform bit offset scheme as described in DWARF standard (though apparently not really followed by major compilers), in which bit offset is a natural extension of byte offset in both big- and little-endian architectures. BEFORE: 1. Bit offsets for little-endian are output as offsets from highest-order bit of underlying int to highest-order bit of bitfield, so double-backwards for little-endian arch and counter to how byte offsets are used, which point to lowest-order bit of underlying type. This makes first bitfield to have bit offset 27, instead of natural 0. 2. Bit offsets for big-endian are output as expected, by referencing highest-order bit offset from highest-order bit of underlying int. This is natural for big-endian platform, e.g., first bitfield has bit offset of 0. 3. Big-endian target also has problem with determining bit holes, because bit positions have to be calculated differently for little- and big-endian platforms and previous commit changed pahole logic to follow little-endian semantics. 4. BTF encoder outputs uniform bit offset for both little- and big-endian format (following DWARF's recommended bit offset scheme) 5. BTF loader, though, follows DWARF loader's format and outputs little-endian bit offsets "double-backwards". $ gcc -g dwarf_test.c -o dwarf_test $ pahole -F dwarf dwarf_test struct S { int j:5; /* 0:27 4 */ int k:6; /* 0:21 4 */ int m:5; /* 0:16 4 */ int n:8; /* 0: 8 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit_padding: 8 bits */ /* last cacheline: 4 bytes */ }; $ pahole -JV dwarf_test File dwarf_test: [1] STRUCT S kind_flag=1 size=4 vlen=4 j type_id=2 bitfield_size=5 bits_offset=0 k type_id=2 bitfield_size=6 bits_offset=5 m type_id=2 bitfield_size=5 bits_offset=11 n type_id=2 bitfield_size=8 bits_offset=16 [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED $ pahole -F btf dwarf_test struct S { int j:5; /* 0:27 4 */ int k:6; /* 0:21 4 */ int m:5; /* 0:16 4 */ int n:8; /* 0: 8 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit_padding: 8 bits */ /* last cacheline: 4 bytes */ }; $ aarch64-linux-gnu-gcc -mbig-endian -g -c dwarf_test.c -o dwarf_test.be $ pahole -F dwarf dwarf_test.be struct S { /* XXX 27 bits hole, try to pack */ int j:5; /* 0: 0 4 */ /* XXX 245 bits hole, try to pack */ int k:6; /* 0: 5 4 */ /* XXX 245 bits hole, try to pack */ int m:5; /* 0:11 4 */ /* XXX 243 bits hole, try to pack */ int n:8; /* 0:16 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit holes: 4, sum bit holes: 760 bits */ /* bit_padding: 16 bits */ /* last cacheline: 4 bytes */ /* BRAIN FART ALERT! 4 bytes != 24 (member bits) + 0 (byte holes) + 760 (bit holes), diff = -768 bits */ }; $ pahole -JV dwarf_test.be File dwarf_test.be: [1] STRUCT S kind_flag=1 size=4 vlen=4 j type_id=2 bitfield_size=5 bits_offset=0 k type_id=2 bitfield_size=6 bits_offset=5 m type_id=2 bitfield_size=5 bits_offset=11 n type_id=2 bitfield_size=8 bits_offset=16 [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED $ pahole -F btf dwarf_test.be struct S { /* XXX 27 bits hole, try to pack */ int j:5; /* 0: 0 4 */ /* XXX 245 bits hole, try to pack */ int k:6; /* 0: 5 4 */ /* XXX 245 bits hole, try to pack */ int m:5; /* 0:11 4 */ /* XXX 243 bits hole, try to pack */ int n:8; /* 0:16 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit holes: 4, sum bit holes: 760 bits */ /* bit_padding: 16 bits */ /* last cacheline: 4 bytes */ /* BRAIN FART ALERT! 4 bytes != 24 (member bits) + 0 (byte holes) + 760 (bit holes), diff = -768 bits */ }; AFTER: 1. Same output for little- and big-endian binaries, both for BTF and DWARF loader. 2. For little-endian target, bit offsets are natural extensions of byte offset, counting from lowest-order bit of underlying int to lowest-order bit of a bitfield. 3. BTF encoder still emits correct and natural bit offsets (for both binaries). 4. No more BRAIN FART ALERTs for big-endian. $ pahole -F dwarf dwarf_test struct S { int j:5; /* 0: 0 4 */ int k:6; /* 0: 5 4 */ int m:5; /* 0:11 4 */ int n:8; /* 0:16 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit_padding: 8 bits */ /* last cacheline: 4 bytes */ }; $ pahole -JV dwarf_test File dwarf_test: [1] STRUCT S kind_flag=1 size=4 vlen=4 j type_id=2 bitfield_size=5 bits_offset=0 k type_id=2 bitfield_size=6 bits_offset=5 m type_id=2 bitfield_size=5 bits_offset=11 n type_id=2 bitfield_size=8 bits_offset=16 [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED $ pahole -F btf dwarf_test struct S { int j:5; /* 0: 0 4 */ int k:6; /* 0: 5 4 */ int m:5; /* 0:11 4 */ int n:8; /* 0:16 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit_padding: 8 bits */ /* last cacheline: 4 bytes */ }; $ pahole -F dwarf dwarf_test.be struct S { int j:5; /* 0: 0 4 */ int k:6; /* 0: 5 4 */ int m:5; /* 0:11 4 */ int n:8; /* 0:16 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit_padding: 8 bits */ /* last cacheline: 4 bytes */ }; $ pahole -JV dwarf_test.be File dwarf_test.be: [1] STRUCT S kind_flag=1 size=4 vlen=4 j type_id=2 bitfield_size=5 bits_offset=0 k type_id=2 bitfield_size=6 bits_offset=5 m type_id=2 bitfield_size=5 bits_offset=11 n type_id=2 bitfield_size=8 bits_offset=16 [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED $ pahole -F btf dwarf_test.be struct S { int j:5; /* 0: 0 4 */ int k:6; /* 0: 5 4 */ int m:5; /* 0:11 4 */ int n:8; /* 0:16 4 */ /* size: 4, cachelines: 1, members: 4 */ /* bit_padding: 8 bits */ /* last cacheline: 4 bytes */ }; FOR REFERENCE. Relevant parts of DWARF output from GCC (clang outputs exactly the same data) for both little- and big-endian binaries: $ readelf -wi dwarf_test Contents of the .debug_info section: <snip> <1><2d>: Abbrev Number: 2 (DW_TAG_structure_type) <2e> DW_AT_name : S <30> DW_AT_byte_size : 4 <31> DW_AT_decl_file : 1 <32> DW_AT_decl_line : 1 <33> DW_AT_decl_column : 8 <34> DW_AT_sibling : <0x71> <2><38>: Abbrev Number: 3 (DW_TAG_member) <39> DW_AT_name : j <3b> DW_AT_decl_file : 1 <3c> DW_AT_decl_line : 2 <3d> DW_AT_decl_column : 6 <3e> DW_AT_type : <0x71> <42> DW_AT_byte_size : 4 <43> DW_AT_bit_size : 5 <44> DW_AT_bit_offset : 27 <45> DW_AT_data_member_location: 0 <2><46>: Abbrev Number: 3 (DW_TAG_member) <47> DW_AT_name : k <49> DW_AT_decl_file : 1 <4a> DW_AT_decl_line : 3 <4b> DW_AT_decl_column : 6 <4c> DW_AT_type : <0x71> <50> DW_AT_byte_size : 4 <51> DW_AT_bit_size : 6 <52> DW_AT_bit_offset : 21 <53> DW_AT_data_member_location: 0 <2><54>: Abbrev Number: 3 (DW_TAG_member) <55> DW_AT_name : m <57> DW_AT_decl_file : 1 <58> DW_AT_decl_line : 4 <59> DW_AT_decl_column : 6 <5a> DW_AT_type : <0x71> <5e> DW_AT_byte_size : 4 <5f> DW_AT_bit_size : 5 <60> DW_AT_bit_offset : 16 <61> DW_AT_data_member_location: 0 <2><62>: Abbrev Number: 3 (DW_TAG_member) <63> DW_AT_name : n <65> DW_AT_decl_file : 1 <66> DW_AT_decl_line : 5 <67> DW_AT_decl_column : 6 <68> DW_AT_type : <0x71> <6c> DW_AT_byte_size : 4 <6d> DW_AT_bit_size : 8 <6e> DW_AT_bit_offset : 8 <6f> DW_AT_data_member_location: 0 <2><70>: Abbrev Number: 0 <1><71>: Abbrev Number: 4 (DW_TAG_base_type) <72> DW_AT_byte_size : 4 <73> DW_AT_encoding : 5 (signed) <74> DW_AT_name : int <snip> $ readelf -wi dwarf_test.be Contents of the .debug_info section: <snip> <1><2d>: Abbrev Number: 2 (DW_TAG_structure_type) <2e> DW_AT_name : S <30> DW_AT_byte_size : 4 <31> DW_AT_decl_file : 1 <32> DW_AT_decl_line : 1 <33> DW_AT_sibling : <0x6c> <2><37>: Abbrev Number: 3 (DW_TAG_member) <38> DW_AT_name : j <3a> DW_AT_decl_file : 1 <3b> DW_AT_decl_line : 2 <3c> DW_AT_type : <0x6c> <40> DW_AT_byte_size : 4 <41> DW_AT_bit_size : 5 <42> DW_AT_bit_offset : 0 <43> DW_AT_data_member_location: 0 <2><44>: Abbrev Number: 3 (DW_TAG_member) <45> DW_AT_name : k <47> DW_AT_decl_file : 1 <48> DW_AT_decl_line : 3 <49> DW_AT_type : <0x6c> <4d> DW_AT_byte_size : 4 <4e> DW_AT_bit_size : 6 <4f> DW_AT_bit_offset : 5 <50> DW_AT_data_member_location: 0 <2><51>: Abbrev Number: 3 (DW_TAG_member) <52> DW_AT_name : m <54> DW_AT_decl_file : 1 <55> DW_AT_decl_line : 4 <56> DW_AT_type : <0x6c> <5a> DW_AT_byte_size : 4 <5b> DW_AT_bit_size : 5 <5c> DW_AT_bit_offset : 11 <5d> DW_AT_data_member_location: 0 <2><5e>: Abbrev Number: 3 (DW_TAG_member) <5f> DW_AT_name : n <61> DW_AT_decl_file : 1 <62> DW_AT_decl_line : 5 <63> DW_AT_type : <0x6c> <67> DW_AT_byte_size : 4 <68> DW_AT_bit_size : 8 <69> DW_AT_bit_offset : 16 <6a> DW_AT_data_member_location: 0 <snip> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Mark Wielaard <mark@klomp.org> Cc: Martin KaFai Lau <kafai@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Andrii Nakryiko
|
5104d1bef3 |
loaders: Record CU's endianness in dwarf/btf/ctf loaders
This patch records for each CU whether it's in little-endian or big-endian data format. This flag will be used in subsequent commits to adjust bit offsets where necessary, to make them uniform across endianness. This patch doesn't have any effect on pahole's output. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Mark Wielaard <mark@klomp.org> Cc: Martin KaFai Lau <kafai@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Andrii Nakryiko
|
4abc595539 |
btf_loader: Adjust negative bitfield offsets early on
Bitfield offsets can be negative, if field "borrows" few bits from following aligned field. This causes a bunch of surprises down the line in pahole's logic (e.g., for hole calculation logic), so instead of waiting till printf routines adjust this for display, adjust them early and keep less surprising semantics. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Martin KaFai Lau <kafai@fb.com> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Andrii Nakryiko
|
55c96aaed8 |
loaders: Strip away volatile/const/restrict when fixing bitfields
btf_loader and ctf_loader didn't remove const/volatile/restrict, so bitfields using modifiers were not adjusted properly. This patch abstracts logic of stripping aways typedefs and access modifiers into tag__strip_typedefs_and_modifiers, which handles any interleaving of typedefs and modifiers. dwarf_loader was adapter to reuse this function as well, instead of custom goto loop. REPRO: $ cat vc_map.c typedef unsigned int u32; typedef volatile u32 vu32; typedef vu32 vu32_t; typedef struct vc_map { volatile unsigned int tx: 1; vu32_t rx: 1; void *x1, *x2; } vc_map; int main() { struct vc_map s; return 0; } BEFORE: $ ~/pahole/build/pahole -F btf vc_map struct vc_map { volatile unsigned int tx:1; /* 0: 0 4 */ vu32_t rx:1; /* 0: 0 4 */ /* XXX 30 bits hole, try to pack */ /* XXX 4 bytes hole, try to pack */ void * x1; /* 8 8 */ void * x2; /* 16 8 */ /* size: 24, cachelines: 1, members: 4 */ /* sum members: 20, holes: 1, sum holes: 4 */ /* bit holes: 1, sum bit holes: 30 bits */ /* last cacheline: 24 bytes */ }; AFTER: $ ~/pahole/build/pahole -F btf vc_map struct vc_map { volatile unsigned int tx:1; /* 0:31 4 */ vu32_t rx:1; /* 0:30 4 */ /* XXX 30 bits hole, try to pack */ /* XXX 4 bytes hole, try to pack */ void * x1; /* 8 8 */ void * x2; /* 16 8 */ /* size: 24, cachelines: 1, members: 4 */ /* sum members: 20, holes: 1, sum holes: 4 */ /* bit holes: 1, sum bit holes: 30 bits */ /* last cacheline: 24 bytes */ }; Signed-off-by: Andrii Nakryiko <andriin@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: bpf@vger.kernel.org Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
c9b2ef034f |
dwarf: Add cu__add_tag_with_id() to stop using id == -1 to allocate id
the CTF and BTF loaders come already with the id to use, while the DWARF loader comes with a Dwarf_Off that needs to be converted into the ptr_table index. So keep the cu__add_tag(cu, tag, &id) method to ask ask for the index to be allocated in the ptr_table and the result to come back via the 'id' parameter, now a uint32_t and introduce a cu__add_tag_with_id(cu, tag, id) method to indicate that the 'uint32_t id' is the one to use. With this we can use a uint32_t for the id both on 32-bit and 64-bit arches. Reported-by: Andrii Nakryiko <andriin@fb.com> Tested-by:Andrii Nakryiko <andrii.nakryiko@gmail.com> Link: https://lore.kernel.org/bpf/CAEf4Bzb0SpvXdDKMMnUof==kp4Y0AP54bKFjeCzX_AsmDm7k7g@mail.gmail.com/ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Andrii Nakryiko
|
3526ebebd3 |
pahole: Use 32-bit integers for type ID iterations within CU
Existing code base assumes that single CU doesn't have more than 65535 types per each CU, which might be a reasonable assumption for DWARF data. With BTF, though, all we get is single, potentially huge, CU which can easily have more than 65k types. For example, this is the case for allyesconfig version of Linux kernel, which has >200k types. Due to this assumption, libdwarves and other parts of pahole are using 16-bit counters to iterate over entities within CU. This can cause infinite loops when iterating BTF data, if there are more than 65535 types. This patch changes non-public variables to use 32-bit integers, where appropriate. This still leads to invalid reported data when using BTF loader (due to using (X & 0xFFFF) type ID, instead of X, when X > 65535) and loading huge files, but at least it's not stuck in an infinite loop anymore. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: bpf@vger.kernel.org Cc: dwarves@vger.kernel.org [ Removed non type ID conversions, for instance for the kind of tag, like in type->namespace.tag.tag, that can remain a uint16_t ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Andrii Nakryiko
|
8f4f280163 |
btf_loader: Simplify fixup code by relying on BTF data more
btf_loader relies on guessing base integral type size for enums and integers, which is unreliable. There doesn't seem to be a need for that, as all this information could be extracted from BTF information. Before: $ PAHOLE=~/local/pahole/build/pahole ./btfdiff ~/local/btf/libc-2.28.so.debug base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! base_type__name_to_size: base_type _Float128 class__fixup_btf_bitfields: unknown base type name "_Float128"! --- /tmp/btfdiff.dwarf.aV4wSL 2019-02-25 13:31:54.787923673 -0800 +++ /tmp/btfdiff.btf.22NQmJ 2019-02-25 13:31:54.802923668 -0800 @@ -461,9 +461,15 @@ struct La_x86_64_retval { uint64_t lrv_rdx; /* 8 8 */ La_x86_64_xmm lrv_xmm0; /* 16 16 */ La_x86_64_xmm lrv_xmm1; /* 32 16 */ - long double lrv_st0; /* 48 16 */ + long double lrv_st0; /* 48 8 */ + + /* XXX 8 bytes hole, try to pack */ + /* --- cacheline 1 boundary (64 bytes) --- */ - long double lrv_st1; /* 64 16 */ + long double lrv_st1; /* 64 8 */ + + /* XXX 8 bytes hole, try to pack */ + La_x86_64_vector lrv_vector0; /* 80 64 */ /* --- cacheline 2 boundary (128 bytes) was 16 bytes ago --- */ La_x86_64_vector lrv_vector1; /* 144 64 */ @@ -472,6 +478,7 @@ struct La_x86_64_retval { __int128 lrv_bnd1; /* 224 16 */ /* size: 240, cachelines: 4, members: 10 */ + /* sum members: 224, holes: 2, sum holes: 16 */ /* last cacheline: 48 bytes */ }; struct r_debug { @@ -2044,7 +2051,7 @@ union ieee754_float { } ieee_nan; /* 0 4 */ }; union ieee854_long_double { - long double d; /* 0 16 */ + long double d; /* 0 8 */ struct { unsigned int mantissa1:32; /* 0: 0 4 */ unsigned int mantissa0:32; /* 4: 0 4 */ @@ -2141,7 +2148,7 @@ struct ucontext_t { /* last cacheline: 8 bytes */ }; union ieee854_float128 { - _Float128 d; /* 0 16 */ + _Float128 d; /* 0 0 */ struct { unsigned int mantissa3:32; /* 0: 0 4 */ unsigned int mantissa2:32; /* 4: 0 4 */ @@ -2219,7 +2226,7 @@ union printf_arg { long unsigned int pa_u_long_int; /* 0 8 */ long long unsigned int pa_u_long_long_int; /* 0 8 */ double pa_double; /* 0 8 */ - long double pa_long_double; /* 0 16 */ + long double pa_long_double; /* 0 8 */ const char * pa_string; /* 0 8 */ const wchar_t * pa_wstring; /* 0 8 */ void * pa_pointer; /* 0 8 */ $ PAHOLE=~/local/pahole/build/pahole ./btfdiff ~/local/btf/libc-2.28.so.debug <empty output> Still good for kernel image: $ PAHOLE=~/local/pahole/build/pahole ./btfdiff ~/local/btf/vmlinux4 <empty output> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: bpf@vger.kernel.org Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Andrii Nakryiko
|
6586e423d4 |
btf_loader: Fix bitfield fixup code
Existing code assumes alignment of any integer type, which breaks for packed structs. This patch fixes all the current discrepanies between dwarf and btf loader, when compared using btfdiff. It preserves bit_offset of non-bitfield members, while for bitfield ones it re-calculates initial byte/bit offset using natural alignment of the underlying integer type, which seems to be always the case for bitfields. I've tested this on toy examples for both x86-64 and arm targets, there were no differences reported by btfdiff. Testing on vmlinux on x86-64 shows only these discrepancies, which are unrelated to bit offsets: $ ./btfdiff /tmp/vmlinux4 --- /tmp/btfdiff.dwarf.GIVfpr 2019-02-20 12:18:29.138788970 -0800 +++ /tmp/btfdiff.btf.c3x2KY 2019-02-20 12:18:29.351786365 -0800 @@ -16884,7 +16884,7 @@ struct pebs_record_nhm { }; union hsw_tsx_tuning { struct { - unsigned int cycles_last_block:32; /* 0: 0 4 */ + u32 cycles_last_block:32; /* 0: 0 4 */ u32 hle_abort:1; /* 4:31 4 */ u32 rtm_abort:1; /* 4:30 4 */ u32 instruction_abort:1; /* 4:29 4 */ @@ -26154,7 +26154,7 @@ struct acpi_device_power { /* last cacheline: 40 bytes */ }; struct acpi_device_perf_flags { - unsigned char reserved:8; /* 0: 0 1 */ + u8 reserved:8; /* 0: 0 1 */ /* size: 1, cachelines: 1, members: 1 */ /* last cacheline: 1 bytes */ Signed-off-by: Andrii Nakryiko <andriin@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: bpf@vger.kernel.org Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
fe4e1f799c |
btf_elf: Rename btf_elf__free() to btf_elf__delete()
That is the idiom for free its members and then free itself, 'free' is just to free its members. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
6780c4334d |
btf: Rename 'struct btf' to 'struct btf_elf'
So that we don't clash with libbpf's 'struct btf', in time more internal state now in 'struct btf_elf' will refer to the equivalent internal state in libbpf's 'struct btf', as they have lots in common. Requested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com> Acked-by: Andrii Nakryiko <andrii.nakryiko@gmail.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Martin Lau <kafai@fb.com> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Andrii Nakryiko
|
ca86e9416b |
pahole: use btf.h directly from libbpf
Now that libbpf is a submodule, we don't need to copy/paste btf.h header with BTF type definitions. This is a first step in migrating parts of libbtf, btf_encoder and btf_loader to use libbpf and starting to use btf__dedup(). Signed-off-by: Andrii Nakryiko <andriin@fb.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Martin KaFai Lau <kafai@fb.com> Cc: Yonghong Song <yhs@fb.com> Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
c86960dce5 |
btf_loader: We can set class_member->type_offset earlier
Because we don't have to lookup the member type that is encoded after it, i.e. some member fields depend on first processing everything, then lookup the types to get the sizes, etc. But the: member->byte_offset = member->bit_offset / 8; Can be done soon after we have member->bit_offset loaded from the BTF section. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
de3459cc0e |
btf_loader: BTF encodes the size of enums as bytes not bits
I wrote the BTF loader from the CTF loader, where the size of enumerations is expressed in bits, while BTF encodes it in bytes, fix it. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Yonghong Song
|
f2092f5658 |
btf: recognize BTF_KIND_FUNC in btf_loader
BTF_KIND_FUNC is generated by llvm (latest trunk, 8.0 or later). Without BTF_KIND_FUNC support, we will see the following errors, -bash-4.4$ cat t.c struct t { int a; char b1:1; char b2:3; int c; } g; int main() { return 0; } -bash-4.4$ clang -O2 -target bpf -g -c t.c -Xclang -target-feature -Xclang +dwarfris -bash-4.4$ pahole -F btf t.o BTF: idx: 3, off: 28, Unknown struct t { int a; /* 0 4 */ /* Bitfield combined with previous fields */ <ERROR(__class__fprintf:1342): 5 not found!> /* Bitfield combined with previous fields */ <ERROR(__class__fprintf:1342): 5 not found!> int c; /* 8 4 */ /* size: 12, cachelines: 1, members: 4 */ /* last cacheline: 12 bytes */ /* BRAIN FART ALERT! 12 != 8 + 0(holes), diff = 4 */ }; -bash-4.4$ The reason is that llvm generates BTF_KIND_FUNC which btf_loader does not recognize. This patch added support for BTF_KIND_FUNC. Since BTF_KIND_FUNC represents a defined subprogram and not a real type. A null type is used to represent BTF_KIND_FUNC to avoid skipping type index. With this fix: -bash-4.4$ pahole -F btf t.o struct t { int a; /* 0 4 */ char b1:1; /* 4: 0 1 */ char b2:3; /* 4: 1 1 */ int c; /* 8 4 */ /* size: 12, cachelines: 1, members: 4 */ /* last cacheline: 12 bytes */ /* BRAIN FART ALERT! 12 != 9 + 0(holes), diff = 3 */ }; Signed-off-by: Yonghong Song <yhs@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Martin KaFai Lau <kafai@fb.com> Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Yonghong Song
|
1176661409 |
btf: Fix kind_flag usage in btf_loader
Commit |
||
Arnaldo Carvalho de Melo
|
ab0cb33e54 |
btf_loader: Fixup class_member->bit_offset for !big_endian files
Yonghong explains: <quote> The bitfield offset in BTF starts from lower number to bigger one. That is, it is always following the big endian convention, bitfield_offset will be smaller if close to the top of structure. This is different from what dwarf is doing, which will show different things on little endian vs. big endian. You can make simple adjustment based on all available info. In btf_encoder.s, we did similar adjustment for little endian from dwarf to btf. </> So fix it up while loading, so that the rebuilt C output shows the same thing from BTF and from DWARF. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Yonghong Song
|
2a82d593be |
btf: Add kind_flag support for btf_loader
For struct/union members, the struct/union type info kind_flag is needed to calculate correct bitfield_size and bit_offset. if (kind_flag) { bitfield_size = BTF_MEMBER_BITFIELD_SIZE(member->offset); bit_offset = BTF_MEMBER_BIT_OFFSET(member->offset); } else { bitfield_size = 0; bit_offset = member->offset; } Note that bitfield_size and bit_offset will not depend on the member type. The member type will help calculate correct bitfield_offset, byte_size, byte_offset, bit_size. For example, with the fix, we will be able to display bit offset and bitfield size properly. -bash-4.4$ cat t.c struct t { int a:2; int b:3; int c:2; } g; -bash-4.4$ gcc -c -O2 -g t.c -bash-4.4$ pahole -JV t.o File t.o: [1] STRUCT t kind_flag=1 size=4 vlen=3 a type_id=2 bitfield_size=2 bits_offset=0 b type_id=2 bitfield_size=3 bits_offset=2 c type_id=2 bitfield_size=2 bits_offset=5 [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED -bash-4.4$ pahole -F btf t.o struct t { int a:2; /* 0: 0 4 */ int b:3; /* 0: 2 4 */ int c:2; /* 0: 5 4 */ /* size: 4, cachelines: 1, members: 3 */ /* bit_padding: 25 bits */ /* last cacheline: 4 bytes */ }; Note that the above offset showing is different from the below dwarf as BTF bitfield_offset is always the offset from the start of structure, kindly like big endian encoding. This may need adjustment to be conforming to the dwarf dump format. -bash-4.4$ pahole -F dwarf t.o struct t { int a:2; /* 0:30 4 */ int b:3; /* 0:27 4 */ int c:2; /* 0:25 4 */ /* size: 4, cachelines: 1, members: 3 */ /* bit_padding: 25 bits */ /* last cacheline: 4 bytes */ }; Signed-off-by: Yonghong Song <yhs@fb.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Martin KaFai Lau <kafai@fb.com> Cc: dwarves@vger.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |
||
Arnaldo Carvalho de Melo
|
472256d3c5 |
btf_loader: Introduce a loader for the BTF format
Show 'struct list_head' from DWARF info: $ pahole -C list_head ~/git/build/v4.20-rc5+/net/ipv4/tcp.o struct list_head { struct list_head * next; /* 0 8 */ struct list_head * prev; /* 8 8 */ /* size: 16, cachelines: 1, members: 2 */ /* last cacheline: 16 bytes */ }; Try to show it from BTF, on a file without it: $ pahole -F btf -C list_head ~/git/build/v4.20-rc5+/net/ipv4/tcp.o pahole: /home/acme/git/build/v4.20-rc5+/net/ipv4/tcp.o: No debugging information found Encode BTF from the DWARF info: $ pahole -J ~/git/build/v4.20-rc5+/net/ipv4/tcp.o Check that it is there: $ readelf -SW ~/git/build/v4.20-rc5+/net/ipv4/tcp.o | grep BTF readelf: /home/acme/git/build/v4.20-rc5+/net/ipv4/tcp.o: Warning: possibly corrupt ELF header - it has a non-zero program header offset, but no program headers [136] .BTF PROGBITS 0000000000000000 101d0e 042edf 00 0 0 1 Now try again printing 'struct list_head' from the BTF info just encoded: $ pahole -F btf -C list_head ~/git/build/v4.20-rc5+/net/ipv4/tcp.o 2> /dev/null struct list_head { struct list_head * next; /* 0 8 */ struct list_head * prev; /* 8 8 */ /* size: 16, cachelines: 1, members: 2 */ /* last cacheline: 16 bytes */ }; $ There is the bitfields case that BTF desn't have the bit_size info for bitfield members that makes the output from dwarf to be different than the one from BTF: $ pahole -F btf -C sk_buff ~/git/build/v4.20-rc5+/net/ipv4/tcp.o > /tmp/sk_buff.btf $ pahole -F dwarf -C sk_buff ~/git/build/v4.20-rc5+/net/ipv4/tcp.o > /tmp/sk_buff.dwarf $ diff -u /tmp/sk_buff.dwarf /tmp/sk_buff.btf --- /tmp/sk_buff.dwarf 2018-12-20 14:50:51.428653046 -0300 +++ /tmp/sk_buff.btf 2018-12-20 14:50:46.302601516 -0300 @@ -38,45 +38,45 @@ __u16 hdr_len; /* 138 2 */ __u16 queue_mapping; /* 140 2 */ __u8 __cloned_offset[0]; /* 142 0 */ - __u8 cloned:1; /* 142: 7 1 */ - __u8 nohdr:1; /* 142: 6 1 */ - __u8 fclone:2; /* 142: 4 1 */ - __u8 peeked:1; /* 142: 3 1 */ - __u8 head_frag:1; /* 142: 2 1 */ - __u8 xmit_more:1; /* 142: 1 1 */ - __u8 pfmemalloc:1; /* 142: 0 1 */ + __u8 cloned; /* 142 1 */ + __u8 nohdr; /* 142 1 */ + __u8 fclone; /* 142 1 */ + __u8 peeked; /* 142 1 */ + __u8 head_frag; /* 142 1 */ + __u8 xmit_more; /* 142 1 */ + __u8 pfmemalloc; /* 142 1 */ /* XXX 1 byte hole, try to pack */ __u32 headers_start[0]; /* 144 0 */ __u8 __pkt_type_offset[0]; /* 144 0 */ - __u8 pkt_type:3; /* 144: 5 1 */ - __u8 ignore_df:1; /* 144: 4 1 */ - __u8 nf_trace:1; /* 144: 3 1 */ - __u8 ip_summed:2; /* 144: 1 1 */ - __u8 ooo_okay:1; /* 144: 0 1 */ - __u8 l4_hash:1; /* 145: 7 1 */ - __u8 sw_hash:1; /* 145: 6 1 */ - __u8 wifi_acked_valid:1; /* 145: 5 1 */ - __u8 wifi_acked:1; /* 145: 4 1 */ - __u8 no_fcs:1; /* 145: 3 1 */ - __u8 encapsulation:1; /* 145: 2 1 */ - __u8 encap_hdr_csum:1; /* 145: 1 1 */ - __u8 csum_valid:1; /* 145: 0 1 */ - __u8 csum_complete_sw:1; /* 146: 7 1 */ - __u8 csum_level:2; /* 146: 5 1 */ - __u8 csum_not_inet:1; /* 146: 4 1 */ - __u8 dst_pending_confirm:1; /* 146: 3 1 */ - __u8 ndisc_nodetype:2; /* 146: 1 1 */ - __u8 ipvs_property:1; /* 146: 0 1 */ - __u8 inner_protocol_type:1; /* 147: 7 1 */ - __u8 remcsum_offload:1; /* 147: 6 1 */ - __u8 offload_fwd_mark:1; /* 147: 5 1 */ - __u8 offload_mr_fwd_mark:1; /* 147: 4 1 */ - __u8 tc_skip_classify:1; /* 147: 3 1 */ - __u8 tc_at_ingress:1; /* 147: 2 1 */ - __u8 tc_redirected:1; /* 147: 1 1 */ - __u8 tc_from_ingress:1; /* 147: 0 1 */ + __u8 pkt_type; /* 144 1 */ + __u8 ignore_df; /* 144 1 */ + __u8 nf_trace; /* 144 1 */ + __u8 ip_summed; /* 144 1 */ + __u8 ooo_okay; /* 144 1 */ + __u8 l4_hash; /* 145 1 */ + __u8 sw_hash; /* 145 1 */ + __u8 wifi_acked_valid; /* 145 1 */ + __u8 wifi_acked; /* 145 1 */ + __u8 no_fcs; /* 145 1 */ + __u8 encapsulation; /* 145 1 */ + __u8 encap_hdr_csum; /* 145 1 */ + __u8 csum_valid; /* 145 1 */ + __u8 csum_complete_sw; /* 146 1 */ + __u8 csum_level; /* 146 1 */ + __u8 csum_not_inet; /* 146 1 */ + __u8 dst_pending_confirm; /* 146 1 */ + __u8 ndisc_nodetype; /* 146 1 */ + __u8 ipvs_property; /* 146 1 */ + __u8 inner_protocol_type; /* 147 1 */ + __u8 remcsum_offload; /* 147 1 */ + __u8 offload_fwd_mark; /* 147 1 */ + __u8 offload_mr_fwd_mark; /* 147 1 */ + __u8 tc_skip_classify; /* 147 1 */ + __u8 tc_at_ingress; /* 147 1 */ + __u8 tc_redirected; /* 147 1 */ + __u8 tc_from_ingress; /* 147 1 */ __u16 tc_index; /* 148 2 */ /* XXX 2 bytes hole, try to pack */ $ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> |