2727static struct btf_type btf_void ;
2828
2929struct btf {
30- union {
31- struct btf_header * hdr ;
32- void * data ;
33- };
30+ void * raw_data ;
31+ __u32 raw_size ;
32+
33+ /*
34+ * When BTF is loaded from ELF or raw memory it is stored
35+ * in contiguous memory block, pointed to by raw_data pointer, and
36+ * hdr, types_data, and strs_data point inside that memory region to
37+ * respective parts of BTF representation:
38+ *
39+ * +--------------------------------+
40+ * | Header | Types | Strings |
41+ * +--------------------------------+
42+ * ^ ^ ^
43+ * | | |
44+ * hdr | |
45+ * types_data-+ |
46+ * strs_data------------+
47+ */
48+ struct btf_header * hdr ;
49+ void * types_data ;
50+ void * strs_data ;
51+
52+ /* type ID to `struct btf_type *` lookup index */
3453 __u32 * type_offs ;
3554 __u32 type_offs_cap ;
36- const char * strings ;
37- void * nohdr_data ;
38- void * types_data ;
3955 __u32 nr_types ;
40- __u32 data_size ;
56+
57+ /* BTF object FD, if loaded into kernel */
4158 int fd ;
59+
60+ /* Pointer size (in bytes) for a target architecture of this BTF */
4261 int ptr_sz ;
4362};
4463
@@ -80,7 +99,7 @@ static int btf_parse_hdr(struct btf *btf)
8099 const struct btf_header * hdr = btf -> hdr ;
81100 __u32 meta_left ;
82101
83- if (btf -> data_size < sizeof (struct btf_header )) {
102+ if (btf -> raw_size < sizeof (struct btf_header )) {
84103 pr_debug ("BTF header not found\n" );
85104 return - EINVAL ;
86105 }
@@ -100,7 +119,7 @@ static int btf_parse_hdr(struct btf *btf)
100119 return - ENOTSUP ;
101120 }
102121
103- meta_left = btf -> data_size - sizeof (* hdr );
122+ meta_left = btf -> raw_size - sizeof (* hdr );
104123 if (!meta_left ) {
105124 pr_debug ("BTF has no data\n" );
106125 return - EINVAL ;
@@ -126,15 +145,13 @@ static int btf_parse_hdr(struct btf *btf)
126145 return - EINVAL ;
127146 }
128147
129- btf -> nohdr_data = btf -> hdr + 1 ;
130-
131148 return 0 ;
132149}
133150
134151static int btf_parse_str_sec (struct btf * btf )
135152{
136153 const struct btf_header * hdr = btf -> hdr ;
137- const char * start = btf -> nohdr_data + hdr -> str_off ;
154+ const char * start = btf -> strs_data ;
138155 const char * end = start + btf -> hdr -> str_len ;
139156
140157 if (!hdr -> str_len || hdr -> str_len - 1 > BTF_MAX_STR_OFFSET ||
@@ -143,8 +160,6 @@ static int btf_parse_str_sec(struct btf *btf)
143160 return - EINVAL ;
144161 }
145162
146- btf -> strings = start ;
147-
148163 return 0 ;
149164}
150165
@@ -186,11 +201,9 @@ static int btf_type_size(const struct btf_type *t)
186201static int btf_parse_type_sec (struct btf * btf )
187202{
188203 struct btf_header * hdr = btf -> hdr ;
189- void * next_type = btf -> nohdr_data + hdr -> type_off ;
204+ void * next_type = btf -> types_data ;
190205 void * end_type = next_type + hdr -> type_len ;
191206
192- btf -> types_data = next_type ;
193-
194207 while (next_type < end_type ) {
195208 int type_size ;
196209 int err ;
@@ -466,7 +479,7 @@ void btf__free(struct btf *btf)
466479 if (btf -> fd >= 0 )
467480 close (btf -> fd );
468481
469- free (btf -> data );
482+ free (btf -> raw_data );
470483 free (btf -> type_offs );
471484 free (btf );
472485}
@@ -482,24 +495,24 @@ struct btf *btf__new(const void *data, __u32 size)
482495
483496 btf -> fd = -1 ;
484497
485- btf -> data = malloc (size );
486- if (!btf -> data ) {
498+ btf -> raw_data = malloc (size );
499+ if (!btf -> raw_data ) {
487500 err = - ENOMEM ;
488501 goto done ;
489502 }
503+ memcpy (btf -> raw_data , data , size );
504+ btf -> raw_size = size ;
490505
491- memcpy (btf -> data , data , size );
492- btf -> data_size = size ;
493-
506+ btf -> hdr = btf -> raw_data ;
494507 err = btf_parse_hdr (btf );
495508 if (err )
496509 goto done ;
497510
498- err = btf_parse_str_sec (btf );
499- if (err )
500- goto done ;
511+ btf -> strs_data = btf -> raw_data + btf -> hdr -> hdr_len + btf -> hdr -> str_off ;
512+ btf -> types_data = btf -> raw_data + btf -> hdr -> hdr_len + btf -> hdr -> type_off ;
501513
502- err = btf_parse_type_sec (btf );
514+ err = btf_parse_str_sec (btf );
515+ err = err ?: btf_parse_type_sec (btf );
503516
504517done :
505518 if (err ) {
@@ -820,8 +833,9 @@ int btf__finalize_data(struct bpf_object *obj, struct btf *btf)
820833
821834int btf__load (struct btf * btf )
822835{
823- __u32 log_buf_size = 0 ;
836+ __u32 log_buf_size = 0 , raw_size ;
824837 char * log_buf = NULL ;
838+ const void * raw_data ;
825839 int err = 0 ;
826840
827841 if (btf -> fd >= 0 )
@@ -836,8 +850,13 @@ int btf__load(struct btf *btf)
836850 * log_buf = 0 ;
837851 }
838852
839- btf -> fd = bpf_load_btf (btf -> data , btf -> data_size ,
840- log_buf , log_buf_size , false);
853+ raw_data = btf__get_raw_data (btf , & raw_size );
854+ if (!raw_data ) {
855+ err = - ENOMEM ;
856+ goto done ;
857+ }
858+
859+ btf -> fd = bpf_load_btf (raw_data , raw_size , log_buf , log_buf_size , false);
841860 if (btf -> fd < 0 ) {
842861 if (!log_buf || errno == ENOSPC ) {
843862 log_buf_size = max ((__u32 )BPF_LOG_BUF_SIZE ,
@@ -870,14 +889,14 @@ void btf__set_fd(struct btf *btf, int fd)
870889
871890const void * btf__get_raw_data (const struct btf * btf , __u32 * size )
872891{
873- * size = btf -> data_size ;
874- return btf -> data ;
892+ * size = btf -> raw_size ;
893+ return btf -> raw_data ;
875894}
876895
877896const char * btf__name_by_offset (const struct btf * btf , __u32 offset )
878897{
879898 if (offset < btf -> hdr -> str_len )
880- return & btf -> strings [ offset ] ;
899+ return btf -> strs_data + offset ;
881900 else
882901 return NULL ;
883902}
@@ -1860,8 +1879,7 @@ static int btf_str_remap_offset(__u32 *str_off_ptr, void *ctx)
18601879 */
18611880static int btf_dedup_strings (struct btf_dedup * d )
18621881{
1863- const struct btf_header * hdr = d -> btf -> hdr ;
1864- char * start = (char * )d -> btf -> nohdr_data + hdr -> str_off ;
1882+ char * start = d -> btf -> strs_data ;
18651883 char * end = start + d -> btf -> hdr -> str_len ;
18661884 char * p = start , * tmp_strs = NULL ;
18671885 struct btf_str_ptrs strs = {
@@ -2970,12 +2988,11 @@ static int btf_dedup_compact_types(struct btf_dedup *d)
29702988 d -> btf -> type_offs = new_offs ;
29712989
29722990 /* make sure string section follows type information without gaps */
2973- d -> btf -> hdr -> str_off = p - d -> btf -> nohdr_data ;
2974- memmove (p , d -> btf -> strings , d -> btf -> hdr -> str_len );
2975- d -> btf -> strings = p ;
2976- p += d -> btf -> hdr -> str_len ;
2991+ d -> btf -> hdr -> str_off = p - d -> btf -> types_data ;
2992+ memmove (p , d -> btf -> strs_data , d -> btf -> hdr -> str_len );
2993+ d -> btf -> strs_data = p ;
29772994
2978- d -> btf -> data_size = p - d -> btf -> data ;
2995+ d -> btf -> raw_size = d -> btf -> hdr -> hdr_len + d -> btf -> hdr -> type_len + d -> btf -> hdr -> str_len ;
29792996 return 0 ;
29802997}
29812998
0 commit comments