diff options
author | Andrii Nakryiko <andriin@fb.com> | 2019-02-04 20:29:44 -0500 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-02-05 10:52:57 -0500 |
commit | 69eaab04c675ef2d0127a80b3395aa90dfd1061f (patch) | |
tree | a75c3cb25d1bf2134b766f4faf95fb337b7a01c3 /tools/lib/bpf/btf.c | |
parent | a8a1f7d09cfc7e18874786c7634c9e71384fcd4e (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.c | 98 |
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 | ||
185 | static 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 | |||
185 | static int btf_parse_type_sec(struct btf *btf) | 216 | static 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 | ||
255 | static __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 | ||
304 | done: | ||
311 | if (nelems && size > UINT32_MAX / nelems) | 305 | if (nelems && size > UINT32_MAX / nelems) |
312 | return -E2BIG; | 306 | return -E2BIG; |
313 | 307 | ||