On Wed, Nov 30, 2022 at 2:59 PM Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> wrote: > > On Mon, Nov 21, 2022 at 4:00 PM Bill Wendling <morbo@xxxxxxxxxx> wrote: > > > > LLD generates a zero-length .BTF section (BFD doesn't generate this > > section). It shares the same address as .BTF_ids (or any section below > > it). E.g.: > > > > [24] .BTF PROGBITS ffffffff825a1900 17a1900 000000 > > [25] .BTF_ids PROGBITS ffffffff825a1900 17a1900 000634 > > > > Writing new data to that section doesn't adjust the addresses of > > following sections. As a result, the "-J" flag produces a corrupted > > file, causing further commands to fail. > > > > Instead of trying to adjust everything, just add a new section with the > > .BTF data and adjust the name of the original .BTF section. (We can't > > remove the old .BTF section because it has variables that are referenced > > elsewhere.) > > > > Have you tried llvm-objcopy --update-section instead? Doesn't it work? > I gave it a quick try and it fails for me with this: llvm-objcopy: error: '.tmp_vmlinux.btf': cannot fit data of size 4470718 into section '.BTF' with size 0 that is part of a segment btf_encoder__write_elf: failed to add .BTF section to '.tmp_vmlinux.btf': 2! Failed to encode BTF -bw > > Link: https://lore.kernel.org/dwarves/20210317232657.mdnsuoqx6nbddjgt@xxxxxxxxxx/ > > Cc: Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> > > Cc: Fangrui Song <maskray@xxxxxxxxxx> > > Cc: dwarves@xxxxxxxxxxxxxxx > > Signed-off-by: Bill Wendling <morbo@xxxxxxxxxx> > > --- > > btf_encoder.c | 88 +++++++++++++++++++++++++++++++-------------------- > > 1 file changed, 54 insertions(+), 34 deletions(-) > > > > diff --git a/btf_encoder.c b/btf_encoder.c > > index a5fa04a84ee2..bd1ce63e992c 100644 > > --- a/btf_encoder.c > > +++ b/btf_encoder.c > > @@ -1039,6 +1039,9 @@ static int btf_encoder__write_elf(struct btf_encoder *encoder) > > Elf_Data *btf_data = NULL; > > Elf_Scn *scn = NULL; > > Elf *elf = NULL; > > + const char *llvm_objcopy; > > + char tmp_fn[PATH_MAX]; > > + char cmd[PATH_MAX * 2]; > > const void *raw_btf_data; > > uint32_t raw_btf_size; > > int fd, err = -1; > > @@ -1081,42 +1084,58 @@ static int btf_encoder__write_elf(struct btf_encoder *encoder) > > > > raw_btf_data = btf__raw_data(btf, &raw_btf_size); > > > > + 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); > > + 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; > > + } > > + > > if (btf_data) { > > - /* Existing .BTF section found */ > > - btf_data->d_buf = (void *)raw_btf_data; > > - btf_data->d_size = raw_btf_size; > > - elf_flagdata(btf_data, ELF_C_SET, ELF_F_DIRTY); > > - > > - if (elf_update(elf, ELF_C_NULL) >= 0 && > > - elf_update(elf, ELF_C_WRITE) >= 0) > > - err = 0; > > - else > > - elf_error("elf_update failed"); > > - } else { > > - 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); > > - 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); > > + /* > > + * Existing .BTF section found. LLD creates a zero-sized .BTF > > + * section. Adding data to that section doesn't change the > > + * addresses of the other sections, causing an overwriting of > > + * data. These commands are a bit convoluted, but they will add > > + * a new .BTF section with the proper size. Note though that > > + * the __start_btf and __stop_btf variables aren't affected by > > + * this change, but then they aren't added when using > > + * "--add-section" either. > > + */ > > + snprintf(cmd, sizeof(cmd), > > + "%s --add-section .BTF.new=%s " > > + "--rename-section .BTF=.BTF.old %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; > > } > > > > + snprintf(cmd, sizeof(cmd), > > + "%s --rename-section .BTF.new=.BTF %s", > > + llvm_objcopy, filename); > > + if (system(cmd)) { > > + fprintf(stderr, "%s: failed to rename .BTF section to '%s': %d!\n", > > + __func__, filename, errno); > > + goto unlink; > > + } > > + > > + err = 0; > > + } else { > > snprintf(cmd, sizeof(cmd), "%s --add-section .BTF=%s %s", > > llvm_objcopy, tmp_fn, filename); > > if (system(cmd)) { > > @@ -1126,10 +1145,11 @@ static int btf_encoder__write_elf(struct btf_encoder *encoder) > > } > > > > err = 0; > > - unlink: > > - unlink(tmp_fn); > > } > > > > +unlink: > > + unlink(tmp_fn); > > + > > out: > > if (fd != -1) > > close(fd); > > -- > > 2.38.1.584.g0f3c55d4c2-goog > >