From: Longjun Luo <luolongjuna@gmail.com>
To: jpoimboe@kernel.org, peterz@infradead.org
Cc: mbenes@suse.cz, pmladek@suse.com, joe.lawrence@redhat.com,
song@kernel.org, puranjay@kernel.org, nathan@kernel.org,
ndesaulniers@google.com, morbo@google.com,
justinstitt@google.com, live-patching@vger.kernel.org,
llvm@lists.linux.dev, linux-kernel@vger.kernel.org,
Longjun Luo <luolongjuna@gmail.com>
Subject: [RFC PATCH v2 05/11] objtool/klp: Support reduced and split DWARF
Date: Wed, 4 Nov 2026 21:31:51 +0800 [thread overview]
Message-ID: <20261104133158.3187525-6-luolongjuna@gmail.com> (raw)
In-Reply-To: <20261104133158.3187525-1-luolongjuna@gmail.com>
Read split CUs through libdw and save matching DWO files in a DWP before
another build overwrites them. Keep the DWP beside each saved object.
Reading saved DWP files requires libdw 0.191 or newer.
Read fixed-width array bounds as unsigned so reduced type information
does not make nonempty arrays appear empty.
Full LTO with --plugin-opt=dwo_dir requires
-mllvm -split-dwarf-cross-cu-references=true to preserve separate CUs
and their source paths. Kbuild does not enable this DWO output mode.
Validated the available objtool tests with GCC 16.2.1 and Clang
22.1.8. No failures.
Assisted-by: LLM
Signed-off-by: Longjun Luo <luolongjuna@gmail.com>
---
scripts/livepatch/klp-build | 18 +++++++++++++++
tools/objtool/klp-dwarf.c | 45 ++++++++++++++++++++++++++++---------
2 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index e373928123e8..95bea5b2057e 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -34,6 +34,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FIX_PATCH_LINES="$SCRIPT_DIR/fix-patch-lines"
OBJTOOL="$PWD/tools/objtool/objtool"
+DWP="${DWP:-llvm-dwp}"
CONFIG="$PWD/.config"
TMP_DIR="$PWD/klp-tmp"
@@ -265,6 +266,11 @@ validate_config() {
[[ -v CONFIG_KLP_BUILD ]] || \
die "CONFIG_KLP_BUILD not enabled"
+ if [[ -v CONFIG_DEBUG_INFO_SPLIT ]]; then
+ command -v "$DWP" &>/dev/null ||
+ die "split DWARF requires llvm-dwp (or set DWP)"
+ fi
+
[[ -v CONFIG_GCC_PLUGIN_LATENT_ENTROPY ]] && \
die "kernel option 'CONFIG_GCC_PLUGIN_LATENT_ENTROPY' not supported"
@@ -588,6 +594,15 @@ find_objects() {
-printf '%P\n'
}
+# Save the matching DWOs before the next build overwrites them.
+save_split_dwarf() {
+ local file="$1"
+ local dest="$2"
+
+ [[ -v CONFIG_DEBUG_INFO_SPLIT ]] || return 0
+ "$DWP" -e "$file" -o "$dest.dwp" || die "cannot save split DWARF for $file"
+}
+
# Copy all .o archives to $ORIG_DIR
copy_orig_objects() {
local files=()
@@ -608,6 +623,7 @@ copy_orig_objects() {
mkdir -p "$orig_dir"
cp -f "$file" "$orig_dir"
+ save_split_dwarf "$file" "$orig_file"
done
xtrace_restore
@@ -647,6 +663,7 @@ copy_patched_objects() {
mkdir -p "$patched_dir"
cp -f "$file" "$patched_dir"
+ save_split_dwarf "$file" "$patched_file"
found=1
done
xtrace_restore
@@ -680,6 +697,7 @@ generate_checksums() {
mkdir -p "$(dirname "$dest")"
cp -f "$file" "$dest"
+ [[ -f "$file.dwp" ]] && cp -f "$file.dwp" "$dest.dwp"
"$OBJTOOL" klp checksum "$dest"
done
diff --git a/tools/objtool/klp-dwarf.c b/tools/objtool/klp-dwarf.c
index 99b098ee7904..98d00ea19b7c 100644
--- a/tools/objtool/klp-dwarf.c
+++ b/tools/objtool/klp-dwarf.c
@@ -138,6 +138,10 @@ static void normalize_source(char *path)
*write = '\0';
}
+/*
+ * Full LTO with --plugin-opt=dwo_dir can merge CUs and lose TU source
+ * paths. Kbuild does not enable this output mode.
+ */
static int read_unit_source(struct identity_cu *cu, Dwarf_Die *die)
{
Dwarf_Attribute attr;
@@ -146,12 +150,12 @@ static int read_unit_source(struct identity_cu *cu, Dwarf_Die *die)
if (dwarf_tag(die) != DW_TAG_compile_unit)
return 0;
- if (dwarf_attr(die, DW_AT_name, &attr)) {
+ if (dwarf_attr_integrate(die, DW_AT_name, &attr)) {
name = dwarf_formstring(&attr);
if (!name)
return die_error(die, "invalid compilation unit name");
}
- if (dwarf_attr(die, DW_AT_comp_dir, &attr)) {
+ if (dwarf_attr_integrate(die, DW_AT_comp_dir, &attr)) {
dir = dwarf_formstring(&attr);
if (!dir)
return die_error(die, "invalid compilation directory");
@@ -472,6 +476,23 @@ static int add_address(struct identity_reader *reader, struct identity_die *entr
return 0;
}
+/*
+ * Reduced DWARF can omit the element size of idt_table. Reading its
+ * DW_FORM_data1 upper bound (255) as -1 would misidentify it as empty.
+ */
+static int read_array_bound(Dwarf_Attribute *attr, Dwarf_Sword *bound)
+{
+ Dwarf_Word value;
+
+ if (dwarf_whatform(attr) == DW_FORM_sdata ||
+ dwarf_whatform(attr) == DW_FORM_implicit_const)
+ return dwarf_formsdata(attr, bound);
+ if (dwarf_formudata(attr, &value) || value > INT64_MAX)
+ return -1;
+ *bound = value;
+ return 0;
+}
+
/*
* The empty features[] in virtio_input.c can share an address with the
* nonempty features[] in trans_virtio.c. Exclude the empty object's DIE
@@ -498,10 +519,10 @@ static bool is_empty_type(Dwarf_Die *type)
return true;
lower = 0;
if (dwarf_attr(&range, DW_AT_lower_bound, &attr) &&
- dwarf_formsdata(&attr, &lower))
+ read_array_bound(&attr, &lower))
continue;
if (dwarf_attr(&range, DW_AT_upper_bound, &attr) &&
- !dwarf_formsdata(&attr, &upper) && upper < lower)
+ !read_array_bound(&attr, &upper) && upper < lower)
return true;
} while (!dwarf_siblingof(&range, &range));
return false;
@@ -752,7 +773,7 @@ static int build_identities(struct identity_reader *reader)
static const Dwfl_Callbacks callbacks = { .section_address = dwfl_offline_section_address };
Dwfl *dwfl = dwfl_begin(&callbacks);
Dwarf_CU *cu = NULL, *next;
- Dwarf_Die die;
+ Dwarf_Die die, split;
Dwarf *dwarf;
struct identity_die *entry;
unsigned int bucket;
@@ -767,11 +788,15 @@ static int build_identities(struct identity_reader *reader)
dwarf = dwfl_module_getdwarf(reader->module, &reader->bias);
if (!dwarf || check_relocations(dwarf))
goto out;
- while (!(ret = dwarf_get_units(dwarf, cu, &next, NULL, &unit_type, &die, NULL))) {
- if (unit_type == DW_UT_skeleton ||
- unit_type == DW_UT_split_compile || unit_type == DW_UT_split_type) {
- ret = die_error(&die, "split DWARF is not supported yet");
- goto out;
+ while (!(ret = dwarf_get_units(dwarf, cu, &next, NULL, &unit_type, &die, &split))) {
+ if (unit_type == DW_UT_skeleton) {
+ /* libdw checks the DWO ID and resolves addresses through the skeleton. */
+ if (!split.addr) {
+ ret = die_error(&die,
+ "missing or mismatched split DWARF file (saved .dwp files require libdw >= 0.191)");
+ goto out;
+ }
+ die = split;
}
if (!is_unit(dwarf_tag(&die))) {
ret = die_error(&die, "invalid unit root");
--
2.55.0
next prev parent reply other threads:[~2026-11-04 13:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 13:31 [RFC PATCH v2 00/11] objtool/klp: DWARF-based cross-build symbol correlation Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 01/11] objtool/klp: Fix checksums and copying of wide strings Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 02/11] objtool/klp: Hash compound literals by content Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 03/11] objtool/klp: Preserve identifier digits when stripping suffixes Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 04/11] objtool/klp: Read symbol identities from DWARF Longjun Luo
2026-11-04 13:31 ` Longjun Luo [this message]
2026-11-04 13:31 ` [RFC PATCH v2 06/11] klp-build: Require CONFIG_DEBUG_INFO Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 07/11] objtool/klp: Correlate symbols using DWARF identities Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 08/11] objtool/klp: Include symbol identities in reference checksums Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 09/11] objtool/klp: Extend twins through unchanged function references Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 10/11] objtool/klp: Check unmatched data references Longjun Luo
2026-11-04 13:31 ` [RFC PATCH v2 11/11] objtool/klp: Test symbol identity and state preservation Longjun Luo
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=20261104133158.3187525-6-luolongjuna@gmail.com \
--to=luolongjuna@gmail.com \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=justinstitt@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=mbenes@suse.cz \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=puranjay@kernel.org \
--cc=song@kernel.org \
/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
all inboxes | Powered by JetHome®