Skip to content

Commit

Permalink
Merge branch 'change-libbpf-print-api'
Browse files Browse the repository at this point in the history
Yonghong Song says:

====================
These are patches responding to my comments for
Magnus's patch (https://patchwork.ozlabs.org/patch/1032848/).
The goal is to make pr_* macros available to other C files
than libbpf.c, and to simplify API function libbpf_set_print().

Specifically, Patch #1 used global functions
to facilitate pr_* macros in the header files so they
are available in different C files.
Patch #2 removes the global function libbpf_print_level_available()
which is added in Patch 1.
Patch #3 simplified libbpf_set_print() which takes only one print
function with a debug level argument among others.

Changelogs:
 v3 -> v4:
   . rename libbpf internal header util.h to libbpf_util.h
   . rename libbpf internal function libbpf_debug_print() to libbpf_print()
 v2 -> v3:
   . bailed out earlier in libbpf_debug_print() if __libbpf_pr is NULL
   . added missing LIBBPF_DEBUG level check in libbpf.c __base_pr().
 v1 -> v2:
   . Renamed global function libbpf_dprint() to libbpf_debug_print()
     to be more expressive.
   . Removed libbpf_dprint_level_available() as it is used only
     once in btf.c and we can remove it by optimizing for common cases.
====================

Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Alexei Starovoitov committed Feb 4, 2019
2 parents cc73357 + 6f1ae8b commit 9fa3b47
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 142 deletions.
110 changes: 53 additions & 57 deletions tools/lib/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
#include <linux/btf.h>
#include "btf.h"
#include "bpf.h"
#include "libbpf.h"
#include "libbpf_util.h"

#define elog(fmt, ...) { if (err_log) err_log(fmt, ##__VA_ARGS__); }
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))

Expand Down Expand Up @@ -107,54 +108,54 @@ static int btf_add_type(struct btf *btf, struct btf_type *t)
return 0;
}

static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log)
static int btf_parse_hdr(struct btf *btf)
{
const struct btf_header *hdr = btf->hdr;
__u32 meta_left;

if (btf->data_size < sizeof(struct btf_header)) {
elog("BTF header not found\n");
pr_debug("BTF header not found\n");
return -EINVAL;
}

if (hdr->magic != BTF_MAGIC) {
elog("Invalid BTF magic:%x\n", hdr->magic);
pr_debug("Invalid BTF magic:%x\n", hdr->magic);
return -EINVAL;
}

if (hdr->version != BTF_VERSION) {
elog("Unsupported BTF version:%u\n", hdr->version);
pr_debug("Unsupported BTF version:%u\n", hdr->version);
return -ENOTSUP;
}

if (hdr->flags) {
elog("Unsupported BTF flags:%x\n", hdr->flags);
pr_debug("Unsupported BTF flags:%x\n", hdr->flags);
return -ENOTSUP;
}

meta_left = btf->data_size - sizeof(*hdr);
if (!meta_left) {
elog("BTF has no data\n");
pr_debug("BTF has no data\n");
return -EINVAL;
}

if (meta_left < hdr->type_off) {
elog("Invalid BTF type section offset:%u\n", hdr->type_off);
pr_debug("Invalid BTF type section offset:%u\n", hdr->type_off);
return -EINVAL;
}

if (meta_left < hdr->str_off) {
elog("Invalid BTF string section offset:%u\n", hdr->str_off);
pr_debug("Invalid BTF string section offset:%u\n", hdr->str_off);
return -EINVAL;
}

if (hdr->type_off >= hdr->str_off) {
elog("BTF type section offset >= string section offset. No type?\n");
pr_debug("BTF type section offset >= string section offset. No type?\n");
return -EINVAL;
}

if (hdr->type_off & 0x02) {
elog("BTF type section is not aligned to 4 bytes\n");
pr_debug("BTF type section is not aligned to 4 bytes\n");
return -EINVAL;
}

Expand All @@ -163,15 +164,15 @@ static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log)
return 0;
}

static int btf_parse_str_sec(struct btf *btf, btf_print_fn_t err_log)
static int btf_parse_str_sec(struct btf *btf)
{
const struct btf_header *hdr = btf->hdr;
const char *start = btf->nohdr_data + hdr->str_off;
const char *end = start + btf->hdr->str_len;

if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_NAME_OFFSET ||
start[0] || end[-1]) {
elog("Invalid BTF string section\n");
pr_debug("Invalid BTF string section\n");
return -EINVAL;
}

Expand All @@ -180,7 +181,7 @@ static int btf_parse_str_sec(struct btf *btf, btf_print_fn_t err_log)
return 0;
}

