From: Jiri Olsa <jolsa@redhat.com>
To: Giuliano Procida <gprocida@google.com>
Cc: dwarves@vger.kernel.org, acme@kernel.org, andrii@kernel.org,
ast@kernel.org, maennich@google.com, kernel-team@android.com,
kernel-team@fb.com, bpf@vger.kernel.org
Subject: Re: [PATCH dwarves 2/4] btf_encoder: Add .BTF section using libelf
Date: Thu, 28 Jan 2021 00:23:20 +0100 [thread overview]
Message-ID: <20210127232320.GA295637@krava> (raw)
In-Reply-To: <20210125130625.2030186-3-gprocida@google.com>
On Mon, Jan 25, 2021 at 01:06:23PM +0000, Giuliano Procida wrote:
> pahole -J uses libelf directly when updating a .BTF section. However,
> it uses llvm-objcopy to add .BTF sections. This commit switches to
> using libelf for both cases.
>
> This eliminates pahole's dependency on llvm-objcopy. One unfortunate
> side-effect is that vmlinux actually increases in size. It seems that
> llvm-objcopy modifies the .strtab section, discarding many strings. I
> speculate that is it discarding strings not referenced from .symtab
> and updating the references therein.
>
> In this initial version layout is left completely up to libelf which
> may be OK for non-loadable object files, but is probably no good for
> things like vmlinux where all the offsets may change. This is
> addressed in a follow-up commit.
>
> Signed-off-by: Giuliano Procida <gprocida@google.com>
> ---
> libbtf.c | 145 ++++++++++++++++++++++++++++++++++++++-----------------
> 1 file changed, 100 insertions(+), 45 deletions(-)
>
> diff --git a/libbtf.c b/libbtf.c
> index 9f76283..fb8e043 100644
> --- a/libbtf.c
> +++ b/libbtf.c
> @@ -699,6 +699,7 @@ static int btf_elf__write(const char *filename, struct btf *btf)
> uint32_t raw_btf_size;
> int fd, err = -1;
> size_t strndx;
> + void *str_table = NULL;
>
> fd = open(filename, O_RDWR);
> if (fd < 0) {
> @@ -741,74 +742,128 @@ static int btf_elf__write(const char *filename, struct btf *btf)
> }
>
> /*
> - * First we look if there was already a .BTF section to overwrite.
> + * First we check if there is already a .BTF section present.
> */
> -
> elf_getshdrstrndx(elf, &strndx);
> + Elf_Scn *btf_scn = 0;
NULL
SNIP
> - const char *llvm_objcopy;
> - char tmp_fn[PATH_MAX];
> - char cmd[PATH_MAX * 2];
> -
> - llvm_objcopy = getenv("LLVM_OBJCOPY");
> - if (!llvm_objcopy)
> - llvm_objcopy = "llvm-objcopy";
> -
> - /* Use objcopy to add a .BTF section */
> - snprintf(tmp_fn, sizeof(tmp_fn), "%s.btf", filename);
> - close(fd);
> - fd = creat(tmp_fn, S_IRUSR | S_IWUSR);
> - if (fd == -1) {
> - fprintf(stderr, "%s: open(%s) failed!\n", __func__,
> - tmp_fn);
> + /* Add ".BTF" to the section name string table */
> + Elf_Data *str_data = elf_getdata(str_scn, NULL);
> + if (!str_data) {
> + fprintf(stderr, "%s: elf_getdata(str_scn) failed: %s\n",
> + __func__, elf_errmsg(elf_errno()));
> goto out;
> }
> -
> - if (write(fd, raw_btf_data, raw_btf_size) != raw_btf_size) {
> - fprintf(stderr, "%s: write of %d bytes to '%s' failed: %d!\n",
> - __func__, raw_btf_size, tmp_fn, errno);
> - goto unlink;
> + dot_btf_offset = str_data->d_size;
> + size_t new_str_size = dot_btf_offset + 5;
> + str_table = malloc(new_str_size);
> + if (!str_table) {
> + fprintf(stderr, "%s: malloc(%zu) failed: %s\n", __func__,
> + new_str_size, elf_errmsg(elf_errno()));
> + goto out;
> }
> + memcpy(str_table, str_data->d_buf, dot_btf_offset);
> + memcpy(str_table + dot_btf_offset, ".BTF", 5);
hum, I wonder this will always copy the final zero byte
> + str_data->d_buf = str_table;
> + str_data->d_size = new_str_size;
> + elf_flagdata(str_data, ELF_C_SET, ELF_F_DIRTY);
> +
> + /* Create a new section */
> + btf_scn = elf_newscn(elf);
> + if (!btf_scn) {
> + fprintf(stderr, "%s: elf_newscn failed: %s\n",
> + __func__, elf_errmsg(elf_errno()));
> + goto out;
> + }
> + btf_data = elf_newdata(btf_scn);
> + if (!btf_data) {
> + fprintf(stderr, "%s: elf_newdata failed: %s\n",
> + __func__, elf_errmsg(elf_errno()));
> + goto out;
> + }
> + }
>
> - snprintf(cmd, sizeof(cmd), "%s --add-section .BTF=%s %s",
> - llvm_objcopy, tmp_fn, filename);
> - if (system(cmd)) {
> - fprintf(stderr, "%s: failed to add .BTF section to '%s': %d!\n",
> - __func__, filename, errno);
> - goto unlink;
> + /* (Re)populate the BTF section data */
> + raw_btf_data = btf__get_raw_data(btf, &raw_btf_size);
> + btf_data->d_buf = (void *)raw_btf_data;
doesn't this potentially leak btf_data->d_buf?
> + btf_data->d_size = raw_btf_size;
> + btf_data->d_type = ELF_T_BYTE;
> + btf_data->d_version = EV_CURRENT;
> + elf_flagdata(btf_data, ELF_C_SET, ELF_F_DIRTY);
> +
> + /* Update .BTF section in the SHT */
> + GElf_Shdr btf_shdr_mem;
> + GElf_Shdr *btf_shdr = gelf_getshdr(btf_scn, &btf_shdr_mem);
> + if (!btf_shdr) {
> + fprintf(stderr, "%s: elf_getshdr(btf_scn) failed: %s\n",
> + __func__, elf_errmsg(elf_errno()));
> + goto out;
> + }
> + btf_shdr->sh_entsize = 0;
> + btf_shdr->sh_flags = 0;
> + if (dot_btf_offset)
> + btf_shdr->sh_name = dot_btf_offset;
> + btf_shdr->sh_type = SHT_PROGBITS;
> + if (!gelf_update_shdr(btf_scn, btf_shdr)) {
> + fprintf(stderr, "%s: gelf_update_shdr failed: %s\n",
> + __func__, elf_errmsg(elf_errno()));
> + goto out;
> + }
> +
> + if (elf_update(elf, ELF_C_NULL) < 0) {
> + fprintf(stderr, "%s: elf_update (layout) failed: %s\n",
> + __func__, elf_errmsg(elf_errno()));
> + goto out;
> + }
> +
> + size_t phnum = 0;
> + if (!elf_getphdrnum(elf, &phnum)) {
> + for (size_t ix = 0; ix < phnum; ++ix) {
> + GElf_Phdr phdr;
> + GElf_Phdr *elf_phdr = gelf_getphdr(elf, ix, &phdr);
> + size_t filesz = gelf_fsize(elf, ELF_T_PHDR, 1, EV_CURRENT);
> + fprintf(stderr, "type: %d %d\n", elf_phdr->p_type, PT_PHDR);
> + fprintf(stderr, "offset: %lu %lu\n", elf_phdr->p_offset, ehdr->e_phoff);
> + fprintf(stderr, "filesize: %lu %lu\n", elf_phdr->p_filesz, filesz);
looks like s forgotten debug or you're missing
btf_elf__verbose check for fprintf calls above
jirka
next prev parent reply other threads:[~2021-01-27 23:27 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-25 13:06 [PATCH dwarves 0/4] BTF ELF writing changes Giuliano Procida
2021-01-25 13:06 ` [PATCH dwarves 1/4] btf_encoder: Improve ELF error reporting Giuliano Procida
2021-01-25 13:06 ` [PATCH dwarves 2/4] btf_encoder: Add .BTF section using libelf Giuliano Procida
2021-01-27 23:23 ` Jiri Olsa [this message]
2021-01-28 13:35 ` Giuliano Procida
2021-02-05 13:40 ` Giuliano Procida
2021-01-25 13:06 ` [PATCH dwarves 3/4] btf_encoder: Manually lay out updated ELF sections Giuliano Procida
2021-01-25 13:06 ` [PATCH dwarves 4/4] btf_encoder: Align .BTF section to 8 bytes Giuliano Procida
2021-01-26 19:55 ` [PATCH dwarves 0/4] BTF ELF writing changes Jiri Olsa
2021-01-27 1:10 ` Giuliano Procida
2021-01-27 1:42 ` Arnaldo Carvalho de Melo
2021-01-27 14:06 ` Arnaldo Carvalho de Melo
2021-01-27 14:36 ` Giuliano Procida
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=20210127232320.GA295637@krava \
--to=jolsa@redhat.com \
--cc=acme@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=dwarves@vger.kernel.org \
--cc=gprocida@google.com \
--cc=kernel-team@android.com \
--cc=kernel-team@fb.com \
--cc=maennich@google.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).