objtool/klp: klp-build LTO support
Subsystems (2)
Song Liu
maintainerv4 cover objtool/klp: klp-build LTO support
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
Song Liu
maintainerPATCH v4 1/7 objtool/klp: Remove redundant strcmp() in correlate_symbols()
find_global_symbol_by_name() already compares names of the two symbols, so there is no need to compare them again.
--- tools/objtool/klp-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/objtool/klp-diff.c +1 -1
@@ -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; }
Signature · 1 line
2.52.0
[tip: objtool/core] objtool/klp: Remove redundant strcmp() in correlate_symbols()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: a1cbaff2ea23645f0a94fdfa721aef202aebdf86 Gitweb: https://git.kernel.org/tip/a1cbaff2ea23645f0a94fdfa721aef202aebdf86 Author: Song Liu <[email protected]> AuthorDate: Thu, 05 Mar 2026 15:15:25 -08:00 Committer: Josh Poimboeuf <[email protected]> CommitterDate: Fri, 06 Mar 2026 08:08:23 -08:00
objtool/klp: Remove redundant strcmp() in correlate_symbols()
find_global_symbol_by_name() already compares names of the two symbols, so there is no need to compare them again.
--- tools/objtool/klp-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/objtool/klp-diff.c +1 -1
@@ -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; }
Song Liu
maintainerPATCH v4 2/7 objtool/klp: Remove trailing '_' in demangle_name()
In reply to Song LiuWith 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().
--- tools/objtool/elf.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
tools/objtool/elf.c +14 -1
@@ -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 ; }
Signature · 1 line
2.52.0
[tip: objtool/core] objtool/klp: Remove trailing '_' in demangle_name()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: a3f28d2072452edb377eaad01375445dbace6771 Gitweb: https://git.kernel.org/tip/a3f28d2072452edb377eaad01375445dbace6771 Author: Song Liu <[email protected]> AuthorDate: Thu, 05 Mar 2026 15:15:26 -08:00 Committer: Josh Poimboeuf <[email protected]> CommitterDate: Fri, 06 Mar 2026 08:08:30 -08:00
objtool/klp: Remove trailing '_' in demangle_name()
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().
--- tools/objtool/elf.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
tools/objtool/elf.c +14 -1
@@ -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 ; }
Song Liu
maintainerPATCH v4 3/7 objtool/klp: Use sym->demangled_name for symbol_name hash
In reply to Song LiuFor 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.
--- tools/objtool/elf.c | 58 +++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 18 deletions(-)
tools/objtool/elf.c +40 -18
@@ -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 ; }
Signature · 1 line
2.52.0
[tip: objtool/core] objtool/klp: Use sym->demangled_name for symbol_name hash
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 0b8fc6adc3d9bdf161fc8ad0a1de191dba293b39 Gitweb: https://git.kernel.org/tip/0b8fc6adc3d9bdf161fc8ad0a1de191dba293b39 Author: Song Liu <[email protected]> AuthorDate: Thu, 05 Mar 2026 15:15:27 -08:00 Committer: Josh Poimboeuf <[email protected]> CommitterDate: Fri, 06 Mar 2026 08:08:32 -08:00
objtool/klp: Use sym->demangled_name for symbol_name hash
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.
--- tools/objtool/elf.c | 58 ++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 18 deletions(-)
tools/objtool/elf.c +40 -18
@@ -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; }
@@ -442,6 +449,28 @@ static int read_sections(struct elf *elf) }/* +* 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. * * Specifically, remove trailing numbers for "__UNIQUE_ID_" symbols and
@@ -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 ; }
Song Liu
maintainerPATCH v4 4/7 objtool/klp: Also demangle global objects
In reply to Song LiuWith 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.
--- tools/objtool/elf.c | 3 --- 1 file changed, 3 deletions(-)
tools/objtool/elf.c +0 -3
@@ -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;
Signature · 1 line
2.52.0
[tip: objtool/core] objtool/klp: Also demangle global objects
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 8206277746d5c6ae300e7e062a0d9238ed59cc7f Gitweb: https://git.kernel.org/tip/8206277746d5c6ae300e7e062a0d9238ed59cc7f Author: Song Liu <[email protected]> AuthorDate: Thu, 05 Mar 2026 15:15:28 -08:00 Committer: Josh Poimboeuf <[email protected]> CommitterDate: Fri, 06 Mar 2026 08:08:32 -08:00
objtool/klp: Also demangle global objects
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.
--- tools/objtool/elf.c | 3 --- 1 file changed, 3 deletions(-)
tools/objtool/elf.c +0 -3
@@ -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;
Song Liu
maintainerPATCH v4 5/7 objtool/klp: Remove .llvm suffix in demangle_name()
In reply to Song LiuRemove .llvm suffix, so that we can correlate foo.llvm.<hash 1> and foo.llvm.<hash 2>.
--- tools/objtool/elf.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/objtool/elf.c +8 -0
@@ -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) {
Signature · 1 line
2.52.0
[tip: objtool/core] objtool/klp: Remove .llvm suffix in demangle_name()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 020b71dcafeeececb78d9ee9e5a2e68e8e05e922 Gitweb: https://git.kernel.org/tip/020b71dcafeeececb78d9ee9e5a2e68e8e05e922 Author: Song Liu <[email protected]> AuthorDate: Thu, 05 Mar 2026 15:15:29 -08:00 Committer: Josh Poimboeuf <[email protected]> CommitterDate: Fri, 06 Mar 2026 08:08:33 -08:00
objtool/klp: Remove .llvm suffix in demangle_name()
Remove .llvm suffix, so that we can correlate foo.llvm.<hash 1> and foo.llvm.<hash 2>.
--- tools/objtool/elf.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/objtool/elf.c +8 -0
@@ -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) {
Song Liu
maintainerPATCH v4 6/7 objtool/klp: Match symbols based on demangled_name for global variables
In reply to Song Liucorrelate_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.
--- tools/objtool/elf.c | 13 +++++++ tools/objtool/include/objtool/elf.h | 3 ++ tools/objtool/klp-diff.c | 57 +++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+)
tools/objtool/elf.c +13 -0
@@ -323,6 +323,19 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *namreturn 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) {
tools/objtool/include/objtool/elf.h +3 -0
@@ -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);
tools/objtool/klp-diff.c +57 -0
69 lines not on this page · raw message
Signature · 1 line
2.52.0
[tip: objtool/core] objtool/klp: Match symbols based on demangled_name for global variables
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: cdea5cadb0ca403b1929f8d29929c0eda0f715d6 Gitweb: https://git.kernel.org/tip/cdea5cadb0ca403b1929f8d29929c0eda0f715d6 Author: Song Liu <[email protected]> AuthorDate: Thu, 05 Mar 2026 15:15:30 -08:00 Committer: Josh Poimboeuf <[email protected]> CommitterDate: Fri, 06 Mar 2026 08:08:33 -08:00
objtool/klp: Match symbols based on demangled_name for global variables
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.
--- tools/objtool/elf.c | 13 ++++++- tools/objtool/include/objtool/elf.h | 3 +- tools/objtool/klp-diff.c | 57 ++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+)
tools/objtool/elf.c +13 -0
@@ -323,6 +323,19 @@ struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *namreturn 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) {
tools/objtool/include/objtool/elf.h +3 -0
@@ -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);
tools/objtool/klp-diff.c +57 -0
69 lines not on this page · raw message
Song Liu
maintainerPATCH v4 7/7 objtool/klp: Correlate locals to globals
In reply to Song LiuAllow 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.
--- tools/objtool/klp-diff.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
tools/objtool/klp-diff.c +30 -0
@@ -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 ;
Signature · 1 line
2.52.0
[tip: objtool/core] objtool/klp: Correlate locals to globals
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 4b57e97be22fb8332d05ee1d0fe3c0dd43c828bf Gitweb: https://git.kernel.org/tip/4b57e97be22fb8332d05ee1d0fe3c0dd43c828bf Author: Song Liu <[email protected]> AuthorDate: Thu, 05 Mar 2026 15:15:31 -08:00 Committer: Josh Poimboeuf <[email protected]> CommitterDate: Fri, 06 Mar 2026 08:08:34 -08:00
objtool/klp: Correlate locals to globals
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.
--- tools/objtool/klp-diff.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
tools/objtool/klp-diff.c +30 -0
@@ -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 ;
Josh Poimboeuf
maintainerQuoted 34 lines · 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 tocorrelate_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 aWARN().
3. Some empty line changes.Changes v1 => v2:
1. Error out on ambiguous .llvm.<hash>Song Liu (7):
objtool/klp: Remove redundantstrcmp()incorrelate_symbols()objtool/klp: Remove trailing '_' indemangle_name()objtool/klp: Usesym->demangled_nameforsymbol_namehash objtool/klp: Also demangle global objects objtool/klp: Remove .llvm suffix indemangle_name()objtool/klp: Match symbols based ondemangled_namefor global
variables
objtool/klp: Correlate locals to globals
Quoted 4 lines
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.
Signature · 1 line
Josh