static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)
static int btf_parse_type_sec(struct btf *btf)
{
struct btf_header *hdr = btf->hdr;
void *nohdr_data = btf->nohdr_data;
Expand Down Expand Up @@ -219,7 +220,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)
case BTF_KIND_RESTRICT:
break;
default:
elog("Unsupported BTF_KIND:%u\n",
pr_debug("Unsupported BTF_KIND:%u\n",
BTF_INFO_KIND(t->info));
return -EINVAL;
}
Expand Down Expand Up @@ -363,7 +364,7 @@ void btf__free(struct btf *btf)
free(btf);
}

struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log)
struct btf *btf__new(__u8 *data, __u32 size)
{
__u32 log_buf_size = 0;
char *log_buf = NULL;
Expand All @@ -376,16 +377,15 @@ struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log)

btf->fd = -1;

if (err_log) {
log_buf = malloc(BPF_LOG_BUF_SIZE);
if (!log_buf) {
err = -ENOMEM;
goto done;
}
*log_buf = 0;
log_buf_size = BPF_LOG_BUF_SIZE;
log_buf = malloc(BPF_LOG_BUF_SIZE);
if (!log_buf) {
err = -ENOMEM;
goto done;
}

*log_buf = 0;
log_buf_size = BPF_LOG_BUF_SIZE;

btf->data = malloc(size);
if (!btf->data) {
err = -ENOMEM;
Expand All @@ -400,21 +400,21 @@ struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log)

if (btf->fd == -1) {
err = -errno;
elog("Error loading BTF: %s(%d)\n", strerror(errno), errno);
pr_warning("Error loading BTF: %s(%d)\n", strerror(errno), errno);
if (log_buf && *log_buf)
elog("%s\n", log_buf);
pr_warning("%s\n", log_buf);
goto done;
}

err = btf_parse_hdr(btf, err_log);
err = btf_parse_hdr(btf);
if (err)
goto done;

err = btf_parse_str_sec(btf, err_log);
err = btf_parse_str_sec(btf);
if (err)
goto done;

err = btf_parse_type_sec(btf, err_log);
err = btf_parse_type_sec(btf);

done:
free(log_buf);
Expand Down Expand Up @@ -491,7 +491,7 @@ int btf__get_from_id(__u32 id, struct btf **btf)
goto exit_free;
}

