public inbox for live-patching@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/7] objtool/klp: klp-build LTO support
@ 2026-03-05 23:15 Song Liu
  2026-03-05 23:15 ` [PATCH v4 1/7] objtool/klp: Remove redundant strcmp() in correlate_symbols() Song Liu
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

Add support for LTO in klp-build toolchain. The key changes are to the
symbol correlation logic.Basically, we want to:

1. Match symbols with differerent .llvm.<hash> suffixes, e.g., foo.llvm.123
   to foo.llvm.456.
2. Match local symbols with promoted global symbols, e.g., local foo
   with global foo.llvm.123.

1/7 and 2/7 are small cleanup/fix for existing code.
3/7 through 7/7 contains the core logic changes to correlate_symbols().

Changes v3 => v4:
1. Minor fixes in patches 1, 3, 7.
2. Only keep patches 1-7 for now, as there is ongoing discussion about the
   test infrastructure.

Changes v2 => v3:
1. Fix a bug in global => local correlations (patch 7/8).
2. Remove a WARN().
3. Some empty line changes.

Changes v1 => v2:
1. Error out on ambiguous .llvm.<hash>

Song Liu (7):
  objtool/klp: Remove redundant strcmp() in correlate_symbols()
  objtool/klp: Remove trailing '_' in demangle_name()
  objtool/klp: Use sym->demangled_name for symbol_name hash
  objtool/klp: Also demangle global objects
  objtool/klp: Remove .llvm suffix in demangle_name()
  objtool/klp: Match symbols based on demangled_name for global
    variables
  objtool/klp: Correlate locals to globals

 tools/objtool/elf.c                 | 95 ++++++++++++++++++++++-------
 tools/objtool/include/objtool/elf.h |  3 +
 tools/objtool/klp-diff.c            | 89 ++++++++++++++++++++++++++-
 3 files changed, 165 insertions(+), 22 deletions(-)

--
2.52.0

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v4 1/7] objtool/klp: Remove redundant strcmp() in correlate_symbols()
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
@ 2026-03-05 23:15 ` Song Liu
  2026-03-05 23:15 ` [PATCH v4 2/7] objtool/klp: Remove trailing '_' in demangle_name() Song Liu
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

find_global_symbol_by_name() already compares names of the two symbols,
so there is no need to compare them again.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/klp-diff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index a3198a63c2f0..57606bc3390a 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -454,7 +454,7 @@ static int correlate_symbols(struct elfs *e)
 
 		sym2 = find_global_symbol_by_name(e->patched, sym1->name);
 
-		if (sym2 && !sym2->twin && !strcmp(sym1->name, sym2->name)) {
+		if (sym2 && !sym2->twin) {
 			sym1->twin = sym2;
 			sym2->twin = sym1;
 		}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 2/7] objtool/klp: Remove trailing '_' in demangle_name()
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
  2026-03-05 23:15 ` [PATCH v4 1/7] objtool/klp: Remove redundant strcmp() in correlate_symbols() Song Liu
@ 2026-03-05 23:15 ` Song Liu
  2026-03-05 23:15 ` [PATCH v4 3/7] objtool/klp: Use sym->demangled_name for symbol_name hash Song Liu
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

With CONFIG_LTO_CLANG_THIN, it is possible to have nested __UNIQUE_ID_,
such as:

  __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695

To remove both trailing numbers, also remove trailing '_'.

Also add comments to demangle_name().

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 2c02c7b49265..0d93e8496e8d 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -441,6 +441,19 @@ static int read_sections(struct elf *elf)
 	return 0;
 }
 
