2019-01-15 18:28:24 +01:00
|
|
|
/*
|
|
|
|
SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
|
2019-01-18 19:42:37 +01:00
|
|
|
Copyright (C) 2019 Facebook
|
2019-01-15 18:28:24 +01:00
|
|
|
*/
|
|
|
|
|
2018-03-06 01:53:50 +01:00
|
|
|
#ifndef _LIBBTF_H
|
|
|
|
#define _LIBBTF_H
|
|
|
|
|
|
|
|
#include "gobuffer.h"
|
|
|
|
|
2018-09-13 18:19:40 +02:00
|
|
|
#include <stdbool.h>
|
2018-03-06 01:53:50 +01:00
|
|
|
#include <stdint.h>
|
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
struct btf_elf {
|
2018-03-06 01:53:50 +01:00
|
|
|
union {
|
|
|
|
struct btf_header *hdr;
|
|
|
|
void *data;
|
|
|
|
};
|
|
|
|
void *priv;
|
|
|
|
Elf *elf;
|
|
|
|
GElf_Ehdr ehdr;
|
|
|
|
struct gobuffer types;
|
|
|
|
struct gobuffer *strings;
|
|
|
|
char *filename;
|
|
|
|
size_t size;
|
|
|
|
int swapped;
|
|
|
|
int in_fd;
|
|
|
|
uint8_t wordsize;
|
2018-09-13 18:19:40 +02:00
|
|
|
bool is_big_endian;
|
2018-03-06 01:53:50 +01:00
|
|
|
uint32_t type_index;
|
|
|
|
};
|
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
extern uint8_t btf_elf__verbose;
|
|
|
|
#define btf_elf__verbose_log(fmt, ...) { if (btf_elf__verbose) printf(fmt, __VA_ARGS__); }
|
2018-03-06 01:53:50 +01:00
|
|
|
|
|
|
|
struct base_type;
|
btf: add func_proto support
Two new btf kinds, BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO,
have been added in kernel since
https://patchwork.ozlabs.org/cover/1000176/
to support better func introspection.
Currently, for a DW_TAG_subroutine_type dwarf type,
a simple "void *" is generated instead of real subroutine type.
This patch teaches pahole to generate BTF_KIND_FUNC_PROTO
properly. After this patch, pahole should have complete
type coverage for C frontend with types a bpf program cares.
For example,
$ cat t1.c
typedef int __int32;
struct t1 {
int a1;
int (*f1)(char p1, __int32 p2);
} g1;
$ cat t2.c
typedef int __int32;
struct t2 {
int a2;
int (*f2)(char q1, __int32 q2, ...);
int (*f3)();
} g2;
int main() { return 0; }
$ gcc -O2 -o t1 -g t1.c t2.c
$ pahole -JV t1
File t1:
[1] TYPEDEF __int32 type_id=2
[2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
[3] STRUCT t1 kind_flag=0 size=16 vlen=2
a1 type_id=2 bits_offset=0
f1 type_id=6 bits_offset=64
[4] FUNC_PROTO (anon) return=2 args=(5 (anon), 1 (anon))
[5] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
[6] PTR (anon) type_id=4
[7] TYPEDEF __int32 type_id=8
[8] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
[9] STRUCT t2 kind_flag=0 size=24 vlen=3
a2 type_id=8 bits_offset=0
f2 type_id=12 bits_offset=64
f3 type_id=14 bits_offset=128
[10] FUNC_PROTO (anon) return=8 args=(11 (anon), 7 (anon), vararg)
[11] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
[12] PTR (anon) type_id=10
[13] FUNC_PROTO (anon) return=8 args=(vararg)
[14] PTR (anon) type_id=13
$
In the above example, type [4], [10] and [13] represent the
func_proto types.
BTF_KIND_FUNC, which represents a real subprogram, is not generated in
this patch and will be considered later.
Signed-off-by: Yonghong Song <yhs@fb.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-12-18 23:09:42 +01:00
|
|
|
struct ftype;
|
2018-03-06 01:53:50 +01:00
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
struct btf_elf *btf_elf__new(const char *filename, Elf *elf);
|
|
|
|
void btf_elf__free(struct btf_elf *btf);
|
2018-03-06 01:53:50 +01:00
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
int32_t btf_elf__add_base_type(struct btf_elf *btf, const struct base_type *bt);
|
|
|
|
int32_t btf_elf__add_ref_type(struct btf_elf *btf, uint16_t kind, uint32_t type,
|
|
|
|
uint32_t name, bool kind_flag);
|
|
|
|
int btf_elf__add_member(struct btf_elf *btf, uint32_t name, uint32_t type, bool kind_flag,
|
|
|
|
uint32_t bitfield_size, uint32_t bit_offset);
|
|
|
|
int32_t btf_elf__add_struct(struct btf_elf *btf, uint8_t kind, uint32_t name,
|
|
|
|
bool kind_flag, uint32_t size, uint16_t nr_members);
|
|
|
|
int32_t btf_elf__add_array(struct btf_elf *btf, uint32_t type, uint32_t index_type,
|
|
|
|
uint32_t nelems);
|
|
|
|
int32_t btf_elf__add_enum(struct btf_elf *btf, uint32_t name, uint32_t size,
|
|
|
|
uint16_t nr_entries);
|
|
|
|
int btf_elf__add_enum_val(struct btf_elf *btf, uint32_t name, int32_t value);
|
|
|
|
int32_t btf_elf__add_func_proto(struct btf_elf *btf, struct ftype *ftype,
|
|
|
|
uint32_t type_id_off);
|
|
|
|
void btf_elf__set_strings(struct btf_elf *btf, struct gobuffer *strings);
|
|
|
|
int btf_elf__encode(struct btf_elf *btf, uint8_t flags);
|
2018-03-06 01:53:50 +01:00
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
char *btf_elf__string(struct btf_elf *btf, uint32_t ref);
|
|
|
|
int btf_elf__load(struct btf_elf *btf);
|
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>
2018-12-03 19:44:16 +01:00
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
uint32_t btf_elf__get32(struct btf_elf *btf, uint32_t *p);
|
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>
2018-12-03 19:44:16 +01:00
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
void *btf_elf__get_buffer(struct btf_elf *btf);
|
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>
2018-12-03 19:44:16 +01:00
|
|
|
|
2019-02-14 14:47:32 +01:00
|
|
|
size_t btf_elf__get_size(struct btf_elf *btf);
|
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>
2018-12-03 19:44:16 +01:00
|
|
|
|
2018-03-06 01:53:50 +01:00
|
|
|
#endif /* _LIBBTF_H */
|