*btf = btf__new((__u8 *)(long)btf_info.btf, btf_info.btf_size, NULL);
*btf = btf__new((__u8 *)(long)btf_info.btf, btf_info.btf_size);
if (IS_ERR(*btf)) {
err = PTR_ERR(*btf);
*btf = NULL;
Expand All @@ -514,8 +514,7 @@ struct btf_ext_sec_copy_param {

static int btf_ext_copy_info(struct btf_ext *btf_ext,
__u8 *data, __u32 data_size,
struct btf_ext_sec_copy_param *ext_sec,
btf_print_fn_t err_log)
struct btf_ext_sec_copy_param *ext_sec)
{
const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
const struct btf_ext_info_sec *sinfo;
Expand All @@ -529,14 +528,14 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
data_size -= hdr->hdr_len;

if (ext_sec->off & 0x03) {
elog(".BTF.ext %s section is not aligned to 4 bytes\n",
pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n",
ext_sec->desc);
return -EINVAL;
}

if (data_size < ext_sec->off ||
ext_sec->len > data_size - ext_sec->off) {
elog("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n",
pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n",
ext_sec->desc, ext_sec->off, ext_sec->len);
return -EINVAL;
}
Expand All @@ -546,15 +545,15 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,

/* At least a record size */
if (info_left < sizeof(__u32)) {
elog(".BTF.ext %s record size not found\n", ext_sec->desc);
pr_debug(".BTF.ext %s record size not found\n", ext_sec->desc);
return -EINVAL;
}

/* The record size needs to meet the minimum standard */
record_size = *(__u32 *)info;
if (record_size < ext_sec->min_rec_size ||
record_size & 0x03) {
elog("%s section in .BTF.ext has invalid record size %u\n",
pr_debug("%s section in .BTF.ext has invalid record size %u\n",
ext_sec->desc, record_size);
return -EINVAL;
}
Expand All @@ -564,7 +563,7 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,

/* If no records, return failure now so .BTF.ext won't be used. */
if (!info_left) {
elog("%s section in .BTF.ext has no records", ext_sec->desc);
pr_debug("%s section in .BTF.ext has no records", ext_sec->desc);
return -EINVAL;
}

Expand All @@ -574,22 +573,22 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
__u32 num_records;

if (info_left < sec_hdrlen) {
elog("%s section header is not found in .BTF.ext\n",
pr_debug("%s section header is not found in .BTF.ext\n",
ext_sec->desc);
return -EINVAL;
}

num_records = sinfo->num_info;
if (num_records == 0) {
elog("%s section has incorrect num_records in .BTF.ext\n",
pr_debug("%s section has incorrect num_records in .BTF.ext\n",
ext_sec->desc);
return -EINVAL;
}

total_record_size = sec_hdrlen +
(__u64)num_records * record_size;
if (info_left < total_record_size) {
elog("%s section has incorrect num_records in .BTF.ext\n",
pr_debug("%s section has incorrect num_records in .BTF.ext\n",
ext_sec->desc);
return -EINVAL;
}
Expand All @@ -610,8 +609,7 @@ static int btf_ext_copy_info(struct btf_ext *btf_ext,
}

static int btf_ext_copy_func_info(struct btf_ext *btf_ext,
__u8 *data, __u32 data_size,
btf_print_fn_t err_log)
__u8 *data, __u32 data_size)
{
const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
struct btf_ext_sec_copy_param param = {
Expand All @@ -622,12 +620,11 @@ static int btf_ext_copy_func_info(struct btf_ext *btf_ext,
.desc = "func_info"
};

return btf_ext_copy_info(btf_ext, data, data_size, &param, err_log);
return btf_ext_copy_info(btf_ext, data, data_size, &param);
}

static int btf_ext_copy_line_info(struct btf_ext *btf_ext,
__u8 *data, __u32 data_size,
btf_print_fn_t err_log)
__u8 *data, __u32 data_size)
{
const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
struct btf_ext_sec_copy_param param = {
Expand All @@ -638,37 +635,36 @@ static int btf_ext_copy_line_info(struct btf_ext *btf_ext,
.desc = "line_info",
};

return btf_ext_copy_info(btf_ext, data, data_size, &param, err_log);
return btf_ext_copy_info(btf_ext, data, data_size, &param);
}

static int btf_ext_parse_hdr(__u8 *data, __u32 data_size,
btf_print_fn_t err_log)
static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
{
const struct btf_ext_header *hdr = (struct btf_ext_header *)data;

if (data_size < offsetof(struct btf_ext_header, func_info_off) ||
data_size < hdr->hdr_len) {
elog("BTF.ext header not found");
pr_debug("BTF.ext header not found");
return -EINVAL;
}

if (hdr->magic != BTF_MAGIC) {
elog("Invalid BTF.ext magic:%x\n", hdr->magic);
pr_debug("Invalid BTF.ext magic:%x\n", hdr->magic);
return -EINVAL;
}

if (hdr->version != BTF_VERSION) {
elog("Unsupported BTF.ext version:%u\n", hdr->version);
pr_debug("Unsupported BTF.ext version:%u\n", hdr->version);
return -ENOTSUP;
}

if (hdr->flags) {
elog("Unsupported BTF.ext flags:%x\n", hdr->flags);
pr_debug("Unsupported BTF.ext flags:%x\n", hdr->flags);
return -ENOTSUP;
}

if (data_size == hdr->hdr_len) {
elog("BTF.ext has no data\n");
pr_debug("BTF.ext has no data\n");
return -EINVAL;
}

Expand All @@ -685,26 +681,26 @@ void btf_ext__free(struct btf_ext *btf_ext)
free(btf_ext);
}

struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log)
struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
{
struct btf_ext *btf_ext;
int err;

err = btf_ext_parse_hdr(data, size, err_log);
err = btf_ext_parse_hdr(data, size);
if (err)
return ERR_PTR(err);

btf_ext = calloc(1, sizeof(struct btf_ext));
if (!btf_ext)
return ERR_PTR(-ENOMEM);

err = btf_ext_copy_func_info(btf_ext, data, size, err_log);
err = btf_ext_copy_func_info(btf_ext, data, size);
if (err) {
btf_ext__free(btf_ext);
return ERR_PTR(err);
}

err = btf_ext_copy_line_info(btf_ext, data, size, err_log);
err = btf_ext_copy_line_info(btf_ext, data, size);
if (err) {
btf_ext__free(btf_ext);
return ERR_PTR(err);
Expand Down
7 changes: 2 additions & 5 deletions tools/lib/bpf/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,8 @@ struct btf_ext_header {
__u32 line_info_len;
};

typedef int (*btf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2)));

LIBBPF_API void btf__free(struct btf *btf);
LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size);
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
const char *type_name);
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
Expand All @@ -70,7 +67,7 @@ LIBBPF_API int btf__fd(const struct btf *btf);
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);

struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
void btf_ext__free(struct btf_ext *btf_ext);
int btf_ext__reloc_func_info(const struct btf *btf,
const struct btf_ext *btf_ext,
Expand Down
Loading

0 comments on commit 9fa3b47

Please sign in to comment.