| .. | .. |
|---|
| 12 | 12 | #include <linux/err.h> |
|---|
| 13 | 13 | #include <linux/kernel.h> |
|---|
| 14 | 14 | #include <linux/string.h> |
|---|
| 15 | +#include <linux/zalloc.h> |
|---|
| 15 | 16 | #include <errno.h> |
|---|
| 16 | | -#include "perf.h" |
|---|
| 17 | +#include <stdlib.h> |
|---|
| 17 | 18 | #include "debug.h" |
|---|
| 19 | +#include "evlist.h" |
|---|
| 18 | 20 | #include "bpf-loader.h" |
|---|
| 19 | 21 | #include "bpf-prologue.h" |
|---|
| 20 | 22 | #include "probe-event.h" |
|---|
| 21 | 23 | #include "probe-finder.h" // for MAX_PROBES |
|---|
| 22 | 24 | #include "parse-events.h" |
|---|
| 23 | 25 | #include "strfilter.h" |
|---|
| 26 | +#include "util.h" |
|---|
| 24 | 27 | #include "llvm-utils.h" |
|---|
| 25 | 28 | #include "c++/clang-c.h" |
|---|
| 26 | 29 | |
|---|
| 27 | | -#define DEFINE_PRINT_FN(name, level) \ |
|---|
| 28 | | -static int libbpf_##name(const char *fmt, ...) \ |
|---|
| 29 | | -{ \ |
|---|
| 30 | | - va_list args; \ |
|---|
| 31 | | - int ret; \ |
|---|
| 32 | | - \ |
|---|
| 33 | | - va_start(args, fmt); \ |
|---|
| 34 | | - ret = veprintf(level, verbose, pr_fmt(fmt), args);\ |
|---|
| 35 | | - va_end(args); \ |
|---|
| 36 | | - return ret; \ |
|---|
| 37 | | -} |
|---|
| 30 | +#include <internal/xyarray.h> |
|---|
| 38 | 31 | |
|---|
| 39 | | -DEFINE_PRINT_FN(warning, 1) |
|---|
| 40 | | -DEFINE_PRINT_FN(info, 1) |
|---|
| 41 | | -DEFINE_PRINT_FN(debug, 1) |
|---|
| 32 | +static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)), |
|---|
| 33 | + const char *fmt, va_list args) |
|---|
| 34 | +{ |
|---|
| 35 | + return veprintf(1, verbose, pr_fmt(fmt), args); |
|---|
| 36 | +} |
|---|
| 42 | 37 | |
|---|
| 43 | 38 | struct bpf_prog_priv { |
|---|
| 44 | 39 | bool is_tp; |
|---|
| .. | .. |
|---|
| 59 | 54 | struct bpf_object *obj; |
|---|
| 60 | 55 | |
|---|
| 61 | 56 | if (!libbpf_initialized) { |
|---|
| 62 | | - libbpf_set_print(libbpf_warning, |
|---|
| 63 | | - libbpf_info, |
|---|
| 64 | | - libbpf_debug); |
|---|
| 57 | + libbpf_set_print(libbpf_perf_print); |
|---|
| 65 | 58 | libbpf_initialized = true; |
|---|
| 66 | 59 | } |
|---|
| 67 | 60 | |
|---|
| .. | .. |
|---|
| 79 | 72 | struct bpf_object *obj; |
|---|
| 80 | 73 | |
|---|
| 81 | 74 | if (!libbpf_initialized) { |
|---|
| 82 | | - libbpf_set_print(libbpf_warning, |
|---|
| 83 | | - libbpf_info, |
|---|
| 84 | | - libbpf_debug); |
|---|
| 75 | + libbpf_set_print(libbpf_perf_print); |
|---|
| 85 | 76 | libbpf_initialized = true; |
|---|
| 86 | 77 | } |
|---|
| 87 | 78 | |
|---|
| .. | .. |
|---|
| 99 | 90 | if (err) |
|---|
| 100 | 91 | return ERR_PTR(-BPF_LOADER_ERRNO__COMPILE); |
|---|
| 101 | 92 | } else |
|---|
| 102 | | - pr_debug("bpf: successfull builtin compilation\n"); |
|---|
| 93 | + pr_debug("bpf: successful builtin compilation\n"); |
|---|
| 103 | 94 | obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, filename); |
|---|
| 104 | 95 | |
|---|
| 105 | 96 | if (!IS_ERR_OR_NULL(obj) && llvm_param.dump_obj) |
|---|
| .. | .. |
|---|
| 337 | 328 | probe_conf.no_inlines = false; |
|---|
| 338 | 329 | probe_conf.force_add = false; |
|---|
| 339 | 330 | |
|---|
| 340 | | - config_str = bpf_program__title(prog, false); |
|---|
| 341 | | - if (IS_ERR(config_str)) { |
|---|
| 342 | | - pr_debug("bpf: unable to get title for program\n"); |
|---|
| 343 | | - return PTR_ERR(config_str); |
|---|
| 344 | | - } |
|---|
| 345 | | - |
|---|
| 346 | 331 | priv = calloc(sizeof(*priv), 1); |
|---|
| 347 | 332 | if (!priv) { |
|---|
| 348 | 333 | pr_debug("bpf: failed to alloc priv\n"); |
|---|
| .. | .. |
|---|
| 350 | 335 | } |
|---|
| 351 | 336 | pev = &priv->pev; |
|---|
| 352 | 337 | |
|---|
| 338 | + config_str = bpf_program__section_name(prog); |
|---|
| 353 | 339 | pr_debug("bpf: config program '%s'\n", config_str); |
|---|
| 354 | 340 | err = parse_prog_config(config_str, &main_str, &is_tp, pev); |
|---|
| 355 | 341 | if (err) |
|---|
| .. | .. |
|---|
| 463 | 449 | if (err) { |
|---|
| 464 | 450 | const char *title; |
|---|
| 465 | 451 | |
|---|
| 466 | | - title = bpf_program__title(prog, false); |
|---|
| 467 | | - if (!title) |
|---|
| 468 | | - title = "[unknown]"; |
|---|
| 469 | | - |
|---|
| 452 | + title = bpf_program__section_name(prog); |
|---|
| 470 | 453 | pr_debug("Failed to generate prologue for program %s\n", |
|---|
| 471 | 454 | title); |
|---|
| 472 | 455 | return err; |
|---|
| .. | .. |
|---|
| 775 | 758 | |
|---|
| 776 | 759 | if (priv->is_tp) { |
|---|
| 777 | 760 | fd = bpf_program__fd(prog); |
|---|
| 778 | | - err = (*func)(priv->sys_name, priv->evt_name, fd, arg); |
|---|
| 761 | + err = (*func)(priv->sys_name, priv->evt_name, fd, obj, arg); |
|---|
| 779 | 762 | if (err) { |
|---|
| 780 | 763 | pr_debug("bpf: tracepoint call back failed, stop iterate\n"); |
|---|
| 781 | 764 | return err; |
|---|
| .. | .. |
|---|
| 800 | 783 | return fd; |
|---|
| 801 | 784 | } |
|---|
| 802 | 785 | |
|---|
| 803 | | - err = (*func)(tev->group, tev->event, fd, arg); |
|---|
| 786 | + err = (*func)(tev->group, tev->event, fd, obj, arg); |
|---|
| 804 | 787 | if (err) { |
|---|
| 805 | 788 | pr_debug("bpf: call back failed, stop iterate\n"); |
|---|
| 806 | 789 | return err; |
|---|
| .. | .. |
|---|
| 829 | 812 | } k; |
|---|
| 830 | 813 | union { |
|---|
| 831 | 814 | u64 value; |
|---|
| 832 | | - struct perf_evsel *evsel; |
|---|
| 815 | + struct evsel *evsel; |
|---|
| 833 | 816 | } v; |
|---|
| 834 | 817 | }; |
|---|
| 835 | 818 | |
|---|
| .. | .. |
|---|
| 841 | 824 | bpf_map_op__delete(struct bpf_map_op *op) |
|---|
| 842 | 825 | { |
|---|
| 843 | 826 | if (!list_empty(&op->list)) |
|---|
| 844 | | - list_del(&op->list); |
|---|
| 827 | + list_del_init(&op->list); |
|---|
| 845 | 828 | if (op->key_type == BPF_MAP_KEY_RANGES) |
|---|
| 846 | 829 | parse_events__clear_array(&op->k.array); |
|---|
| 847 | 830 | free(op); |
|---|
| .. | .. |
|---|
| 1055 | 1038 | static int |
|---|
| 1056 | 1039 | bpf_map__config_value(struct bpf_map *map, |
|---|
| 1057 | 1040 | struct parse_events_term *term, |
|---|
| 1058 | | - struct perf_evlist *evlist __maybe_unused) |
|---|
| 1041 | + struct evlist *evlist __maybe_unused) |
|---|
| 1059 | 1042 | { |
|---|
| 1060 | 1043 | if (!term->err_val) { |
|---|
| 1061 | 1044 | pr_debug("Config value not set\n"); |
|---|
| .. | .. |
|---|
| 1073 | 1056 | static int |
|---|
| 1074 | 1057 | __bpf_map__config_event(struct bpf_map *map, |
|---|
| 1075 | 1058 | struct parse_events_term *term, |
|---|
| 1076 | | - struct perf_evlist *evlist) |
|---|
| 1059 | + struct evlist *evlist) |
|---|
| 1077 | 1060 | { |
|---|
| 1078 | | - struct perf_evsel *evsel; |
|---|
| 1061 | + struct evsel *evsel; |
|---|
| 1079 | 1062 | const struct bpf_map_def *def; |
|---|
| 1080 | 1063 | struct bpf_map_op *op; |
|---|
| 1081 | 1064 | const char *map_name = bpf_map__name(map); |
|---|
| .. | .. |
|---|
| 1115 | 1098 | static int |
|---|
| 1116 | 1099 | bpf_map__config_event(struct bpf_map *map, |
|---|
| 1117 | 1100 | struct parse_events_term *term, |
|---|
| 1118 | | - struct perf_evlist *evlist) |
|---|
| 1101 | + struct evlist *evlist) |
|---|
| 1119 | 1102 | { |
|---|
| 1120 | 1103 | if (!term->err_val) { |
|---|
| 1121 | 1104 | pr_debug("Config value not set\n"); |
|---|
| .. | .. |
|---|
| 1133 | 1116 | struct bpf_obj_config__map_func { |
|---|
| 1134 | 1117 | const char *config_opt; |
|---|
| 1135 | 1118 | int (*config_func)(struct bpf_map *, struct parse_events_term *, |
|---|
| 1136 | | - struct perf_evlist *); |
|---|
| 1119 | + struct evlist *); |
|---|
| 1137 | 1120 | }; |
|---|
| 1138 | 1121 | |
|---|
| 1139 | 1122 | struct bpf_obj_config__map_func bpf_obj_config__map_funcs[] = { |
|---|
| .. | .. |
|---|
| 1181 | 1164 | static int |
|---|
| 1182 | 1165 | bpf__obj_config_map(struct bpf_object *obj, |
|---|
| 1183 | 1166 | struct parse_events_term *term, |
|---|
| 1184 | | - struct perf_evlist *evlist, |
|---|
| 1167 | + struct evlist *evlist, |
|---|
| 1185 | 1168 | int *key_scan_pos) |
|---|
| 1186 | 1169 | { |
|---|
| 1187 | 1170 | /* key is "map:<mapname>.<config opt>" */ |
|---|
| .. | .. |
|---|
| 1232 | 1215 | pr_debug("ERROR: Invalid map config option '%s'\n", map_opt); |
|---|
| 1233 | 1216 | err = -BPF_LOADER_ERRNO__OBJCONF_MAP_OPT; |
|---|
| 1234 | 1217 | out: |
|---|
| 1235 | | - free(map_name); |
|---|
| 1236 | 1218 | if (!err) |
|---|
| 1237 | | - key_scan_pos += strlen(map_opt); |
|---|
| 1219 | + *key_scan_pos += strlen(map_opt); |
|---|
| 1220 | + |
|---|
| 1221 | + free(map_name); |
|---|
| 1238 | 1222 | return err; |
|---|
| 1239 | 1223 | } |
|---|
| 1240 | 1224 | |
|---|
| 1241 | 1225 | int bpf__config_obj(struct bpf_object *obj, |
|---|
| 1242 | 1226 | struct parse_events_term *term, |
|---|
| 1243 | | - struct perf_evlist *evlist, |
|---|
| 1227 | + struct evlist *evlist, |
|---|
| 1244 | 1228 | int *error_pos) |
|---|
| 1245 | 1229 | { |
|---|
| 1246 | 1230 | int key_scan_pos = 0; |
|---|
| .. | .. |
|---|
| 1413 | 1397 | |
|---|
| 1414 | 1398 | static int |
|---|
| 1415 | 1399 | apply_config_evsel_for_key(const char *name, int map_fd, void *pkey, |
|---|
| 1416 | | - struct perf_evsel *evsel) |
|---|
| 1400 | + struct evsel *evsel) |
|---|
| 1417 | 1401 | { |
|---|
| 1418 | | - struct xyarray *xy = evsel->fd; |
|---|
| 1402 | + struct xyarray *xy = evsel->core.fd; |
|---|
| 1419 | 1403 | struct perf_event_attr *attr; |
|---|
| 1420 | 1404 | unsigned int key, events; |
|---|
| 1421 | 1405 | bool check_pass = false; |
|---|
| .. | .. |
|---|
| 1433 | 1417 | return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTDIM; |
|---|
| 1434 | 1418 | } |
|---|
| 1435 | 1419 | |
|---|
| 1436 | | - attr = &evsel->attr; |
|---|
| 1420 | + attr = &evsel->core.attr; |
|---|
| 1437 | 1421 | if (attr->inherit) { |
|---|
| 1438 | 1422 | pr_debug("ERROR: Can't put inherit event into map %s\n", name); |
|---|
| 1439 | 1423 | return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH; |
|---|
| 1440 | 1424 | } |
|---|
| 1441 | 1425 | |
|---|
| 1442 | | - if (perf_evsel__is_bpf_output(evsel)) |
|---|
| 1426 | + if (evsel__is_bpf_output(evsel)) |
|---|
| 1443 | 1427 | check_pass = true; |
|---|
| 1444 | 1428 | if (attr->type == PERF_TYPE_RAW) |
|---|
| 1445 | 1429 | check_pass = true; |
|---|
| .. | .. |
|---|
| 1503 | 1487 | struct bpf_map *map; |
|---|
| 1504 | 1488 | int err; |
|---|
| 1505 | 1489 | |
|---|
| 1506 | | - bpf_map__for_each(map, obj) { |
|---|
| 1490 | + bpf_object__for_each_map(map, obj) { |
|---|
| 1507 | 1491 | err = apply_obj_config_map(map); |
|---|
| 1508 | 1492 | if (err) |
|---|
| 1509 | 1493 | return err; |
|---|
| .. | .. |
|---|
| 1527 | 1511 | |
|---|
| 1528 | 1512 | #define bpf__for_each_map(pos, obj, objtmp) \ |
|---|
| 1529 | 1513 | bpf_object__for_each_safe(obj, objtmp) \ |
|---|
| 1530 | | - bpf_map__for_each(pos, obj) |
|---|
| 1514 | + bpf_object__for_each_map(pos, obj) |
|---|
| 1531 | 1515 | |
|---|
| 1532 | 1516 | #define bpf__for_each_map_named(pos, obj, objtmp, name) \ |
|---|
| 1533 | 1517 | bpf__for_each_map(pos, obj, objtmp) \ |
|---|
| .. | .. |
|---|
| 1535 | 1519 | (strcmp(name, \ |
|---|
| 1536 | 1520 | bpf_map__name(pos)) == 0)) |
|---|
| 1537 | 1521 | |
|---|
| 1538 | | -struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name) |
|---|
| 1522 | +struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name) |
|---|
| 1539 | 1523 | { |
|---|
| 1540 | 1524 | struct bpf_map_priv *tmpl_priv = NULL; |
|---|
| 1541 | 1525 | struct bpf_object *obj, *tmp; |
|---|
| 1542 | | - struct perf_evsel *evsel = NULL; |
|---|
| 1526 | + struct evsel *evsel = NULL; |
|---|
| 1543 | 1527 | struct bpf_map *map; |
|---|
| 1544 | 1528 | int err; |
|---|
| 1545 | 1529 | bool need_init = false; |
|---|
| .. | .. |
|---|
| 1577 | 1561 | return ERR_PTR(-err); |
|---|
| 1578 | 1562 | } |
|---|
| 1579 | 1563 | |
|---|
| 1580 | | - evsel = perf_evlist__last(evlist); |
|---|
| 1564 | + evsel = evlist__last(evlist); |
|---|
| 1581 | 1565 | } |
|---|
| 1582 | 1566 | |
|---|
| 1583 | 1567 | bpf__for_each_map_named(map, obj, tmp, name) { |
|---|
| .. | .. |
|---|
| 1603 | 1587 | |
|---|
| 1604 | 1588 | op = bpf_map__add_newop(map, NULL); |
|---|
| 1605 | 1589 | if (IS_ERR(op)) |
|---|
| 1606 | | - return ERR_PTR(PTR_ERR(op)); |
|---|
| 1590 | + return ERR_CAST(op); |
|---|
| 1607 | 1591 | op->op_type = BPF_MAP_OP_SET_EVSEL; |
|---|
| 1608 | 1592 | op->v.evsel = evsel; |
|---|
| 1609 | 1593 | } |
|---|
| .. | .. |
|---|
| 1612 | 1596 | return evsel; |
|---|
| 1613 | 1597 | } |
|---|
| 1614 | 1598 | |
|---|
| 1615 | | -int bpf__setup_stdout(struct perf_evlist *evlist) |
|---|
| 1599 | +int bpf__setup_stdout(struct evlist *evlist) |
|---|
| 1616 | 1600 | { |
|---|
| 1617 | | - struct perf_evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); |
|---|
| 1618 | | - return IS_ERR(evsel) ? PTR_ERR(evsel) : 0; |
|---|
| 1601 | + struct evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__"); |
|---|
| 1602 | + return PTR_ERR_OR_ZERO(evsel); |
|---|
| 1619 | 1603 | } |
|---|
| 1620 | 1604 | |
|---|
| 1621 | 1605 | #define ERRNO_OFFSET(e) ((e) - __BPF_LOADER_ERRNO__START) |
|---|
| .. | .. |
|---|
| 1768 | 1752 | |
|---|
| 1769 | 1753 | int bpf__strerror_config_obj(struct bpf_object *obj __maybe_unused, |
|---|
| 1770 | 1754 | struct parse_events_term *term __maybe_unused, |
|---|
| 1771 | | - struct perf_evlist *evlist __maybe_unused, |
|---|
| 1755 | + struct evlist *evlist __maybe_unused, |
|---|
| 1772 | 1756 | int *error_pos __maybe_unused, int err, |
|---|
| 1773 | 1757 | char *buf, size_t size) |
|---|
| 1774 | 1758 | { |
|---|
| .. | .. |
|---|
| 1792 | 1776 | return 0; |
|---|
| 1793 | 1777 | } |
|---|
| 1794 | 1778 | |
|---|
| 1795 | | -int bpf__strerror_setup_output_event(struct perf_evlist *evlist __maybe_unused, |
|---|
| 1779 | +int bpf__strerror_setup_output_event(struct evlist *evlist __maybe_unused, |
|---|
| 1796 | 1780 | int err, char *buf, size_t size) |
|---|
| 1797 | 1781 | { |
|---|
| 1798 | 1782 | bpf__strerror_head(err, buf, size); |
|---|