1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Copyright (c) 2018 Facebook */ 3 4 #include <stdlib.h> 5 #include <string.h> 6 #include <unistd.h> 7 #include <errno.h> 8 #include <linux/err.h> 9 #include <linux/btf.h> 10 #include "btf.h" 11 #include "bpf.h" 12 13 #define elog(fmt, ...) { if (err_log) err_log(fmt, ##__VA_ARGS__); } 14 #define max(a, b) ((a) > (b) ? (a) : (b)) 15 #define min(a, b) ((a) < (b) ? (a) : (b)) 16 17 #define BTF_MAX_NR_TYPES 65535 18 19 static struct btf_type btf_void; 20 21 struct btf { 22 union { 23 struct btf_header *hdr; 24 void *data; 25 }; 26 struct btf_type **types; 27 const char *strings; 28 void *nohdr_data; 29 __u32 nr_types; 30 __u32 types_size; 31 __u32 data_size; 32 int fd; 33 }; 34 35 static const char *btf_name_by_offset(const struct btf *btf, __u32 offset) 36 { 37 if (offset < btf->hdr->str_len) 38 return &btf->strings[offset]; 39 else 40 return NULL; 41 } 42 43 static int btf_add_type(struct btf *btf, struct btf_type *t) 44 { 45 if (btf->types_size - btf->nr_types < 2) { 46 struct btf_type **new_types; 47 __u32 expand_by, new_size; 48 49 if (btf->types_size == BTF_MAX_NR_TYPES) 50 return -E2BIG; 51 52 expand_by = max(btf->types_size >> 2, 16); 53 new_size = min(BTF_MAX_NR_TYPES, btf->types_size + expand_by); 54 55 new_types = realloc(btf->types, sizeof(*new_types) * new_size); 56 if (!new_types) 57 return -ENOMEM; 58 59 if (btf->nr_types == 0) 60 new_types[0] = &btf_void; 61 62 btf->types = new_types; 63 btf->types_size = new_size; 64 } 65 66 btf->types[++(btf->nr_types)] = t; 67 68 return 0; 69 } 70 71 static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log) 72 { 73 const struct btf_header *hdr = btf->hdr; 74 __u32 meta_left; 75 76 if (btf->data_size < sizeof(struct btf_header)) { 77 elog("BTF header not found\n"); 78 return -EINVAL; 79 } 80 81 if (hdr->magic != BTF_MAGIC) { 82 elog("Invalid BTF magic:%x\n", hdr->magic); 83 return -EINVAL; 84 } 85 86 if (hdr->version != BTF_VERSION) { 87 elog("Unsupported BTF version:%u\n", hdr->version); 88 return -ENOTSUP; 89 } 90 91 if (hdr->flags) { 92 elog("Unsupported BTF flags:%x\n", hdr->flags); 93 return -ENOTSUP; 94 } 95 96 meta_left = btf->data_size - sizeof(*hdr); 97 if (!meta_left) { 98 elog("BTF has no data\n"); 99 return -EINVAL; 100 } 101 102 if (meta_left < hdr->type_off) { 103 elog("Invalid BTF type section offset:%u\n", hdr->type_off); 104 return -EINVAL; 105 } 106 107 if (meta_left < hdr->str_off) { 108 elog("Invalid BTF string section offset:%u\n", hdr->str_off); 109 return -EINVAL; 110 } 111 112 if (hdr->type_off >= hdr->str_off) { 113 elog("BTF type section offset >= string section offset. No type?\n"); 114 return -EINVAL; 115 } 116 117 if (hdr->type_off & 0x02) { 118 elog("BTF type section is not aligned to 4 bytes\n"); 119 return -EINVAL; 120 } 121 122 btf->nohdr_data = btf->hdr + 1; 123 124 return 0; 125 } 126 127 static int btf_parse_str_sec(struct btf *btf, btf_print_fn_t err_log) 128 { 129 const struct btf_header *hdr = btf->hdr; 130 const char *start = btf->nohdr_data + hdr->str_off; 131 const char *end = start + btf->hdr->str_len; 132 133 if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_NAME_OFFSET || 134 start[0] || end[-1]) { 135 elog("Invalid BTF string section\n"); 136 return -EINVAL; 137 } 138 139 btf->strings = start; 140 141 return 0; 142 } 143 144 static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) 145 { 146 struct btf_header *hdr = btf->hdr; 147 void *nohdr_data = btf->nohdr_data; 148 void *next_type = nohdr_data + hdr->type_off; 149 void *end_type = nohdr_data + hdr->str_off; 150 151 while (next_type < end_type) { 152 struct btf_type *t = next_type; 153 __u16 vlen = BTF_INFO_VLEN(t->info); 154 int err; 155 156 next_type += sizeof(*t); 157 switch (BTF_INFO_KIND(t->info)) { 158 case BTF_KIND_INT: 159 next_type += sizeof(int); 160 break; 161 case BTF_KIND_ARRAY: 162 next_type += sizeof(struct btf_array); 163 break; 164 case BTF_KIND_STRUCT: 165 case BTF_KIND_UNION: 166 next_type += vlen * sizeof(struct btf_member); 167 break; 168 case BTF_KIND_ENUM: 169 next_type += vlen * sizeof(struct btf_enum); 170 break; 171 case BTF_KIND_TYPEDEF: 172 case BTF_KIND_PTR: 173 case BTF_KIND_FWD: 174 case BTF_KIND_VOLATILE: 175 case BTF_KIND_CONST: 176 case BTF_KIND_RESTRICT: 177 break; 178 default: 179 elog("Unsupported BTF_KIND:%u\n", 180 BTF_INFO_KIND(t->info)); 181 return -EINVAL; 182 } 183 184 err = btf_add_type(btf, t); 185 if (err) 186 return err; 187 } 188 189 return 0; 190 } 191 192 const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id) 193 { 194 if (type_id > btf->nr_types) 195 return NULL; 196 197 return btf->types[type_id]; 198 } 199 200 static bool btf_type_is_void(const struct btf_type *t) 201 { 202 return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD; 203 } 204 205 static bool btf_type_is_void_or_null(const struct btf_type *t) 206 { 207 return !t || btf_type_is_void(t); 208 } 209 210 static __s64 btf_type_size(const struct btf_type *t) 211 { 212 switch (BTF_INFO_KIND(t->info)) { 213 case BTF_KIND_INT: 214 case BTF_KIND_STRUCT: 215 case BTF_KIND_UNION: 216 case BTF_KIND_ENUM: 217 return t->size; 218 case BTF_KIND_PTR: 219 return sizeof(void *); 220 default: 221 return -EINVAL; 222 } 223 } 224 225 #define MAX_RESOLVE_DEPTH 32 226 227 __s64 btf__resolve_size(const struct btf *btf, __u32 type_id) 228 { 229 const struct btf_array *array; 230 const struct btf_type *t; 231 __u32 nelems = 1; 232 __s64 size = -1; 233 int i; 234 235 t = btf__type_by_id(btf, type_id); 236 for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); 237 i++) { 238 size = btf_type_size(t); 239 if (size >= 0) 240 break; 241 242 switch (BTF_INFO_KIND(t->info)) { 243 case BTF_KIND_TYPEDEF: 244 case BTF_KIND_VOLATILE: 245 case BTF_KIND_CONST: 246 case BTF_KIND_RESTRICT: 247 type_id = t->type; 248 break; 249 case BTF_KIND_ARRAY: 250 array = (const struct btf_array *)(t + 1); 251 if (nelems && array->nelems > UINT32_MAX / nelems) 252 return -E2BIG; 253 nelems *= array->nelems; 254 type_id = array->type; 255 break; 256 default: 257 return -EINVAL; 258 } 259 260 t = btf__type_by_id(btf, type_id); 261 } 262 263 if (size < 0) 264 return -EINVAL; 265 266 if (nelems && size > UINT32_MAX / nelems) 267 return -E2BIG; 268 269 return nelems * size; 270 } 271 272 __s32 btf__find_by_name(const struct btf *btf, const char *type_name) 273 { 274 __u32 i; 275 276 if (!strcmp(type_name, "void")) 277 return 0; 278 279 for (i = 1; i <= btf->nr_types; i++) { 280 const struct btf_type *t = btf->types[i]; 281 const char *name = btf_name_by_offset(btf, t->name_off); 282 283 if (name && !strcmp(type_name, name)) 284 return i; 285 } 286 287 return -ENOENT; 288 } 289 290 void btf__free(struct btf *btf) 291 { 292 if (!btf) 293 return; 294 295 if (btf->fd != -1) 296 close(btf->fd); 297 298 free(btf->data); 299 free(btf->types); 300 free(btf); 301 } 302 303 struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log) 304 { 305 __u32 log_buf_size = 0; 306 char *log_buf = NULL; 307 struct btf *btf; 308 int err; 309 310 btf = calloc(1, sizeof(struct btf)); 311 if (!btf) 312 return ERR_PTR(-ENOMEM); 313 314 btf->fd = -1; 315 316 if (err_log) { 317 log_buf = malloc(BPF_LOG_BUF_SIZE); 318 if (!log_buf) { 319 err = -ENOMEM; 320 goto done; 321 } 322 *log_buf = 0; 323 log_buf_size = BPF_LOG_BUF_SIZE; 324 } 325 326 btf->data = malloc(size); 327 if (!btf->data) { 328 err = -ENOMEM; 329 goto done; 330 } 331 332 memcpy(btf->data, data, size); 333 btf->data_size = size; 334 335 btf->fd = bpf_load_btf(btf->data, btf->data_size, 336 log_buf, log_buf_size, false); 337 338 if (btf->fd == -1) { 339 err = -errno; 340 elog("Error loading BTF: %s(%d)\n", strerror(errno), errno); 341 if (log_buf && *log_buf) 342 elog("%s\n", log_buf); 343 goto done; 344 } 345 346 err = btf_parse_hdr(btf, err_log); 347 if (err) 348 goto done; 349 350 err = btf_parse_str_sec(btf, err_log); 351 if (err) 352 goto done; 353 354 err = btf_parse_type_sec(btf, err_log); 355 356 done: 357 free(log_buf); 358 359 if (err) { 360 btf__free(btf); 361 return ERR_PTR(err); 362 } 363 364 return btf; 365 } 366 367 int btf__fd(const struct btf *btf) 368 { 369 return btf->fd; 370 } 371