Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/bpf/resolve_btfids/main.c
50356 views
1
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2
3
/*
4
* resolve_btfids scans ELF object for .BTF_ids section and resolves
5
* its symbols with BTF ID values.
6
*
7
* Each symbol points to 4 bytes data and is expected to have
8
* following name syntax:
9
*
10
* __BTF_ID__<type>__<symbol>[__<id>]
11
*
12
* type is:
13
*
14
* func - lookup BTF_KIND_FUNC symbol with <symbol> name
15
* and store its ID into the data:
16
*
17
* __BTF_ID__func__vfs_close__1:
18
* .zero 4
19
*
20
* struct - lookup BTF_KIND_STRUCT symbol with <symbol> name
21
* and store its ID into the data:
22
*
23
* __BTF_ID__struct__sk_buff__1:
24
* .zero 4
25
*
26
* union - lookup BTF_KIND_UNION symbol with <symbol> name
27
* and store its ID into the data:
28
*
29
* __BTF_ID__union__thread_union__1:
30
* .zero 4
31
*
32
* typedef - lookup BTF_KIND_TYPEDEF symbol with <symbol> name
33
* and store its ID into the data:
34
*
35
* __BTF_ID__typedef__pid_t__1:
36
* .zero 4
37
*
38
* set - store symbol size into first 4 bytes and sort following
39
* ID list
40
*
41
* __BTF_ID__set__list:
42
* .zero 4
43
* list:
44
* __BTF_ID__func__vfs_getattr__3:
45
* .zero 4
46
* __BTF_ID__func__vfs_fallocate__4:
47
* .zero 4
48
*
49
* set8 - store symbol size into first 4 bytes and sort following
50
* ID list
51
*
52
* __BTF_ID__set8__list:
53
* .zero 8
54
* list:
55
* __BTF_ID__func__vfs_getattr__3:
56
* .zero 4
57
* .word (1 << 0) | (1 << 2)
58
* __BTF_ID__func__vfs_fallocate__5:
59
* .zero 4
60
* .word (1 << 3) | (1 << 1) | (1 << 2)
61
*/
62
63
#define _GNU_SOURCE
64
#include <stdio.h>
65
#include <string.h>
66
#include <unistd.h>
67
#include <stdlib.h>
68
#include <libelf.h>
69
#include <gelf.h>
70
#include <sys/stat.h>
71
#include <fcntl.h>
72
#include <errno.h>
73
#include <linux/btf_ids.h>
74
#include <linux/kallsyms.h>
75
#include <linux/rbtree.h>
76
#include <linux/zalloc.h>
77
#include <linux/err.h>
78
#include <linux/limits.h>
79
#include <bpf/btf.h>
80
#include <bpf/libbpf.h>
81
#include <subcmd/parse-options.h>
82
83
#define BTF_IDS_SECTION ".BTF_ids"
84
#define BTF_ID_PREFIX "__BTF_ID__"
85
86
#define BTF_STRUCT "struct"
87
#define BTF_UNION "union"
88
#define BTF_TYPEDEF "typedef"
89
#define BTF_FUNC "func"
90
#define BTF_SET "set"
91
#define BTF_SET8 "set8"
92
93
#define ADDR_CNT 100
94
95
#if __BYTE_ORDER == __LITTLE_ENDIAN
96
# define ELFDATANATIVE ELFDATA2LSB
97
#elif __BYTE_ORDER == __BIG_ENDIAN
98
# define ELFDATANATIVE ELFDATA2MSB
99
#else
100
# error "Unknown machine endianness!"
101
#endif
102
103
enum btf_id_kind {
104
BTF_ID_KIND_NONE,
105
BTF_ID_KIND_SYM,
106
BTF_ID_KIND_SET,
107
BTF_ID_KIND_SET8
108
};
109
110
struct btf_id {
111
struct rb_node rb_node;
112
char *name;
113
union {
114
int id;
115
int cnt;
116
};
117
enum btf_id_kind kind;
118
int addr_cnt;
119
Elf64_Addr addr[ADDR_CNT];
120
};
121
122
struct object {
123
const char *path;
124
const char *btf_path;
125
const char *base_btf_path;
126
127
struct btf *btf;
128
struct btf *base_btf;
129
bool distill_base;
130
131
struct {
132
int fd;
133
Elf *elf;
134
Elf_Data *symbols;
135
Elf_Data *idlist;
136
int symbols_shndx;
137
int idlist_shndx;
138
size_t strtabidx;
139
unsigned long idlist_addr;
140
int encoding;
141
} efile;
142
143
struct rb_root sets;
144
struct rb_root structs;
145
struct rb_root unions;
146
struct rb_root typedefs;
147
struct rb_root funcs;
148
149
int nr_funcs;
150
int nr_structs;
151
int nr_unions;
152
int nr_typedefs;
153
};
154
155
#define KF_IMPLICIT_ARGS (1 << 16)
156
#define KF_IMPL_SUFFIX "_impl"
157
158
struct kfunc {
159
const char *name;
160
u32 btf_id;
161
u32 flags;
162
};
163
164
struct btf2btf_context {
165
struct btf *btf;
166
u32 *decl_tags;
167
u32 nr_decl_tags;
168
u32 max_decl_tags;
169
struct kfunc *kfuncs;
170
u32 nr_kfuncs;
171
u32 max_kfuncs;
172
};
173
174
static int verbose;
175
static int warnings;
176
177
static int eprintf(int level, int var, const char *fmt, ...)
178
{
179
va_list args;
180
int ret = 0;
181
182
if (var >= level) {
183
va_start(args, fmt);
184
ret = vfprintf(stderr, fmt, args);
185
va_end(args);
186
}
187
return ret;
188
}
189
190
#ifndef pr_fmt
191
#define pr_fmt(fmt) fmt
192
#endif
193
194
#define pr_debug(fmt, ...) \
195
eprintf(1, verbose, pr_fmt(fmt), ##__VA_ARGS__)
196
#define pr_debugN(n, fmt, ...) \
197
eprintf(n, verbose, pr_fmt(fmt), ##__VA_ARGS__)
198
#define pr_debug2(fmt, ...) pr_debugN(2, pr_fmt(fmt), ##__VA_ARGS__)
199
#define pr_err(fmt, ...) \
200
eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
201
#define pr_info(fmt, ...) \
202
eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
203
204
static bool is_btf_id(const char *name)
205
{
206
return name && !strncmp(name, BTF_ID_PREFIX, sizeof(BTF_ID_PREFIX) - 1);
207
}
208
209
static struct btf_id *btf_id__find(struct rb_root *root, const char *name)
210
{
211
struct rb_node *p = root->rb_node;
212
struct btf_id *id;
213
int cmp;
214
215
while (p) {
216
id = rb_entry(p, struct btf_id, rb_node);
217
cmp = strcmp(id->name, name);
218
if (cmp < 0)
219
p = p->rb_left;
220
else if (cmp > 0)
221
p = p->rb_right;
222
else
223
return id;
224
}
225
return NULL;
226
}
227
228
static struct btf_id *__btf_id__add(struct rb_root *root,
229
char *name,
230
enum btf_id_kind kind,
231
bool unique)
232
{
233
struct rb_node **p = &root->rb_node;
234
struct rb_node *parent = NULL;
235
struct btf_id *id;
236
int cmp;
237
238
while (*p != NULL) {
239
parent = *p;
240
id = rb_entry(parent, struct btf_id, rb_node);
241
cmp = strcmp(id->name, name);
242
if (cmp < 0)
243
p = &(*p)->rb_left;
244
else if (cmp > 0)
245
p = &(*p)->rb_right;
246
else
247
return unique ? NULL : id;
248
}
249
250
id = zalloc(sizeof(*id));
251
if (id) {
252
pr_debug("adding symbol %s\n", name);
253
id->name = name;
254
id->kind = kind;
255
rb_link_node(&id->rb_node, parent, p);
256
rb_insert_color(&id->rb_node, root);
257
}
258
return id;
259
}
260
261
static inline struct btf_id *btf_id__add(struct rb_root *root, char *name, enum btf_id_kind kind)
262
{
263
return __btf_id__add(root, name, kind, false);
264
}
265
266
static inline struct btf_id *btf_id__add_unique(struct rb_root *root, char *name, enum btf_id_kind kind)
267
{
268
return __btf_id__add(root, name, kind, true);
269
}
270
271
static char *get_id(const char *prefix_end)
272
{
273
/*
274
* __BTF_ID__func__vfs_truncate__0
275
* prefix_end = ^
276
* pos = ^
277
*/
278
int len = strlen(prefix_end);
279
int pos = sizeof("__") - 1;
280
char *p, *id;
281
282
if (pos >= len)
283
return NULL;
284
285
id = strdup(prefix_end + pos);
286
if (id) {
287
/*
288
* __BTF_ID__func__vfs_truncate__0
289
* id = ^
290
*
291
* cut the unique id part
292
*/
293
p = strrchr(id, '_');
294
p--;
295
if (*p != '_') {
296
free(id);
297
return NULL;
298
}
299
*p = '\0';
300
}
301
return id;
302
}
303
304
static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind kind)
305
{
306
int len = strlen(name);
307
int prefixlen;
308
char *id;
309
310
/*
311
* __BTF_ID__set__name
312
* name = ^
313
* id = ^
314
*/
315
switch (kind) {
316
case BTF_ID_KIND_SET:
317
prefixlen = sizeof(BTF_SET "__") - 1;
318
break;
319
case BTF_ID_KIND_SET8:
320
prefixlen = sizeof(BTF_SET8 "__") - 1;
321
break;
322
default:
323
pr_err("Unexpected kind %d passed to %s() for symbol %s\n", kind, __func__, name);
324
return NULL;
325
}
326
327
id = name + prefixlen;
328
if (id >= name + len) {
329
pr_err("FAILED to parse set name: %s\n", name);
330
return NULL;
331
}
332
333
return btf_id__add_unique(&obj->sets, id, kind);
334
}
335
336
static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
337
{
338
char *id;
339
340
id = get_id(name + size);
341
if (!id) {
342
pr_err("FAILED to parse symbol name: %s\n", name);
343
return NULL;
344
}
345
346
return btf_id__add(root, id, BTF_ID_KIND_SYM);
347
}
348
349
static void bswap_32_data(void *data, u32 nr_bytes)
350
{
351
u32 cnt, i;
352
u32 *ptr;
353
354
cnt = nr_bytes / sizeof(u32);
355
ptr = data;
356
357
for (i = 0; i < cnt; i++)
358
ptr[i] = bswap_32(ptr[i]);
359
}
360
361
static int elf_collect(struct object *obj)
362
{
363
Elf_Scn *scn = NULL;
364
size_t shdrstrndx;
365
GElf_Ehdr ehdr;
366
int idx = 0;
367
Elf *elf;
368
int fd;
369
370
fd = open(obj->path, O_RDWR, 0666);
371
if (fd == -1) {
372
pr_err("FAILED cannot open %s: %s\n",
373
obj->path, strerror(errno));
374
return -1;
375
}
376
377
elf_version(EV_CURRENT);
378
379
elf = elf_begin(fd, ELF_C_READ_MMAP_PRIVATE, NULL);
380
if (!elf) {
381
close(fd);
382
pr_err("FAILED cannot create ELF descriptor: %s\n",
383
elf_errmsg(-1));
384
return -1;
385
}
386
387
obj->efile.fd = fd;
388
obj->efile.elf = elf;
389
390
elf_flagelf(elf, ELF_C_SET, ELF_F_LAYOUT);
391
392
if (elf_getshdrstrndx(elf, &shdrstrndx) != 0) {
393
pr_err("FAILED cannot get shdr str ndx\n");
394
return -1;
395
}
396
397
if (gelf_getehdr(obj->efile.elf, &ehdr) == NULL) {
398
pr_err("FAILED cannot get ELF header: %s\n",
399
elf_errmsg(-1));
400
return -1;
401
}
402
obj->efile.encoding = ehdr.e_ident[EI_DATA];
403
404
/*
405
* Scan all the elf sections and look for save data
406
* from .BTF_ids section and symbols.
407
*/
408
while ((scn = elf_nextscn(elf, scn)) != NULL) {
409
Elf_Data *data;
410
GElf_Shdr sh;
411
char *name;
412
413
idx++;
414
if (gelf_getshdr(scn, &sh) != &sh) {
415
pr_err("FAILED get section(%d) header\n", idx);
416
return -1;
417
}
418
419
name = elf_strptr(elf, shdrstrndx, sh.sh_name);
420
if (!name) {
421
pr_err("FAILED get section(%d) name\n", idx);
422
return -1;
423
}
424
425
data = elf_getdata(scn, 0);
426
if (!data) {
427
pr_err("FAILED to get section(%d) data from %s\n",
428
idx, name);
429
return -1;
430
}
431
432
pr_debug2("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
433
idx, name, (unsigned long) data->d_size,
434
(int) sh.sh_link, (unsigned long) sh.sh_flags,
435
(int) sh.sh_type);
436
437
if (sh.sh_type == SHT_SYMTAB) {
438
obj->efile.symbols = data;
439
obj->efile.symbols_shndx = idx;
440
obj->efile.strtabidx = sh.sh_link;
441
} else if (!strcmp(name, BTF_IDS_SECTION)) {
442
/*
443
* If target endianness differs from host, we need to bswap32
444
* the .BTF_ids section data on load, because .BTF_ids has
445
* Elf_Type = ELF_T_BYTE, and so libelf returns data buffer in
446
* the target endianness. We repeat this on dump.
447
*/
448
if (obj->efile.encoding != ELFDATANATIVE) {
449
pr_debug("bswap_32 .BTF_ids data from target to host endianness\n");
450
bswap_32_data(data->d_buf, data->d_size);
451
}
452
obj->efile.idlist = data;
453
obj->efile.idlist_shndx = idx;
454
obj->efile.idlist_addr = sh.sh_addr;
455
}
456
}
457
458
return 0;
459
}
460
461
static int symbols_collect(struct object *obj)
462
{
463
Elf_Scn *scn = NULL;
464
int n, i;
465
GElf_Shdr sh;
466
char *name;
467
468
scn = elf_getscn(obj->efile.elf, obj->efile.symbols_shndx);
469
if (!scn)
470
return -1;
471
472
if (gelf_getshdr(scn, &sh) != &sh)
473
return -1;
474
475
n = sh.sh_size / sh.sh_entsize;
476
477
/*
478
* Scan symbols and look for the ones starting with
479
* __BTF_ID__* over .BTF_ids section.
480
*/
481
for (i = 0; i < n; i++) {
482
char *prefix;
483
struct btf_id *id;
484
GElf_Sym sym;
485
486
if (!gelf_getsym(obj->efile.symbols, i, &sym))
487
return -1;
488
489
if (sym.st_shndx != obj->efile.idlist_shndx)
490
continue;
491
492
name = elf_strptr(obj->efile.elf, obj->efile.strtabidx,
493
sym.st_name);
494
495
if (!is_btf_id(name))
496
continue;
497
498
/*
499
* __BTF_ID__TYPE__vfs_truncate__0
500
* prefix = ^
501
*/
502
prefix = name + sizeof(BTF_ID_PREFIX) - 1;
503
504
/* struct */
505
if (!strncmp(prefix, BTF_STRUCT, sizeof(BTF_STRUCT) - 1)) {
506
obj->nr_structs++;
507
id = add_symbol(&obj->structs, prefix, sizeof(BTF_STRUCT) - 1);
508
/* union */
509
} else if (!strncmp(prefix, BTF_UNION, sizeof(BTF_UNION) - 1)) {
510
obj->nr_unions++;
511
id = add_symbol(&obj->unions, prefix, sizeof(BTF_UNION) - 1);
512
/* typedef */
513
} else if (!strncmp(prefix, BTF_TYPEDEF, sizeof(BTF_TYPEDEF) - 1)) {
514
obj->nr_typedefs++;
515
id = add_symbol(&obj->typedefs, prefix, sizeof(BTF_TYPEDEF) - 1);
516
/* func */
517
} else if (!strncmp(prefix, BTF_FUNC, sizeof(BTF_FUNC) - 1)) {
518
obj->nr_funcs++;
519
id = add_symbol(&obj->funcs, prefix, sizeof(BTF_FUNC) - 1);
520
/* set8 */
521
} else if (!strncmp(prefix, BTF_SET8, sizeof(BTF_SET8) - 1)) {
522
id = add_set(obj, prefix, BTF_ID_KIND_SET8);
523
/*
524
* SET8 objects store list's count, which is encoded
525
* in symbol's size, together with 'cnt' field hence
526
* that - 1.
527
*/
528
if (id)
529
id->cnt = sym.st_size / sizeof(uint64_t) - 1;
530
/* set */
531
} else if (!strncmp(prefix, BTF_SET, sizeof(BTF_SET) - 1)) {
532
id = add_set(obj, prefix, BTF_ID_KIND_SET);
533
/*
534
* SET objects store list's count, which is encoded
535
* in symbol's size, together with 'cnt' field hence
536
* that - 1.
537
*/
538
if (id)
539
id->cnt = sym.st_size / sizeof(int) - 1;
540
} else {
541
pr_err("FAILED unsupported prefix %s\n", prefix);
542
return -1;
543
}
544
545
if (!id)
546
return -EINVAL;
547
548
if (id->addr_cnt >= ADDR_CNT) {
549
pr_err("FAILED symbol %s crossed the number of allowed lists\n",
550
id->name);
551
return -1;
552
}
553
id->addr[id->addr_cnt++] = sym.st_value;
554
}
555
556
return 0;
557
}
558
559
static int load_btf(struct object *obj)
560
{
561
struct btf *base_btf = NULL, *btf = NULL;
562
int err;
563
564
if (obj->base_btf_path) {
565
base_btf = btf__parse(obj->base_btf_path, NULL);
566
err = libbpf_get_error(base_btf);
567
if (err) {
568
pr_err("FAILED: load base BTF from %s: %s\n",
569
obj->base_btf_path, strerror(-err));
570
goto out_err;
571
}
572
}
573
574
btf = btf__parse_split(obj->btf_path ?: obj->path, base_btf);
575
err = libbpf_get_error(btf);
576
if (err) {
577
pr_err("FAILED: load BTF from %s: %s\n",
578
obj->btf_path ?: obj->path, strerror(-err));
579
goto out_err;
580
}
581
582
obj->base_btf = base_btf;
583
obj->btf = btf;
584
585
return 0;
586
587
out_err:
588
btf__free(base_btf);
589
btf__free(btf);
590
obj->base_btf = NULL;
591
obj->btf = NULL;
592
return err;
593
}
594
595
static int symbols_resolve(struct object *obj)
596
{
597
int nr_typedefs = obj->nr_typedefs;
598
int nr_structs = obj->nr_structs;
599
int nr_unions = obj->nr_unions;
600
int nr_funcs = obj->nr_funcs;
601
struct btf *btf = obj->btf;
602
int err, type_id;
603
__u32 nr_types;
604
605
err = -1;
606
nr_types = btf__type_cnt(btf);
607
608
/*
609
* Iterate all the BTF types and search for collected symbol IDs.
610
*/
611
for (type_id = 1; type_id < nr_types; type_id++) {
612
const struct btf_type *type;
613
struct rb_root *root;
614
struct btf_id *id;
615
const char *str;
616
int *nr;
617
618
type = btf__type_by_id(btf, type_id);
619
if (!type) {
620
pr_err("FAILED: malformed BTF, can't resolve type for ID %d\n",
621
type_id);
622
goto out;
623
}
624
625
if (btf_is_func(type) && nr_funcs) {
626
nr = &nr_funcs;
627
root = &obj->funcs;
628
} else if (btf_is_struct(type) && nr_structs) {
629
nr = &nr_structs;
630
root = &obj->structs;
631
} else if (btf_is_union(type) && nr_unions) {
632
nr = &nr_unions;
633
root = &obj->unions;
634
} else if (btf_is_typedef(type) && nr_typedefs) {
635
nr = &nr_typedefs;
636
root = &obj->typedefs;
637
} else
638
continue;
639
640
str = btf__name_by_offset(btf, type->name_off);
641
if (!str) {
642
pr_err("FAILED: malformed BTF, can't resolve name for ID %d\n",
643
type_id);
644
goto out;
645
}
646
647
id = btf_id__find(root, str);
648
if (id) {
649
if (id->id) {
650
pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
651
str, id->id, type_id, id->id);
652
warnings++;
653
} else {
654
id->id = type_id;
655
(*nr)--;
656
}
657
}
658
}
659
660
err = 0;
661
out:
662
return err;
663
}
664
665
static int id_patch(struct object *obj, struct btf_id *id)
666
{
667
Elf_Data *data = obj->efile.idlist;
668
int *ptr = data->d_buf;
669
int i;
670
671
/* For set, set8, id->id may be 0 */
672
if (!id->id && id->kind != BTF_ID_KIND_SET && id->kind != BTF_ID_KIND_SET8) {
673
pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
674
warnings++;
675
}
676
677
for (i = 0; i < id->addr_cnt; i++) {
678
unsigned long addr = id->addr[i];
679
unsigned long idx = addr - obj->efile.idlist_addr;
680
681
pr_debug("patching addr %5lu: ID %7d [%s]\n",
682
idx, id->id, id->name);
683
684
if (idx >= data->d_size) {
685
pr_err("FAILED patching index %lu out of bounds %lu\n",
686
idx, data->d_size);
687
return -1;
688
}
689
690
idx = idx / sizeof(int);
691
ptr[idx] = id->id;
692
}
693
694
return 0;
695
}
696
697
static int __symbols_patch(struct object *obj, struct rb_root *root)
698
{
699
struct rb_node *next;
700
struct btf_id *id;
701
702
next = rb_first(root);
703
while (next) {
704
id = rb_entry(next, struct btf_id, rb_node);
705
706
if (id_patch(obj, id))
707
return -1;
708
709
next = rb_next(next);
710
}
711
return 0;
712
}
713
714
static int cmp_id(const void *pa, const void *pb)
715
{
716
const int *a = pa, *b = pb;
717
718
return *a - *b;
719
}
720
721
static int sets_patch(struct object *obj)
722
{
723
Elf_Data *data = obj->efile.idlist;
724
struct rb_node *next;
725
int cnt;
726
727
next = rb_first(&obj->sets);
728
while (next) {
729
struct btf_id_set8 *set8 = NULL;
730
struct btf_id_set *set = NULL;
731
unsigned long addr, off;
732
struct btf_id *id;
733
734
id = rb_entry(next, struct btf_id, rb_node);
735
addr = id->addr[0];
736
off = addr - obj->efile.idlist_addr;
737
738
/* sets are unique */
739
if (id->addr_cnt != 1) {
740
pr_err("FAILED malformed data for set '%s'\n",
741
id->name);
742
return -1;
743
}
744
745
switch (id->kind) {
746
case BTF_ID_KIND_SET:
747
set = data->d_buf + off;
748
cnt = set->cnt;
749
qsort(set->ids, set->cnt, sizeof(set->ids[0]), cmp_id);
750
break;
751
case BTF_ID_KIND_SET8:
752
set8 = data->d_buf + off;
753
cnt = set8->cnt;
754
/*
755
* Make sure id is at the beginning of the pairs
756
* struct, otherwise the below qsort would not work.
757
*/
758
BUILD_BUG_ON((u32 *)set8->pairs != &set8->pairs[0].id);
759
qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id);
760
break;
761
default:
762
pr_err("Unexpected btf_id_kind %d for set '%s'\n", id->kind, id->name);
763
return -1;
764
}
765
766
pr_debug("sorting addr %5lu: cnt %6d [%s]\n", off, cnt, id->name);
767
768
next = rb_next(next);
769
}
770
return 0;
771
}
772
773
static int symbols_patch(struct object *obj)
774
{
775
if (__symbols_patch(obj, &obj->structs) ||
776
__symbols_patch(obj, &obj->unions) ||
777
__symbols_patch(obj, &obj->typedefs) ||
778
__symbols_patch(obj, &obj->funcs) ||
779
__symbols_patch(obj, &obj->sets))
780
return -1;
781
782
if (sets_patch(obj))
783
return -1;
784
785
return 0;
786
}
787
788
static int dump_raw_data(const char *out_path, const void *data, u32 size)
789
{
790
size_t written;
791
FILE *file;
792
793
file = fopen(out_path, "wb");
794
if (!file) {
795
pr_err("Couldn't open %s for writing\n", out_path);
796
return -1;
797
}
798
799
written = fwrite(data, 1, size, file);
800
if (written != size) {
801
pr_err("Failed to write data to %s\n", out_path);
802
fclose(file);
803
unlink(out_path);
804
return -1;
805
}
806
807
fclose(file);
808
pr_debug("Dumped %lu bytes of data to %s\n", size, out_path);
809
810
return 0;
811
}
812
813
static int dump_raw_btf_ids(struct object *obj, const char *out_path)
814
{
815
Elf_Data *data = obj->efile.idlist;
816
int err;
817
818
if (!data || !data->d_buf) {
819
pr_debug("%s has no BTF_ids data to dump\n", obj->path);
820
return 0;
821
}
822
823
/*
824
* If target endianness differs from host, we need to bswap32 the
825
* .BTF_ids section data before dumping so that the output is in
826
* target endianness.
827
*/
828
if (obj->efile.encoding != ELFDATANATIVE) {
829
pr_debug("bswap_32 .BTF_ids data from host to target endianness\n");
830
bswap_32_data(data->d_buf, data->d_size);
831
}
832
833
err = dump_raw_data(out_path, data->d_buf, data->d_size);
834
if (err)
835
return -1;
836
837
return 0;
838
}
839
840
static int dump_raw_btf(struct btf *btf, const char *out_path)
841
{
842
const void *raw_btf_data;
843
u32 raw_btf_size;
844
int err;
845
846
raw_btf_data = btf__raw_data(btf, &raw_btf_size);
847
if (!raw_btf_data) {
848
pr_err("btf__raw_data() failed\n");
849
return -1;
850
}
851
852
err = dump_raw_data(out_path, raw_btf_data, raw_btf_size);
853
if (err)
854
return -1;
855
856
return 0;
857
}
858
859
static const struct btf_type *btf_type_skip_qualifiers(const struct btf *btf, s32 type_id)
860
{
861
const struct btf_type *t = btf__type_by_id(btf, type_id);
862
863
while (btf_is_mod(t))
864
t = btf__type_by_id(btf, t->type);
865
866
return t;
867
}
868
869
static int push_decl_tag_id(struct btf2btf_context *ctx, u32 decl_tag_id)
870
{
871
u32 *arr = ctx->decl_tags;
872
u32 cap = ctx->max_decl_tags;
873
874
if (ctx->nr_decl_tags + 1 > cap) {
875
cap = max(cap + 256, cap * 2);
876
arr = realloc(arr, sizeof(u32) * cap);
877
if (!arr)
878
return -ENOMEM;
879
ctx->max_decl_tags = cap;
880
ctx->decl_tags = arr;
881
}
882
883
ctx->decl_tags[ctx->nr_decl_tags++] = decl_tag_id;
884
885
return 0;
886
}
887
888
static int push_kfunc(struct btf2btf_context *ctx, struct kfunc *kfunc)
889
{
890
struct kfunc *arr = ctx->kfuncs;
891
u32 cap = ctx->max_kfuncs;
892
893
if (ctx->nr_kfuncs + 1 > cap) {
894
cap = max(cap + 256, cap * 2);
895
arr = realloc(arr, sizeof(struct kfunc) * cap);
896
if (!arr)
897
return -ENOMEM;
898
ctx->max_kfuncs = cap;
899
ctx->kfuncs = arr;
900
}
901
902
ctx->kfuncs[ctx->nr_kfuncs++] = *kfunc;
903
904
return 0;
905
}
906
907
static int collect_decl_tags(struct btf2btf_context *ctx)
908
{
909
const u32 type_cnt = btf__type_cnt(ctx->btf);
910
struct btf *btf = ctx->btf;
911
const struct btf_type *t;
912
int err;
913
914
for (u32 id = 1; id < type_cnt; id++) {
915
t = btf__type_by_id(btf, id);
916
if (!btf_is_decl_tag(t))
917
continue;
918
err = push_decl_tag_id(ctx, id);
919
if (err)
920
return err;
921
}
922
923
return 0;
924
}
925
926
/*
927
* To find the kfunc flags having its struct btf_id (with ELF addresses)
928
* we need to find the address that is in range of a set8.
929
* If a set8 is found, then the flags are located at addr + 4 bytes.
930
* Return 0 (no flags!) if not found.
931
*/
932
static u32 find_kfunc_flags(struct object *obj, struct btf_id *kfunc_id)
933
{
934
const u32 *elf_data_ptr = obj->efile.idlist->d_buf;
935
u64 set_lower_addr, set_upper_addr, addr;
936
struct btf_id *set_id;
937
struct rb_node *next;
938
u32 flags;
939
u64 idx;
940
941
for (next = rb_first(&obj->sets); next; next = rb_next(next)) {
942
set_id = rb_entry(next, struct btf_id, rb_node);
943
if (set_id->kind != BTF_ID_KIND_SET8 || set_id->addr_cnt != 1)
944
continue;
945
946
set_lower_addr = set_id->addr[0];
947
set_upper_addr = set_lower_addr + set_id->cnt * sizeof(u64);
948
949
for (u32 i = 0; i < kfunc_id->addr_cnt; i++) {
950
addr = kfunc_id->addr[i];
951
/*
952
* Lower bound is exclusive to skip the 8-byte header of the set.
953
* Upper bound is inclusive to capture the last entry at offset 8*cnt.
954
*/
955
if (set_lower_addr < addr && addr <= set_upper_addr) {
956
pr_debug("found kfunc %s in BTF_ID_FLAGS %s\n",
957
kfunc_id->name, set_id->name);
958
idx = addr - obj->efile.idlist_addr;
959
idx = idx / sizeof(u32) + 1;
960
flags = elf_data_ptr[idx];
961
962
return flags;
963
}
964
}
965
}
966
967
return 0;
968
}
969
970
static int collect_kfuncs(struct object *obj, struct btf2btf_context *ctx)
971
{
972
const char *tag_name, *func_name;
973
struct btf *btf = ctx->btf;
974
const struct btf_type *t;
975
u32 flags, func_id;
976
struct kfunc kfunc;
977
struct btf_id *id;
978
int err;
979
980
if (ctx->nr_decl_tags == 0)
981
return 0;
982
983
for (u32 i = 0; i < ctx->nr_decl_tags; i++) {
984
t = btf__type_by_id(btf, ctx->decl_tags[i]);
985
if (btf_kflag(t) || btf_decl_tag(t)->component_idx != -1)
986
continue;
987
988
tag_name = btf__name_by_offset(btf, t->name_off);
989
if (strcmp(tag_name, "bpf_kfunc") != 0)
990
continue;
991
992
func_id = t->type;
993
t = btf__type_by_id(btf, func_id);
994
if (!btf_is_func(t))
995
continue;
996
997
func_name = btf__name_by_offset(btf, t->name_off);
998
if (!func_name)
999
continue;
1000
1001
id = btf_id__find(&obj->funcs, func_name);
1002
if (!id || id->kind != BTF_ID_KIND_SYM)
1003
continue;
1004
1005
flags = find_kfunc_flags(obj, id);
1006
1007
kfunc.name = id->name;
1008
kfunc.btf_id = func_id;
1009
kfunc.flags = flags;
1010
1011
err = push_kfunc(ctx, &kfunc);
1012
if (err)
1013
return err;
1014
}
1015
1016
return 0;
1017
}
1018
1019
static int build_btf2btf_context(struct object *obj, struct btf2btf_context *ctx)
1020
{
1021
int err;
1022
1023
ctx->btf = obj->btf;
1024
1025
err = collect_decl_tags(ctx);
1026
if (err) {
1027
pr_err("ERROR: resolve_btfids: failed to collect decl tags from BTF\n");
1028
return err;
1029
}
1030
1031
err = collect_kfuncs(obj, ctx);
1032
if (err) {
1033
pr_err("ERROR: resolve_btfids: failed to collect kfuncs from BTF\n");
1034
return err;
1035
}
1036
1037
return 0;
1038
}
1039
1040
1041
/* Implicit BPF kfunc arguments can only be of particular types */
1042
static bool is_kf_implicit_arg(const struct btf *btf, const struct btf_param *p)
1043
{
1044
static const char *const kf_implicit_arg_types[] = {
1045
"bpf_prog_aux",
1046
};
1047
const struct btf_type *t;
1048
const char *name;
1049
1050
t = btf_type_skip_qualifiers(btf, p->type);
1051
if (!btf_is_ptr(t))
1052
return false;
1053
1054
t = btf_type_skip_qualifiers(btf, t->type);
1055
if (!btf_is_struct(t))
1056
return false;
1057
1058
name = btf__name_by_offset(btf, t->name_off);
1059
if (!name)
1060
return false;
1061
1062
for (int i = 0; i < ARRAY_SIZE(kf_implicit_arg_types); i++)
1063
if (strcmp(name, kf_implicit_arg_types[i]) == 0)
1064
return true;
1065
1066
return false;
1067
}
1068
1069
/*
1070
* For a kfunc with KF_IMPLICIT_ARGS we do the following:
1071
* 1. Add a new function with _impl suffix in the name, with the prototype
1072
* of the original kfunc.
1073
* 2. Add all decl tags except "bpf_kfunc" for the _impl func.
1074
* 3. Add a new function prototype with modified list of arguments:
1075
* omitting implicit args.
1076
* 4. Change the prototype of the original kfunc to the new one.
1077
*
1078
* This way we transform the BTF associated with the kfunc from
1079
* __bpf_kfunc bpf_foo(int arg1, void *implicit_arg);
1080
* into
1081
* bpf_foo_impl(int arg1, void *implicit_arg);
1082
* __bpf_kfunc bpf_foo(int arg1);
1083
*
1084
* If a kfunc with KF_IMPLICIT_ARGS already has an _impl counterpart
1085
* in BTF, then it's a legacy case: an _impl function is declared in the
1086
* source code. In this case, we can skip adding an _impl function, but we
1087
* still have to add a func prototype that omits implicit args.
1088
*/
1089
static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct kfunc *kfunc)
1090
{
1091
s32 idx, new_proto_id, new_func_id, proto_id;
1092
const char *param_name, *tag_name;
1093
const struct btf_param *params;
1094
enum btf_func_linkage linkage;
1095
char tmp_name[KSYM_NAME_LEN];
1096
struct btf *btf = ctx->btf;
1097
int err, len, nr_params;
1098
struct btf_type *t;
1099
1100
t = (struct btf_type *)btf__type_by_id(btf, kfunc->btf_id);
1101
if (!t || !btf_is_func(t)) {
1102
pr_err("ERROR: resolve_btfids: btf id %d is not a function\n", kfunc->btf_id);
1103
return -EINVAL;
1104
}
1105
1106
linkage = btf_vlen(t);
1107
1108
proto_id = t->type;
1109
t = (struct btf_type *)btf__type_by_id(btf, proto_id);
1110
if (!t || !btf_is_func_proto(t)) {
1111
pr_err("ERROR: resolve_btfids: btf id %d is not a function prototype\n", proto_id);
1112
return -EINVAL;
1113
}
1114
1115
len = snprintf(tmp_name, sizeof(tmp_name), "%s%s", kfunc->name, KF_IMPL_SUFFIX);
1116
if (len < 0 || len >= sizeof(tmp_name)) {
1117
pr_err("ERROR: function name is too long: %s%s\n", kfunc->name, KF_IMPL_SUFFIX);
1118
return -E2BIG;
1119
}
1120
1121
if (btf__find_by_name_kind(btf, tmp_name, BTF_KIND_FUNC) > 0) {
1122
pr_debug("resolve_btfids: function %s already exists in BTF\n", tmp_name);
1123
goto add_new_proto;
1124
}
1125
1126
/* Add a new function with _impl suffix and original prototype */
1127
new_func_id = btf__add_func(btf, tmp_name, linkage, proto_id);
1128
if (new_func_id < 0) {
1129
pr_err("ERROR: resolve_btfids: failed to add func %s to BTF\n", tmp_name);
1130
return new_func_id;
1131
}
1132
1133
/* Copy all decl tags except "bpf_kfunc" from the original kfunc to the new one */
1134
for (int i = 0; i < ctx->nr_decl_tags; i++) {
1135
t = (struct btf_type *)btf__type_by_id(btf, ctx->decl_tags[i]);
1136
if (t->type != kfunc->btf_id)
1137
continue;
1138
1139
tag_name = btf__name_by_offset(btf, t->name_off);
1140
if (strcmp(tag_name, "bpf_kfunc") == 0)
1141
continue;
1142
1143
idx = btf_decl_tag(t)->component_idx;
1144
1145
if (btf_kflag(t))
1146
err = btf__add_decl_attr(btf, tag_name, new_func_id, idx);
1147
else
1148
err = btf__add_decl_tag(btf, tag_name, new_func_id, idx);
1149
1150
if (err < 0) {
1151
pr_err("ERROR: resolve_btfids: failed to add decl tag %s for %s\n",
1152
tag_name, tmp_name);
1153
return -EINVAL;
1154
}
1155
}
1156
1157
add_new_proto:
1158
t = (struct btf_type *)btf__type_by_id(btf, proto_id);
1159
new_proto_id = btf__add_func_proto(btf, t->type);
1160
if (new_proto_id < 0) {
1161
pr_err("ERROR: resolve_btfids: failed to add func proto for %s\n", kfunc->name);
1162
return new_proto_id;
1163
}
1164
1165
/* Add non-implicit args to the new prototype */
1166
t = (struct btf_type *)btf__type_by_id(btf, proto_id);
1167
nr_params = btf_vlen(t);
1168
for (int i = 0; i < nr_params; i++) {
1169
params = btf_params(t);
1170
if (is_kf_implicit_arg(btf, &params[i]))
1171
break;
1172
param_name = btf__name_by_offset(btf, params[i].name_off);
1173
err = btf__add_func_param(btf, param_name, params[i].type);
1174
if (err < 0) {
1175
pr_err("ERROR: resolve_btfids: failed to add param %s for %s\n",
1176
param_name, kfunc->name);
1177
return err;
1178
}
1179
t = (struct btf_type *)btf__type_by_id(btf, proto_id);
1180
}
1181
1182
/* Finally change the prototype of the original kfunc to the new one */
1183
t = (struct btf_type *)btf__type_by_id(btf, kfunc->btf_id);
1184
t->type = new_proto_id;
1185
1186
pr_debug("resolve_btfids: updated BTF for kfunc with implicit args %s\n", kfunc->name);
1187
1188
return 0;
1189
}
1190
1191
static int btf2btf(struct object *obj)
1192
{
1193
struct btf2btf_context ctx = {};
1194
int err;
1195
1196
err = build_btf2btf_context(obj, &ctx);
1197
if (err)
1198
goto out;
1199
1200
for (u32 i = 0; i < ctx.nr_kfuncs; i++) {
1201
struct kfunc *kfunc = &ctx.kfuncs[i];
1202
1203
if (!(kfunc->flags & KF_IMPLICIT_ARGS))
1204
continue;
1205
1206
err = process_kfunc_with_implicit_args(&ctx, kfunc);
1207
if (err)
1208
goto out;
1209
}
1210
1211
err = 0;
1212
out:
1213
free(ctx.decl_tags);
1214
free(ctx.kfuncs);
1215
1216
return err;
1217
}
1218
1219
/*
1220
* Sort types by name in ascending order resulting in all
1221
* anonymous types being placed before named types.
1222
*/
1223
static int cmp_type_names(const void *a, const void *b, void *priv)
1224
{
1225
struct btf *btf = (struct btf *)priv;
1226
const struct btf_type *ta = btf__type_by_id(btf, *(__u32 *)a);
1227
const struct btf_type *tb = btf__type_by_id(btf, *(__u32 *)b);
1228
const char *na, *nb;
1229
int r;
1230
1231
na = btf__str_by_offset(btf, ta->name_off);
1232
nb = btf__str_by_offset(btf, tb->name_off);
1233
r = strcmp(na, nb);
1234
if (r != 0)
1235
return r;
1236
1237
/* preserve original relative order of anonymous or same-named types */
1238
return *(__u32 *)a < *(__u32 *)b ? -1 : 1;
1239
}
1240
1241
static int sort_btf_by_name(struct btf *btf)
1242
{
1243
__u32 *permute_ids = NULL, *id_map = NULL;
1244
int nr_types, i, err = 0;
1245
__u32 start_id = 0, id;
1246
1247
if (btf__base_btf(btf))
1248
start_id = btf__type_cnt(btf__base_btf(btf));
1249
nr_types = btf__type_cnt(btf) - start_id;
1250
1251
permute_ids = calloc(nr_types, sizeof(*permute_ids));
1252
if (!permute_ids) {
1253
err = -ENOMEM;
1254
goto out;
1255
}
1256
1257
id_map = calloc(nr_types, sizeof(*id_map));
1258
if (!id_map) {
1259
err = -ENOMEM;
1260
goto out;
1261
}
1262
1263
for (i = 0, id = start_id; i < nr_types; i++, id++)
1264
permute_ids[i] = id;
1265
1266
qsort_r(permute_ids, nr_types, sizeof(*permute_ids), cmp_type_names,
1267
btf);
1268
1269
for (i = 0; i < nr_types; i++) {
1270
id = permute_ids[i] - start_id;
1271
id_map[id] = i + start_id;
1272
}
1273
1274
err = btf__permute(btf, id_map, nr_types, NULL);
1275
if (err)
1276
pr_err("FAILED: btf permute: %s\n", strerror(-err));
1277
1278
out:
1279
free(permute_ids);
1280
free(id_map);
1281
return err;
1282
}
1283
1284
static int finalize_btf(struct object *obj)
1285
{
1286
struct btf *base_btf = obj->base_btf, *btf = obj->btf;
1287
int err;
1288
1289
if (obj->base_btf && obj->distill_base) {
1290
err = btf__distill_base(obj->btf, &base_btf, &btf);
1291
if (err) {
1292
pr_err("FAILED to distill base BTF: %s\n", strerror(errno));
1293
goto out_err;
1294
}
1295
1296
btf__free(obj->base_btf);
1297
btf__free(obj->btf);
1298
obj->base_btf = base_btf;
1299
obj->btf = btf;
1300
}
1301
1302
err = sort_btf_by_name(obj->btf);
1303
if (err) {
1304
pr_err("FAILED to sort BTF: %s\n", strerror(errno));
1305
goto out_err;
1306
}
1307
1308
return 0;
1309
1310
out_err:
1311
btf__free(base_btf);
1312
btf__free(btf);
1313
obj->base_btf = NULL;
1314
obj->btf = NULL;
1315
1316
return err;
1317
}
1318
1319
static inline int make_out_path(char *buf, u32 buf_sz, const char *in_path, const char *suffix)
1320
{
1321
int len = snprintf(buf, buf_sz, "%s%s", in_path, suffix);
1322
1323
if (len < 0 || len >= buf_sz) {
1324
pr_err("Output path is too long: %s%s\n", in_path, suffix);
1325
return -E2BIG;
1326
}
1327
1328
return 0;
1329
}
1330
1331
/*
1332
* Patch the .BTF_ids section of an ELF file with data from provided file.
1333
* Equivalent to: objcopy --update-section .BTF_ids=<btfids> <elf>
1334
*
1335
* 1. Find .BTF_ids section in the ELF
1336
* 2. Verify that blob file size matches section size
1337
* 3. Update section data buffer with blob data
1338
* 4. Write the ELF file
1339
*/
1340
static int patch_btfids(const char *btfids_path, const char *elf_path)
1341
{
1342
Elf_Scn *scn = NULL;
1343
FILE *btfids_file;
1344
size_t shdrstrndx;
1345
int fd, err = -1;
1346
Elf_Data *data;
1347
struct stat st;
1348
GElf_Shdr sh;
1349
char *name;
1350
Elf *elf;
1351
1352
elf_version(EV_CURRENT);
1353
1354
fd = open(elf_path, O_RDWR, 0666);
1355
if (fd < 0) {
1356
pr_err("FAILED to open %s: %s\n", elf_path, strerror(errno));
1357
return -1;
1358
}
1359
1360
elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL);
1361
if (!elf) {
1362
close(fd);
1363
pr_err("FAILED cannot create ELF descriptor: %s\n", elf_errmsg(-1));
1364
return -1;
1365
}
1366
1367
elf_flagelf(elf, ELF_C_SET, ELF_F_LAYOUT);
1368
1369
if (elf_getshdrstrndx(elf, &shdrstrndx) != 0) {
1370
pr_err("FAILED cannot get shdr str ndx\n");
1371
goto out;
1372
}
1373
1374
while ((scn = elf_nextscn(elf, scn)) != NULL) {
1375
1376
if (gelf_getshdr(scn, &sh) != &sh) {
1377
pr_err("FAILED to get section header\n");
1378
goto out;
1379
}
1380
1381
name = elf_strptr(elf, shdrstrndx, sh.sh_name);
1382
if (!name)
1383
continue;
1384
1385
if (strcmp(name, BTF_IDS_SECTION) == 0)
1386
break;
1387
}
1388
1389
if (!scn) {
1390
pr_err("FAILED: section %s not found in %s\n", BTF_IDS_SECTION, elf_path);
1391
goto out;
1392
}
1393
1394
data = elf_getdata(scn, NULL);
1395
if (!data) {
1396
pr_err("FAILED to get %s section data from %s\n", BTF_IDS_SECTION, elf_path);
1397
goto out;
1398
}
1399
1400
if (stat(btfids_path, &st) < 0) {
1401
pr_err("FAILED to stat %s: %s\n", btfids_path, strerror(errno));
1402
goto out;
1403
}
1404
1405
if ((size_t)st.st_size != data->d_size) {
1406
pr_err("FAILED: size mismatch - %s section in %s is %zu bytes, %s is %zu bytes\n",
1407
BTF_IDS_SECTION, elf_path, data->d_size, btfids_path, (size_t)st.st_size);
1408
goto out;
1409
}
1410
1411
btfids_file = fopen(btfids_path, "rb");
1412
if (!btfids_file) {
1413
pr_err("FAILED to open %s: %s\n", btfids_path, strerror(errno));
1414
goto out;
1415
}
1416
1417
pr_debug("Copying data from %s to %s section of %s (%zu bytes)\n",
1418
btfids_path, BTF_IDS_SECTION, elf_path, data->d_size);
1419
1420
if (fread(data->d_buf, data->d_size, 1, btfids_file) != 1) {
1421
pr_err("FAILED to read %s\n", btfids_path);
1422
fclose(btfids_file);
1423
goto out;
1424
}
1425
fclose(btfids_file);
1426
1427
elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY);
1428
if (elf_update(elf, ELF_C_WRITE) < 0) {
1429
pr_err("FAILED to update ELF file %s\n", elf_path);
1430
goto out;
1431
}
1432
1433
err = 0;
1434
out:
1435
elf_end(elf);
1436
close(fd);
1437
1438
return err;
1439
}
1440
1441
static const char * const resolve_btfids_usage[] = {
1442
"resolve_btfids [<options>] <ELF object>",
1443
"resolve_btfids --patch_btfids <.BTF_ids file> <ELF object>",
1444
NULL
1445
};
1446
1447
int main(int argc, const char **argv)
1448
{
1449
struct object obj = {
1450
.efile = {
1451
.idlist_shndx = -1,
1452
.symbols_shndx = -1,
1453
},
1454
.structs = RB_ROOT,
1455
.unions = RB_ROOT,
1456
.typedefs = RB_ROOT,
1457
.funcs = RB_ROOT,
1458
.sets = RB_ROOT,
1459
};
1460
const char *btfids_path = NULL;
1461
bool fatal_warnings = false;
1462
bool resolve_btfids = true;
1463
char out_path[PATH_MAX];
1464
1465
struct option btfid_options[] = {
1466
OPT_INCR('v', "verbose", &verbose,
1467
"be more verbose (show errors, etc)"),
1468
OPT_STRING(0, "btf", &obj.btf_path, "file",
1469
"path to a file with input BTF data"),
1470
OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
1471
"path of file providing base BTF"),
1472
OPT_BOOLEAN(0, "fatal_warnings", &fatal_warnings,
1473
"turn warnings into errors"),
1474
OPT_BOOLEAN(0, "distill_base", &obj.distill_base,
1475
"distill --btf_base and emit .BTF.base section data"),
1476
OPT_STRING(0, "patch_btfids", &btfids_path, "file",
1477
"path to .BTF_ids section data blob to patch into ELF file"),
1478
OPT_END()
1479
};
1480
int err = -1;
1481
1482
argc = parse_options(argc, argv, btfid_options, resolve_btfids_usage,
1483
PARSE_OPT_STOP_AT_NON_OPTION);
1484
if (argc != 1)
1485
usage_with_options(resolve_btfids_usage, btfid_options);
1486
1487
obj.path = argv[0];
1488
1489
if (btfids_path)
1490
return patch_btfids(btfids_path, obj.path);
1491
1492
if (elf_collect(&obj))
1493
goto out;
1494
1495
/*
1496
* We did not find .BTF_ids section or symbols section,
1497
* nothing to do..
1498
*/
1499
if (obj.efile.idlist_shndx == -1 ||
1500
obj.efile.symbols_shndx == -1) {
1501
pr_debug("Cannot find .BTF_ids or symbols sections, skip symbols resolution\n");
1502
resolve_btfids = false;
1503
}
1504
1505
if (resolve_btfids)
1506
if (symbols_collect(&obj))
1507
goto out;
1508
1509
if (load_btf(&obj))
1510
goto out;
1511
1512
if (btf2btf(&obj))
1513
goto out;
1514
1515
if (finalize_btf(&obj))
1516
goto out;
1517
1518
if (!resolve_btfids)
1519
goto dump_btf;
1520
1521
if (symbols_resolve(&obj))
1522
goto out;
1523
1524
if (symbols_patch(&obj))
1525
goto out;
1526
1527
err = make_out_path(out_path, sizeof(out_path), obj.path, BTF_IDS_SECTION);
1528
err = err ?: dump_raw_btf_ids(&obj, out_path);
1529
if (err)
1530
goto out;
1531
1532
dump_btf:
1533
err = make_out_path(out_path, sizeof(out_path), obj.path, BTF_ELF_SEC);
1534
err = err ?: dump_raw_btf(obj.btf, out_path);
1535
if (err)
1536
goto out;
1537
1538
if (obj.base_btf && obj.distill_base) {
1539
err = make_out_path(out_path, sizeof(out_path), obj.path, BTF_BASE_ELF_SEC);
1540
err = err ?: dump_raw_btf(obj.base_btf, out_path);
1541
if (err)
1542
goto out;
1543
}
1544
1545
if (!(fatal_warnings && warnings))
1546
err = 0;
1547
out:
1548
btf__free(obj.base_btf);
1549
btf__free(obj.btf);
1550
if (obj.efile.elf) {
1551
elf_end(obj.efile.elf);
1552
close(obj.efile.fd);
1553
}
1554
return err;
1555
}
1556
1557