sync with latest bpf-next

The following three files are added:
  libbpf_probes.c
  libbpf_util.h
  libbpf.map

Signed-off-by: Yonghong Song <yhs@fb.com>
This commit is contained in:
Yonghong Song
2019-02-04 13:28:44 -08:00
parent d5b146fec5
commit 1dc0296fce
11 changed files with 798 additions and 177 deletions

View File

@@ -42,6 +42,7 @@
#include "bpf.h"
#include "btf.h"
#include "str_error.h"
#include "libbpf_util.h"
#ifndef EM_BPF
#define EM_BPF 247
@@ -53,39 +54,39 @@
#define __printf(a, b) __attribute__((format(printf, a, b)))
__printf(1, 2)
static int __base_pr(const char *format, ...)
__printf(2, 3)
static int __base_pr(enum libbpf_print_level level, const char *format, ...)
{
va_list args;
int err;
if (level == LIBBPF_DEBUG)
return 0;
va_start(args, format);
err = vfprintf(stderr, format, args);
va_end(args);
return err;
}
static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_debug;
static __printf(2, 3) libbpf_print_fn_t __libbpf_pr = __base_pr;
#define __pr(func, fmt, ...) \
do { \
if ((func)) \
(func)("libbpf: " fmt, ##__VA_ARGS__); \
} while (0)
#define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__)
#define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__)
#define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__)
void libbpf_set_print(libbpf_print_fn_t warn,
libbpf_print_fn_t info,
libbpf_print_fn_t debug)
void libbpf_set_print(libbpf_print_fn_t fn)
{
__pr_warning = warn;
__pr_info = info;
__pr_debug = debug;
__libbpf_pr = fn;
}
__printf(2, 3)
void libbpf_print(enum libbpf_print_level level, const char *format, ...)
{
va_list args;
if (!__libbpf_pr)
return;
va_start(args, format);
__libbpf_pr(level, format, args);
va_end(args);
}
#define STRERR_BUFSIZE 128
@@ -839,8 +840,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
else if (strcmp(name, "maps") == 0)
obj->efile.maps_shndx = idx;
else if (strcmp(name, BTF_ELF_SEC) == 0) {
obj->btf = btf__new(data->d_buf, data->d_size,
__pr_debug);
obj->btf = btf__new(data->d_buf, data->d_size);
if (IS_ERR(obj->btf)) {
pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
BTF_ELF_SEC, PTR_ERR(obj->btf));
@@ -915,8 +915,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
BTF_EXT_ELF_SEC, BTF_ELF_SEC);
} else {
obj->btf_ext = btf_ext__new(btf_ext_data->d_buf,
btf_ext_data->d_size,
__pr_debug);
btf_ext_data->d_size);
if (IS_ERR(obj->btf_ext)) {
pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
BTF_EXT_ELF_SEC,
@@ -1057,72 +1056,18 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf)
{
const struct btf_type *container_type;
const struct btf_member *key, *value;
struct bpf_map_def *def = &map->def;
const size_t max_name = 256;
char container_name[max_name];
__s64 key_size, value_size;
__s32 container_id;
__u32 key_type_id, value_type_id;
int ret;
if (snprintf(container_name, max_name, "____btf_map_%s", map->name) ==
max_name) {
pr_warning("map:%s length of '____btf_map_%s' is too long\n",
map->name, map->name);
return -EINVAL;
}
ret = btf__get_map_kv_tids(btf, map->name, def->key_size,
def->value_size, &key_type_id,
&value_type_id);
if (ret)
return ret;
container_id = btf__find_by_name(btf, container_name);
if (container_id < 0) {
pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
map->name, container_name);
return container_id;
}
container_type = btf__type_by_id(btf, container_id);
if (!container_type) {
pr_warning("map:%s cannot find BTF type for container_id:%u\n",
map->name, container_id);
return -EINVAL;
}
if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
BTF_INFO_VLEN(container_type->info) < 2) {
pr_warning("map:%s container_name:%s is an invalid container struct\n",
map->name, container_name);
return -EINVAL;
}
key = (struct btf_member *)(container_type + 1);
value = key + 1;
key_size = btf__resolve_size(btf, key->type);
if (key_size < 0) {
pr_warning("map:%s invalid BTF key_type_size\n",
map->name);
return key_size;
}
if (def->key_size != key_size) {
pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
map->name, (__u32)key_size, def->key_size);
return -EINVAL;
}
value_size = btf__resolve_size(btf, value->type);
if (value_size < 0) {
pr_warning("map:%s invalid BTF value_type_size\n", map->name);
return value_size;
}
if (def->value_size != value_size) {
pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
map->name, (__u32)value_size, def->value_size);
return -EINVAL;
}
map->btf_key_type_id = key->type;
map->btf_value_type_id = value->type;
map->btf_key_type_id = key_type_id;
map->btf_value_type_id = value_type_id;
return 0;
}
@@ -2667,9 +2612,38 @@ static const struct {
#undef BPF_EAPROG_SEC
#undef BPF_APROG_COMPAT
#define MAX_TYPE_NAME_SIZE 32
static char *libbpf_get_type_names(bool attach_type)
{
int i, len = ARRAY_SIZE(section_names) * MAX_TYPE_NAME_SIZE;
char *buf;
buf = malloc(len);
if (!buf)
return NULL;
buf[0] = '\0';
/* Forge string buf with all available names */
for (i = 0; i < ARRAY_SIZE(section_names); i++) {
if (attach_type && !section_names[i].is_attachable)
continue;
if (strlen(buf) + strlen(section_names[i].sec) + 2 > len) {
free(buf);
return NULL;
}
strcat(buf, " ");
strcat(buf, section_names[i].sec);
}
return buf;
}
int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
enum bpf_attach_type *expected_attach_type)
{
char *type_names;
int i;
if (!name)
@@ -2682,12 +2656,20 @@ int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type,
*expected_attach_type = section_names[i].expected_attach_type;
return 0;
}
pr_warning("failed to guess program type based on ELF section name '%s'\n", name);
type_names = libbpf_get_type_names(false);
if (type_names != NULL) {
pr_info("supported section(type) names are:%s\n", type_names);
free(type_names);
}
return -EINVAL;
}
int libbpf_attach_type_by_name(const char *name,
enum bpf_attach_type *attach_type)
{
char *type_names;
int i;
if (!name)
@@ -2701,6 +2683,13 @@ int libbpf_attach_type_by_name(const char *name,
*attach_type = section_names[i].attach_type;
return 0;
}
pr_warning("failed to guess attach type based on ELF section name '%s'\n", name);
type_names = libbpf_get_type_names(true);
if (type_names != NULL) {
pr_info("attachable section(type) names are:%s\n", type_names);
free(type_names);
}
return -EINVAL;
}
@@ -2840,6 +2829,12 @@ bpf_object__find_map_by_name(struct bpf_object *obj, const char *name)
return NULL;
}
int
bpf_object__find_map_fd_by_name(struct bpf_object *obj, const char *name)
{
return bpf_map__fd(bpf_object__find_map_by_name(obj, name));
}
struct bpf_map *
bpf_object__find_map_by_offset(struct bpf_object *obj, size_t offset)
{
@@ -2907,8 +2902,6 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
err = bpf_program__identify_section(prog, &prog_type,
&expected_attach_type);
if (err < 0) {
pr_warning("failed to guess program type based on section name %s\n",
prog->section_name);
bpf_object__close(obj);
return -EINVAL;
}