From: Alan Maguire <alan.maguire@oracle.com>
To: acme@kernel.org, ast@kernel.org, andrii@kernel.org,
daniel@iogearbox.net, quentin@isovalent.com, jolsa@kernel.org
Cc: martin.lau@linux.dev, song@kernel.org, yhs@fb.com,
john.fastabend@gmail.com, kpsingh@kernel.org, sdf@google.com,
haoluo@google.com, mykolal@fb.com, bpf@vger.kernel.org,
Alan Maguire <alan.maguire@oracle.com>
Subject: [PATCH v2 bpf-next 2/9] libbpf: support handling of kind layout section in BTF
Date: Fri, 16 Jun 2023 18:17:20 +0100 [thread overview]
Message-ID: <20230616171728.530116-3-alan.maguire@oracle.com> (raw)
In-Reply-To: <20230616171728.530116-1-alan.maguire@oracle.com>
support reading in kind layout fixing endian issues on reading;
also support writing kind layout section to raw BTF object.
There is not yet an API to populate the kind layout with meaningful
information.
Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
---
tools/lib/bpf/btf.c | 132 +++++++++++++++++++++++++++++++++-----------
1 file changed, 99 insertions(+), 33 deletions(-)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 8484b563b53d..f9f919fdc728 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -39,40 +39,44 @@ struct btf {
/*
* When BTF is loaded from an ELF or raw memory it is stored
- * in a contiguous memory block. The hdr, type_data, and, strs_data
- * point inside that memory region to their respective parts of BTF
- * representation:
+ * in a contiguous memory block. The hdr, type_data, strs_data,
+ * and optional kind layout point inside that memory region to their
+ * respective parts of BTF representation:
*
- * +--------------------------------+
- * | Header | Types | Strings |
- * +--------------------------------+
- * ^ ^ ^
- * | | |
- * hdr | |
- * types_data-+ |
- * strs_data------------+
+ * +--------------------------------+-------------+
+ * | Header | Types | Strings | Kind Layout |
+ * +--------------------------------+-------------+
+ * ^ ^ ^ ^
+ * | | | |
+ * hdr | | |
+ * types_data-+ | |
+ * strs_data------------+ |
+ * kind_layout----------------------+
+ *
+ * kind_layout is optional.
*
* If BTF data is later modified, e.g., due to types added or
* removed, BTF deduplication performed, etc, this contiguous
- * representation is broken up into three independently allocated
- * memory regions to be able to modify them independently.
+ * representation is broken up into three or four independently
+ * allocated memory regions to be able to modify them independently.
* raw_data is nulled out at that point, but can be later allocated
* and cached again if user calls btf__raw_data(), at which point
- * raw_data will contain a contiguous copy of header, types, and
- * strings:
+ * raw_data will contain a contiguous copy of header, types, strings
+ * and (again optionally) kind layout:
*
- * +----------+ +---------+ +-----------+
- * | Header | | Types | | Strings |
- * +----------+ +---------+ +-----------+
- * ^ ^ ^
- * | | |
- * hdr | |
- * types_data----+ |
- * strset__data(strs_set)-----+
+ * +----------+ +---------+ +-----------+ +-------------+
+ * | Header | | Types | | Strings | | Kind layout |
+ * +----------+ +---------+ +-----------+ +-------------+
+ * ^ ^ ^ ^
+ * | | | |
+ * hdr | | |
+ * types_data----+ | |
+ * strset__data(strs_set)-----+ |
+ * kind_layout-------------------------------+
*
- * +----------+---------+-----------+
- * | Header | Types | Strings |
- * raw_data----->+----------+---------+-----------+
+ * +----------+---------+-----------+-------------+
+ * | Header | Types | Strings | Kind Layout |
+ * raw_data----->+----------+---------+-----------+-------------+
*/
struct btf_header *hdr;
@@ -116,6 +120,8 @@ struct btf {
/* whether strings are already deduplicated */
bool strs_deduped;
+ struct btf_kind_layout *kind_layout;
+
/* BTF object FD, if loaded into kernel */
int fd;
@@ -215,6 +221,13 @@ static void btf_bswap_hdr(struct btf_header *h)
h->type_len = bswap_32(h->type_len);
h->str_off = bswap_32(h->str_off);
h->str_len = bswap_32(h->str_len);
+ if (h->hdr_len >= sizeof(struct btf_header)) {
+ h->kind_layout_off = bswap_32(h->kind_layout_off);
+ h->kind_layout_len = bswap_32(h->kind_layout_len);
+ h->crc = bswap_32(h->crc);
+ h->base_crc = bswap_32(h->base_crc);
+ }
+
}
static int btf_parse_hdr(struct btf *btf)
@@ -222,14 +235,17 @@ static int btf_parse_hdr(struct btf *btf)
struct btf_header *hdr = btf->hdr;
__u32 meta_left;
- if (btf->raw_size < sizeof(struct btf_header)) {
+ if (btf->raw_size < BTF_HEADER_MIN_LEN) {
pr_debug("BTF header not found\n");
return -EINVAL;
}
if (hdr->magic == bswap_16(BTF_MAGIC)) {
+ int swapped_len = bswap_32(hdr->hdr_len);
+
btf->swapped_endian = true;
- if (bswap_32(hdr->hdr_len) != sizeof(struct btf_header)) {
+ if (swapped_len != sizeof(struct btf_header) &&
+ swapped_len != BTF_HEADER_MIN_LEN) {
pr_warn("Can't load BTF with non-native endianness due to unsupported header length %u\n",
bswap_32(hdr->hdr_len));
return -ENOTSUP;
@@ -285,6 +301,32 @@ static int btf_parse_str_sec(struct btf *btf)
return 0;
}
+static void btf_bswap_kind_layout_sec(struct btf_kind_layout *k, int len)
+{
+ struct btf_kind_layout *end = (void *)k + len;
+
+ while (k < end) {
+ k->flags = bswap_16(k->flags);
+ k++;
+ }
+}
+
+static int btf_parse_kind_layout_sec(struct btf *btf)
+{
+ const struct btf_header *hdr = btf->hdr;
+
+ if (hdr->hdr_len < sizeof(struct btf_header) ||
+ !hdr->kind_layout_off || !hdr->kind_layout_len)
+ return 0;
+ if (hdr->kind_layout_len < sizeof(struct btf_kind_layout)) {
+ pr_debug("Invalid BTF kind layout section\n");
+ return -EINVAL;
+ }
+ btf->kind_layout = btf->raw_data + btf->hdr->hdr_len + btf->hdr->kind_layout_off;
+
+ return 0;
+}
+
static int btf_type_size(const struct btf_type *t)
{
const int base_size = sizeof(struct btf_type);
@@ -901,6 +943,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf)
btf->types_data = btf->raw_data + btf->hdr->hdr_len + btf->hdr->type_off;
err = btf_parse_str_sec(btf);
+ err = err ?: btf_parse_kind_layout_sec(btf);
err = err ?: btf_parse_type_sec(btf);
if (err)
goto done;
@@ -1267,6 +1310,11 @@ static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endi
}
data_sz = hdr->hdr_len + hdr->type_len + hdr->str_len;
+ if (btf->kind_layout) {
+ data_sz = roundup(data_sz, 4);
+ data_sz += hdr->kind_layout_len;
+ hdr->kind_layout_off = roundup(hdr->type_len + hdr->str_len, 4);
+ }
data = calloc(1, data_sz);
if (!data)
return NULL;
@@ -1293,8 +1341,15 @@ static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endi
p += hdr->type_len;
memcpy(p, btf_strs_data(btf), hdr->str_len);
- p += hdr->str_len;
+ /* round up to 4 byte alignment to match offset above */
+ p = data + hdr->hdr_len + roundup(hdr->type_len + hdr->str_len, 4);
+ if (btf->kind_layout) {
+ memcpy(p, btf->kind_layout, hdr->kind_layout_len);
+ if (swap_endian)
+ btf_bswap_kind_layout_sec(p, hdr->kind_layout_len);
+ p += hdr->kind_layout_len;
+ }
*size = data_sz;
return data;
err_out:
@@ -1425,13 +1480,13 @@ static void btf_invalidate_raw_data(struct btf *btf)
}
}
-/* Ensure BTF is ready to be modified (by splitting into a three memory
- * regions for header, types, and strings). Also invalidate cached
- * raw_data, if any.
+/* Ensure BTF is ready to be modified (by splitting into a three or four memory
+ * regions for header, types, strings and optional kind layout). Also invalidate
+ * cached raw_data, if any.
*/
static int btf_ensure_modifiable(struct btf *btf)
{
- void *hdr, *types;
+ void *hdr, *types, *kind_layout = NULL;
struct strset *set = NULL;
int err = -ENOMEM;
@@ -1446,9 +1501,17 @@ static int btf_ensure_modifiable(struct btf *btf)
types = malloc(btf->hdr->type_len);
if (!hdr || !types)
goto err_out;
+ if (btf->hdr->hdr_len >= sizeof(struct btf_header) &&
+ btf->hdr->kind_layout_off && btf->hdr->kind_layout_len) {
+ kind_layout = calloc(1, btf->hdr->kind_layout_len);
+ if (!kind_layout)
+ goto err_out;
+ }
memcpy(hdr, btf->hdr, btf->hdr->hdr_len);
memcpy(types, btf->types_data, btf->hdr->type_len);
+ if (kind_layout)
+ memcpy(kind_layout, btf->kind_layout, btf->hdr->kind_layout_len);
/* build lookup index for all strings */
set = strset__new(BTF_MAX_STR_OFFSET, btf->strs_data, btf->hdr->str_len);
@@ -1463,6 +1526,8 @@ static int btf_ensure_modifiable(struct btf *btf)
btf->types_data_cap = btf->hdr->type_len;
btf->strs_data = NULL;
btf->strs_set = set;
+ btf->kind_layout = kind_layout;
+
/* if BTF was created from scratch, all strings are guaranteed to be
* unique and deduplicated
*/
@@ -1480,6 +1545,7 @@ static int btf_ensure_modifiable(struct btf *btf)
strset__free(set);
free(hdr);
free(types);
+ free(kind_layout);
return err;
}
--
2.39.3
next prev parent reply other threads:[~2023-06-16 17:18 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-16 17:17 [PATCH v2 bpf-next 0/9] bpf: support BTF kind layout info, CRCs Alan Maguire
2023-06-16 17:17 ` [PATCH v2 bpf-next 1/9] btf: add kind layout encoding, crcs to UAPI Alan Maguire
2023-06-17 0:39 ` Alexei Starovoitov
2023-06-22 22:02 ` Andrii Nakryiko
2023-07-03 13:42 ` Alan Maguire
2023-07-05 23:48 ` Andrii Nakryiko
2023-07-20 20:18 ` Alan Maguire
2023-06-16 17:17 ` Alan Maguire [this message]
2023-06-22 22:02 ` [PATCH v2 bpf-next 2/9] libbpf: support handling of kind layout section in BTF Andrii Nakryiko
2023-06-16 17:17 ` [PATCH v2 bpf-next 3/9] libbpf: use kind layout to compute an unknown kind size Alan Maguire
2023-06-22 22:03 ` Andrii Nakryiko
2023-06-16 17:17 ` [PATCH v2 bpf-next 4/9] btf: support kernel parsing of BTF with kind layout Alan Maguire
2023-06-18 13:08 ` Jiri Olsa
2023-06-20 8:40 ` Alan Maguire
2023-06-22 22:03 ` Andrii Nakryiko
2023-06-16 17:17 ` [PATCH v2 bpf-next 5/9] libbpf: add kind layout encoding, crc support Alan Maguire
2023-06-19 23:24 ` Yonghong Song
2023-06-20 9:09 ` Alan Maguire
2023-06-20 14:41 ` Yonghong Song
2023-06-22 22:04 ` Andrii Nakryiko
2023-06-16 17:17 ` [PATCH v2 bpf-next 6/9] btf: generate BTF kind layout for vmlinux/module BTF Alan Maguire
2023-06-16 18:53 ` kernel test robot
2023-06-18 13:07 ` Jiri Olsa
2023-06-20 8:46 ` Alan Maguire
2023-06-16 17:17 ` [PATCH v2 bpf-next 7/9] bpftool: add BTF dump "format meta" to dump header/metadata Alan Maguire
2023-06-22 22:04 ` Andrii Nakryiko
2023-06-29 14:16 ` Quentin Monnet
2023-06-16 17:17 ` [PATCH v2 bpf-next 8/9] bpftool: update doc to describe bpftool btf dump .. format meta Alan Maguire
2023-06-29 14:16 ` Quentin Monnet
2023-06-16 17:17 ` [PATCH v2 bpf-next 9/9] selftests/bpf: test kind encoding/decoding Alan Maguire
2023-06-22 23:48 ` Andrii Nakryiko
2023-06-16 17:17 ` [PATCH dwarves] dwarves: encode BTF kind layout, crcs Alan Maguire
2023-06-17 0:39 ` [PATCH v2 bpf-next 0/9] bpf: support BTF kind layout info, CRCs Alexei Starovoitov
2023-06-20 8:41 ` Alan Maguire
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230616171728.530116-3-alan.maguire@oracle.com \
--to=alan.maguire@oracle.com \
--cc=acme@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=martin.lau@linux.dev \
--cc=mykolal@fb.com \
--cc=quentin@isovalent.com \
--cc=sdf@google.com \
--cc=song@kernel.org \
--cc=yhs@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).