Skip to content

Commit

Permalink
tools/bpf: move libbpf pr_* debug print functions to headers
Browse files Browse the repository at this point in the history
A global function libbpf_print, which is invisible
outside the shared library, is defined to print based
on levels. The pr_warning, pr_info and pr_debug
macros are moved into the newly created header
common.h. So any .c file including common.h can
use these macros directly.

Currently btf__new and btf_ext__new API has an argument getting
__pr_debug function pointer into btf.c so the debugging information
can be printed there. This patch removed this parameter
from btf__new and btf_ext__new and directly using pr_debug in btf.c.

Another global function libbpf_print_level_available, also
invisible outside the shared library, can test
whether a particular level debug printing is
available or not. It is used in btf.c to
test whether DEBUG level debug printing is availabl or not,
based on which the log buffer will be allocated when loading
btf to the kernel.

Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Yonghong Song authored and Alexei Starovoitov committed Feb 4, 2019
1 parent cc73357 commit 8461ef8
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 70 deletions.
97 changes: 47 additions & 50 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,7 +377,7 @@ struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log)

btf->fd = -1;

if (err_log) {
if (libbpf_print_level_available(LIBBPF_DEBUG)) {
log_buf = malloc(BPF_LOG_BUF_SIZE);
if (!log_buf) {
err = -ENOMEM;
Expand All @@ -400,21 +401,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_debug("Error loading BTF: %s(%d)\n", strerror(errno), errno);
if (log_buf && *log_buf)
elog("%s\n", log_buf);
pr_debug("%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 +492,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 +515,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 +529,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 +546,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 +564,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 +574,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 +610,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 +621,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 +636,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 +682,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 8461ef8

Please sign in to comment.