Dwarves debugging tools
 help / color / mirror / Atom feed
From: Bill Wendling <morbo@google.com>
To: dwarves@vger.kernel.org
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>,
	Fangrui Song <maskray@google.com>,
	Bill Wendling <morbo@google.com>
Subject: [PATCH 1/1] btf_encoder: Generate a new .BTF section even if one exists
Date: Tue, 22 Nov 2022 00:00:11 +0000	[thread overview]
Message-ID: <20221122000011.241697-2-morbo@google.com> (raw)
In-Reply-To: <20221122000011.241697-1-morbo@google.com>

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.)

Link: https://lore.kernel.org/dwarves/20210317232657.mdnsuoqx6nbddjgt@google.com/
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Fangrui Song <maskray@google.com>
Cc: dwarves@vger.kernel.org
Signed-off-by: Bill Wendling <morbo@google.com>
---
 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


  reply	other threads:[~2022-11-22  0:00 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-22  0:00 [PATCH dwarves 0/1] LLD .BTF section patch Bill Wendling
2022-11-22  0:00 ` Bill Wendling [this message]
2022-11-30 22:59   ` [PATCH 1/1] btf_encoder: Generate a new .BTF section even if one exists Andrii Nakryiko
2022-12-01  0:21     ` Bill Wendling
2022-12-01 19:56       ` Andrii Nakryiko
2022-12-01 20:19         ` Bill Wendling
2022-12-06 18:38           ` Andrii Nakryiko
2022-12-06 18:43             ` Andrii Nakryiko
2022-12-06 20:15             ` Bill Wendling
2022-12-06 22:52               ` Andrii Nakryiko
2022-12-07 20:16                 ` Bill Wendling
2022-12-07 20:33                   ` Andrii Nakryiko
2022-12-15 23:00                     ` Bill Wendling
2022-12-16  0:09                       ` Bill Wendling
2022-12-20 22:00                         ` Andrii Nakryiko
2022-11-28 20:20 ` [PATCH dwarves 0/1] LLD .BTF section patch Bill Wendling

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=20221122000011.241697-2-morbo@google.com \
    --to=morbo@google.com \
    --cc=andrii.nakryiko@gmail.com \
    --cc=dwarves@vger.kernel.org \
    --cc=maskray@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