+/*
+ * Remove number suffix of a symbol.
+ *
+ * Specifically, remove trailing numbers for "__UNIQUE_ID_" symbols and
+ * symbols with '.'.
+ *
+ * With CONFIG_LTO_CLANG_THIN, it is possible to have nested __UNIQUE_ID_,
+ * such as
+ *
+ *   __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695
+ *
+ * to remove both trailing numbers, also remove trailing '_'.
+ */
 static const char *demangle_name(struct symbol *sym)
 {
 	char *str;
@@ -463,7 +476,7 @@ static const char *demangle_name(struct symbol *sym)
 	for (int i = strlen(str) - 1; i >= 0; i--) {
 		char c = str[i];
 
-		if (!isdigit(c) && c != '.') {
+		if (!isdigit(c) && c != '.' && c != '_') {
 			str[i + 1] = '\0';
 			break;
 		}
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 3/7] objtool/klp: Use sym->demangled_name for symbol_name hash
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
  2026-03-05 23:15 ` [PATCH v4 1/7] objtool/klp: Remove redundant strcmp() in correlate_symbols() Song Liu
  2026-03-05 23:15 ` [PATCH v4 2/7] objtool/klp: Remove trailing '_' in demangle_name() Song Liu
@ 2026-03-05 23:15 ` Song Liu
  2026-03-05 23:15 ` [PATCH v4 4/7] objtool/klp: Also demangle global objects Song Liu
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

For klp-build with LTO, it is necessary to correlate demangled symbols,
e.g., correlate foo.llvm.<num 1> and foo.llvm.<num 2>. However, these two
symbols do not have the same str_hash(name). To be able to correlate the
two symbols, calculate hash based on demanged_name, so that these two
symbols have the same hash.

No functional changes intended.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 58 +++++++++++++++++++++++++++++++--------------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 0d93e8496e8d..d9f883f7cff8 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -26,11 +26,18 @@
 #include <objtool/elf.h>
 #include <objtool/warn.h>
 
+static ssize_t demangled_name_len(const char *name);
+
 static inline u32 str_hash(const char *str)
 {
 	return jhash(str, strlen(str), 0);
 }
 
+static inline u32 str_hash_demangled(const char *str)
+{
+	return jhash(str, demangled_name_len(str), 0);
+}
+
 #define __elf_table(name)	(elf->name##_hash)
 #define __elf_bits(name)	(elf->name##_bits)
 
@@ -294,7 +301,7 @@ static struct symbol *find_local_symbol_by_file_and_name(const struct elf *elf,
 {
 	struct symbol *sym;
 
-	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) {
 		if (sym->bind == STB_LOCAL && sym->file == file &&
 		    !strcmp(sym->name, name)) {
 			return sym;
@@ -308,7 +315,7 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam
 {
 	struct symbol *sym;
 
-	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash_demangled(name)) {
 		if (!strcmp(sym->name, name) && !is_local_sym(sym))
 			return sym;
 	}
@@ -441,6 +448,28 @@ static int read_sections(struct elf *elf)
 	return 0;
 }
 
+/*
+ * Returns desired length of the demangled name.
+ * If name doesn't need demangling, return strlen(name).
+ */
+static ssize_t demangled_name_len(const char *name)
+{
+	ssize_t idx;
+
+	if (!strstarts(name, "__UNIQUE_ID_") && !strchr(name, '.'))
+		return strlen(name);
+
+	for (idx = strlen(name) - 1; idx >= 0; idx--) {
+		char c = name[idx];
+
+		if (!isdigit(c) && c != '.' && c != '_')
+			break;
+	}
+	if (idx <= 0)
+		return strlen(name);
+	return idx + 1;
+}
+
 /*
  * Remove number suffix of a symbol.
  *
@@ -457,6 +486,7 @@ static int read_sections(struct elf *elf)
 static const char *demangle_name(struct symbol *sym)
 {
 	char *str;
+	ssize_t len;
 
 	if (!is_local_sym(sym))
 		return sym->name;
@@ -464,24 +494,16 @@ static const char *demangle_name(struct symbol *sym)
 	if (!is_func_sym(sym) && !is_object_sym(sym))
 		return sym->name;
 
-	if (!strstarts(sym->name, "__UNIQUE_ID_") && !strchr(sym->name, '.'))
+	len = demangled_name_len(sym->name);
+	if (len == strlen(sym->name))
 		return sym->name;
 
-	str = strdup(sym->name);
+	str = strndup(sym->name, len);
 	if (!str) {
 		ERROR_GLIBC("strdup");
 		return NULL;
 	}
 
-	for (int i = strlen(str) - 1; i >= 0; i--) {
-		char c = str[i];
-
-		if (!isdigit(c) && c != '.' && c != '_') {
-			str[i + 1] = '\0';
-			break;
-		}
-	}
-
 	return str;
 }
 
@@ -517,9 +539,13 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym)
 		entry = &sym->sec->symbol_list;
 	list_add(&sym->list, entry);
 
+	sym->demangled_name = demangle_name(sym);
+	if (!sym->demangled_name)
+		return -1;
+
 	list_add_tail(&sym->global_list, &elf->symbols);
 	elf_hash_add(symbol, &sym->hash, sym->idx);
-	elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name));
+	elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->demangled_name));
 
 	if (is_func_sym(sym) &&
 	    (strstarts(sym->name, "__pfx_") ||
@@ -543,10 +569,6 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym)
 
 	sym->pfunc = sym->cfunc = sym;
 
-	sym->demangled_name = demangle_name(sym);
-	if (!sym->demangled_name)
-		return -1;
-
 	return 0;
 }
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 4/7] objtool/klp: Also demangle global objects
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
                   ` (2 preceding siblings ...)
  2026-03-05 23:15 ` [PATCH v4 3/7] objtool/klp: Use sym->demangled_name for symbol_name hash Song Liu
@ 2026-03-05 23:15 ` Song Liu
  2026-03-05 23:15 ` [PATCH v4 5/7] objtool/klp: Remove .llvm suffix in demangle_name() Song Liu
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

With CONFIG_LTO_CLANG_THIN, it is possible to have global __UNIQUE_ID,
such as:

   FUNC    GLOBAL HIDDEN  19745 __UNIQUE_ID_quirk_amd_nb_node_458

Also demangle global objects.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index d9f883f7cff8..78db51ebbed4 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -488,9 +488,6 @@ static const char *demangle_name(struct symbol *sym)
 	char *str;
 	ssize_t len;
 
-	if (!is_local_sym(sym))
-		return sym->name;
-
 	if (!is_func_sym(sym) && !is_object_sym(sym))
 		return sym->name;
 
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 5/7] objtool/klp: Remove .llvm suffix in demangle_name()
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
                   ` (3 preceding siblings ...)
  2026-03-05 23:15 ` [PATCH v4 4/7] objtool/klp: Also demangle global objects Song Liu
@ 2026-03-05 23:15 ` Song Liu
  2026-03-05 23:15 ` [PATCH v4 6/7] objtool/klp: Match symbols based on demangled_name for global variables Song Liu
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

Remove .llvm suffix, so that we can correlate foo.llvm.<hash 1> and
foo.llvm.<hash 2>.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 78db51ebbed4..51e6267cdf8d 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -455,6 +455,11 @@ static int read_sections(struct elf *elf)
 static ssize_t demangled_name_len(const char *name)
 {
 	ssize_t idx;
+	const char *p;
+
+	p = strstr(name, ".llvm.");
+	if (p)
+		return p - name;
 
 	if (!strstarts(name, "__UNIQUE_ID_") && !strchr(name, '.'))
 		return strlen(name);
@@ -482,6 +487,9 @@ static ssize_t demangled_name_len(const char *name)
  *   __UNIQUE_ID_addressable___UNIQUE_ID_pci_invalid_bar_694_695
  *
  * to remove both trailing numbers, also remove trailing '_'.
+ *
+ * For symbols with llvm suffix, i.e., foo.llvm.<hash>, remove the
+ * .llvm.<hash> part.
  */
 static const char *demangle_name(struct symbol *sym)
 {
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 6/7] objtool/klp: Match symbols based on demangled_name for global variables
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
                   ` (4 preceding siblings ...)
  2026-03-05 23:15 ` [PATCH v4 5/7] objtool/klp: Remove .llvm suffix in demangle_name() Song Liu
@ 2026-03-05 23:15 ` Song Liu
  2026-03-05 23:15 ` [PATCH v4 7/7] objtool/klp: Correlate locals to globals Song Liu
  2026-03-06 16:09 ` [PATCH v4 0/7] objtool/klp: klp-build LTO support Josh Poimboeuf
  7 siblings, 0 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

correlate_symbols() will always try to match full name first. If there is
no match, try match only demangled_name.

In very rare cases, it is possible to have multiple foo.llvm.<hash> in
the same kernel. Whenever there is ambiguity like this, fail the klp diff.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/elf.c                 | 13 +++++++
 tools/objtool/include/objtool/elf.h |  3 ++
 tools/objtool/klp-diff.c            | 57 +++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 51e6267cdf8d..ef4affd6e45e 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -323,6 +323,19 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *nam
 	return NULL;
 }
 
+void iterate_global_symbol_by_demangled_name(const struct elf *elf,
+					     const char *demangled_name,
+					     void (*process)(struct symbol *sym, void *data),
+					     void *data)
+{
+	struct symbol *sym;
+
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(demangled_name)) {
+		if (!strcmp(sym->demangled_name, demangled_name) && !is_local_sym(sym))
+			process(sym, data);
+	}
+}
+
 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
 				     unsigned long offset, unsigned int len)
 {
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index e12c516bd320..25573e5af76e 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -186,6 +186,9 @@ struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
 struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name);
+void iterate_global_symbol_by_demangled_name(const struct elf *elf, const char *demangled_name,
+					     void (*process)(struct symbol *sym, void *data),
+					     void *data);
 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
 int find_symbol_hole_containing(const struct section *sec, unsigned long offset);
 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 57606bc3390a..92043da0ed0b 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -355,6 +355,46 @@ static bool dont_correlate(struct symbol *sym)
 	       strstarts(sym->name, "__initcall__");
 }
 
+struct process_demangled_name_data {
+	struct symbol *ret;
+	int count;
+};
+
+static void process_demangled_name(struct symbol *sym, void *d)
+{
+	struct process_demangled_name_data *data = d;
+
+	if (sym->twin)
+		return;
+
+	data->count++;
+	data->ret = sym;
+}
+
+/*
+ * When there is no full name match, try match demangled_name. This would
+ * match original foo.llvm.123 to patched foo.llvm.456.
+ *
+ * Note that, in very rare cases, it is possible to have multiple
+ * foo.llvm.<hash> in the same kernel. When this happens, report error and
+ * fail the diff.
+ */
+static int find_global_symbol_by_demangled_name(struct elf *elf, struct symbol *sym,
+						struct symbol **out_sym)
+{
+	struct process_demangled_name_data data = {};
+
+	iterate_global_symbol_by_demangled_name(elf, sym->demangled_name,
+						process_demangled_name,
+						&data);
+	if (data.count > 1) {
+		ERROR("Multiple (%d) correlation candidates for %s", data.count, sym->name);
+		return -1;
+	}
+	*out_sym = data.ret;
+	return 0;
+}
+
 /*
  * For each symbol in the original kernel, find its corresponding "twin" in the
  * patched kernel.
@@ -453,6 +493,23 @@ static int correlate_symbols(struct elfs *e)
 			continue;
 
 		sym2 = find_global_symbol_by_name(e->patched, sym1->name);
+		if (sym2 && !sym2->twin) {
+			sym1->twin = sym2;
+			sym2->twin = sym1;
+		}
+	}
+
+	/*
+	 * Correlate globals with demangled_name.
+	 * A separate loop is needed because we want to finish all the
+	 * full name correlations first.
+	 */
+	for_each_sym(e->orig, sym1) {
+		if (sym1->bind == STB_LOCAL || sym1->twin)
+			continue;
+
+		if (find_global_symbol_by_demangled_name(e->patched, sym1, &sym2))
+			return -1;
 
 		if (sym2 && !sym2->twin) {
 			sym1->twin = sym2;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 7/7] objtool/klp: Correlate locals to globals
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
                   ` (5 preceding siblings ...)
  2026-03-05 23:15 ` [PATCH v4 6/7] objtool/klp: Match symbols based on demangled_name for global variables Song Liu
@ 2026-03-05 23:15 ` Song Liu
  2026-03-06 16:09 ` [PATCH v4 0/7] objtool/klp: klp-build LTO support Josh Poimboeuf
  7 siblings, 0 replies; 9+ messages in thread
From: Song Liu @ 2026-03-05 23:15 UTC (permalink / raw)
  To: live-patching
  Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, kernel-team,
	Song Liu

Allow correlating original locals to patched globals, and vice versa.
This is needed when:

1. User adds/removes "static" for a function.
2. CONFIG_LTO_CLANG_THIN promotes local functions and objects to global
   and add .llvm.<hash> suffix.

Signed-off-by: Song Liu <song@kernel.org>
---
 tools/objtool/klp-diff.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 92043da0ed0b..7bdb2a417096 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -517,6 +517,36 @@ static int correlate_symbols(struct elfs *e)
 		}
 	}
 
+	/* Correlate original locals with patched globals */
+	for_each_sym(e->orig, sym1) {
+		if (sym1->twin || dont_correlate(sym1) || !is_local_sym(sym1))
+			continue;
+
+		sym2 = find_global_symbol_by_name(e->patched, sym1->name);
+		if (!sym2 && find_global_symbol_by_demangled_name(e->patched, sym1, &sym2))
+			return -1;
+
+		if (sym2 && !sym2->twin) {
+			sym1->twin = sym2;
+			sym2->twin = sym1;
+		}
+	}
+
+	/* Correlate original globals with patched locals */
+	for_each_sym(e->patched, sym2) {
+		if (sym2->twin || dont_correlate(sym2) || !is_local_sym(sym2))
+			continue;
+
+		sym1 = find_global_symbol_by_name(e->orig, sym2->name);
+		if (!sym1 && find_global_symbol_by_demangled_name(e->orig, sym2, &sym1))
+			return -1;
+
+		if (sym1 && !sym1->twin) {
+			sym2->twin = sym1;
+			sym1->twin = sym2;
+		}
+	}
+
 	for_each_sym(e->orig, sym1) {
 		if (sym1->twin || dont_correlate(sym1))
 			continue;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v4 0/7] objtool/klp: klp-build LTO support
  2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
                   ` (6 preceding siblings ...)
  2026-03-05 23:15 ` [PATCH v4 7/7] objtool/klp: Correlate locals to globals Song Liu
@ 2026-03-06 16:09 ` Josh Poimboeuf
  7 siblings, 0 replies; 9+ messages in thread
From: Josh Poimboeuf @ 2026-03-06 16:09 UTC (permalink / raw)
  To: Song Liu; +Cc: live-patching, jikos, mbenes, pmladek, joe.lawrence, kernel-team

On Thu, Mar 05, 2026 at 03:15:24PM -0800, Song Liu wrote:
> Add support for LTO in klp-build toolchain. The key changes are to the
> symbol correlation logic.Basically, we want to:
> 
> 1. Match symbols with differerent .llvm.<hash> suffixes, e.g., foo.llvm.123
>    to foo.llvm.456.
> 2. Match local symbols with promoted global symbols, e.g., local foo
>    with global foo.llvm.123.
> 
> 1/7 and 2/7 are small cleanup/fix for existing code.
> 3/7 through 7/7 contains the core logic changes to correlate_symbols().
> 
> Changes v3 => v4:
> 1. Minor fixes in patches 1, 3, 7.
> 2. Only keep patches 1-7 for now, as there is ongoing discussion about the
>    test infrastructure.
> 
> Changes v2 => v3:
> 1. Fix a bug in global => local correlations (patch 7/8).
> 2. Remove a WARN().
> 3. Some empty line changes.
> 
> Changes v1 => v2:
> 1. Error out on ambiguous .llvm.<hash>
> 
> Song Liu (7):
>   objtool/klp: Remove redundant strcmp() in correlate_symbols()
>   objtool/klp: Remove trailing '_' in demangle_name()
>   objtool/klp: Use sym->demangled_name for symbol_name hash
>   objtool/klp: Also demangle global objects
>   objtool/klp: Remove .llvm suffix in demangle_name()
>   objtool/klp: Match symbols based on demangled_name for global
>     variables
>   objtool/klp: Correlate locals to globals
> 
>  tools/objtool/elf.c                 | 95 ++++++++++++++++++++++-------
>  tools/objtool/include/objtool/elf.h |  3 +
>  tools/objtool/klp-diff.c            | 89 ++++++++++++++++++++++++++-
>  3 files changed, 165 insertions(+), 22 deletions(-)

Thanks!  I will go ahead and queue these up.

-- 
Josh

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-03-06 16:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-05 23:15 [PATCH v4 0/7] objtool/klp: klp-build LTO support Song Liu
2026-03-05 23:15 ` [PATCH v4 1/7] objtool/klp: Remove redundant strcmp() in correlate_symbols() Song Liu
2026-03-05 23:15 ` [PATCH v4 2/7] objtool/klp: Remove trailing '_' in demangle_name() Song Liu
2026-03-05 23:15 ` [PATCH v4 3/7] objtool/klp: Use sym->demangled_name for symbol_name hash Song Liu
2026-03-05 23:15 ` [PATCH v4 4/7] objtool/klp: Also demangle global objects Song Liu
2026-03-05 23:15 ` [PATCH v4 5/7] objtool/klp: Remove .llvm suffix in demangle_name() Song Liu
2026-03-05 23:15 ` [PATCH v4 6/7] objtool/klp: Match symbols based on demangled_name for global variables Song Liu
2026-03-05 23:15 ` [PATCH v4 7/7] objtool/klp: Correlate locals to globals Song Liu
2026-03-06 16:09 ` [PATCH v4 0/7] objtool/klp: klp-build LTO support Josh Poimboeuf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox