aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/btf.c
diff options
context:
space:
mode:
authorAndrii Nakryiko <andriin@fb.com>2019-02-04 20:29:44 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2019-02-05 10:52:57 -0500
commit69eaab04c675ef2d0127a80b3395aa90dfd1061f (patch)
treea75c3cb25d1bf2134b766f4faf95fb337b7a01c3 /tools/lib/bpf/btf.c
parenta8a1f7d09cfc7e18874786c7634c9e71384fcd4e (diff)
btf: extract BTF type size calculation
This pre-patch extracts calculation of amount of space taken by BTF type descriptor for later reuse by btf_dedup functionality. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools/lib/bpf/btf.c')
-rw-r--r--tools/lib/bpf/btf.c98
1 files changed, 46 insertions, 52 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 7ec0463354db..06bd1a625ff4 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -182,6 +182,37 @@ static int btf_parse_str_sec(struct btf *btf)
182 return 0; 182 return 0;
183} 183}
184 184
185static int btf_type_size(struct btf_type *t)
186{
187 int base_size = sizeof(struct btf_type);
188 __u16 vlen = BTF_INFO_VLEN(t->info);
189
190 switch (BTF_INFO_KIND(t->info)) {
191 case BTF_KIND_FWD:
192 case BTF_KIND_CONST:
193 case BTF_KIND_VOLATILE:
194 case BTF_KIND_RESTRICT:
195 case BTF_KIND_PTR:
196 case BTF_KIND_TYPEDEF:
197 case BTF_KIND_FUNC:
198 return base_size;
199 case BTF_KIND_INT:
200 return base_size + sizeof(__u32);
201 case BTF_KIND_ENUM:
202 return base_size + vlen * sizeof(struct btf_enum);
203 case BTF_KIND_ARRAY:
204 return base_size + sizeof(struct btf_array);
205 case BTF_KIND_STRUCT:
206 case BTF_KIND_UNION:
207 return base_size + vlen * sizeof(struct btf_member);
208 case BTF_KIND_FUNC_PROTO:
209 return base_size + vlen * sizeof(struct btf_param);
210 default:
211 pr_debug("Unsupported BTF_KIND:%u\n", BTF_INFO_KIND(t->info));
212 return -EINVAL;
213 }
214}
215
185static int btf_parse_type_sec(struct btf *btf) 216static int btf_parse_type_sec(struct btf *btf)
186{ 217{
187 struct btf_header *hdr = btf->hdr; 218 struct btf_header *hdr = btf->hdr;
@@ -191,41 +222,13 @@ static int btf_parse_type_sec(struct btf *btf)
191 222
192 while (next_type < end_type) { 223 while (next_type < end_type) {
193 struct btf_type *t = next_type; 224 struct btf_type *t = next_type;
194 __u16 vlen = BTF_INFO_VLEN(t->info); 225 int type_size;
195 int err; 226 int err;
196 227
197 next_type += sizeof(*t); 228 type_size = btf_type_size(t);
198 switch (BTF_INFO_KIND(t->info)) { 229 if (type_size < 0)
199 case BTF_KIND_INT: 230 return type_size;
200 next_type += sizeof(int); 231 next_type += type_size;
201 break;
202 case BTF_KIND_ARRAY:
203 next_type += sizeof(struct btf_array);
204 break;
205 case BTF_KIND_STRUCT:
206 case BTF_KIND_UNION:
207 next_type += vlen * sizeof(struct btf_member);
208 break;
209 case BTF_KIND_ENUM:
210 next_type += vlen * sizeof(struct btf_enum);
211 break;
212 case BTF_KIND_FUNC_PROTO:
213 next_type += vlen * sizeof(struct btf_param);
214 break;
215 case BTF_KIND_FUNC:
216 case BTF_KIND_TYPEDEF:
217 case BTF_KIND_PTR:
218 case BTF_KIND_FWD:
219 case BTF_KIND_VOLATILE:
220 case BTF_KIND_CONST:
221 case BTF_KIND_RESTRICT:
222 break;
223 default:
224 pr_debug("Unsupported BTF_KIND:%u\n",
225 BTF_INFO_KIND(t->info));
226 return -EINVAL;
227 }
228
229 err = btf_add_type(btf, t); 232 err = btf_add_type(btf, t);
230 if (err) 233 if (err)
231 return err; 234 return err;
@@ -252,21 +255,6 @@ static bool btf_type_is_void_or_null(const struct btf_type *t)
252 return !t || btf_type_is_void(t); 255 return !t || btf_type_is_void(t);
253} 256}
254 257
255static __s64 btf_type_size(const struct btf_type *t)
256{
257 switch (BTF_INFO_KIND(t->info)) {
258 case BTF_KIND_INT:
259 case BTF_KIND_STRUCT:
260 case BTF_KIND_UNION:
261 case BTF_KIND_ENUM:
262 return t->size;
263 case BTF_KIND_PTR:
264 return sizeof(void *);
265 default:
266 return -EINVAL;
267 }
268}
269
270#define MAX_RESOLVE_DEPTH 32 258#define MAX_RESOLVE_DEPTH 32
271 259
272__s64 btf__resolve_size(const struct btf *btf, __u32 type_id) 260__s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
@@ -280,11 +268,16 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
280 t = btf__type_by_id(btf, type_id); 268 t = btf__type_by_id(btf, type_id);
281 for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); 269 for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
282 i++) { 270 i++) {
283 size = btf_type_size(t);
284 if (size >= 0)
285 break;
286
287 switch (BTF_INFO_KIND(t->info)) { 271 switch (BTF_INFO_KIND(t->info)) {
272 case BTF_KIND_INT:
273 case BTF_KIND_STRUCT:
274 case BTF_KIND_UNION:
275 case BTF_KIND_ENUM:
276 size = t->size;
277 goto done;
278 case BTF_KIND_PTR:
279 size = sizeof(void *);
280 goto done;
288 case BTF_KIND_TYPEDEF: 281 case BTF_KIND_TYPEDEF:
289 case BTF_KIND_VOLATILE: 282 case BTF_KIND_VOLATILE:
290 case BTF_KIND_CONST: 283 case BTF_KIND_CONST:
@@ -308,6 +301,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
308 if (size < 0) 301 if (size < 0)
309 return -EINVAL; 302 return -EINVAL;
310 303
304done:
311 if (nelems && size > UINT32_MAX / nelems) 305 if (nelems && size > UINT32_MAX / nelems)
312 return -E2BIG; 306 return -E2BIG;
313 307