lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <176371907982.498.1222124194340102338.tip-bot2@tip-bot2>
Date: Fri, 21 Nov 2025 09:57:59 -0000
From: "tip-bot2 for Josh Poimboeuf" <tip-bot2@...utronix.de>
To: linux-tip-commits@...r.kernel.org
Cc: Josh Poimboeuf <jpoimboe@...nel.org>,
 "Peter Zijlstra (Intel)" <peterz@...radead.org>, x86@...nel.org,
 linux-kernel@...r.kernel.org
Subject: [tip: objtool/core] objtool: Fix .cold function detection for
 duplicate symbols

The following commit has been merged into the objtool/core branch of tip:

Commit-ID:     2c2acca2eabf53a954ed5aacef987bbf909b9f12
Gitweb:        https://git.kernel.org/tip/2c2acca2eabf53a954ed5aacef987bbf909b9f12
Author:        Josh Poimboeuf <jpoimboe@...nel.org>
AuthorDate:    Thu, 20 Nov 2025 12:52:16 -08:00
Committer:     Peter Zijlstra <peterz@...radead.org>
CommitterDate: Fri, 21 Nov 2025 10:04:07 +01:00

objtool: Fix .cold function detection for duplicate symbols

The objtool .cold child/parent correlation is done in two phases: first
in elf_add_symbol() and later in add_jump_destinations().

The first phase is rather crude and can pick the wrong parent if there
are duplicates with the same name.

The second phase usually fixes that, but only if the parent has a direct
jump to the child.  It does *not* work if the only branch from the
parent to the child is an alternative or jump table entry.

Make the first phase more robust by looking for the parent in the same
STT_FILE as the child.

Fixes the following objtool warnings in an AutoFDO build with a large
CLANG_AUTOFDO_PROFILE profile:

  vmlinux.o: warning: objtool: rdev_add_key() falls through to next function rdev_add_key.cold()
  vmlinux.o: warning: objtool: rdev_set_default_key() falls through to next function rdev_set_default_key.cold()

Fixes: 13810435b9a7 ("objtool: Support GCC 8's cold subfunctions")
Signed-off-by: Josh Poimboeuf <jpoimboe@...nel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
Link: https://patch.msgid.link/82c7b52e40efa75dd10e1c550cc75c1ce10ac2c9.1763671318.git.jpoimboe@kernel.org
---
 tools/objtool/elf.c                 | 28 ++++++++++++++++++++++++++--
 tools/objtool/include/objtool/elf.h |  2 +-
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 7895f65..fffca31 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -288,6 +288,23 @@ struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
 	return NULL;
 }
 
+/* Find local symbol with matching STT_FILE */
+static struct symbol *find_local_symbol_by_file_and_name(const struct elf *elf,
+							 struct symbol *file,
+							 const char *name)
+{
+	struct symbol *sym;
+
+	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
+		if (sym->bind == STB_LOCAL && sym->file == file &&
+		    !strcmp(sym->name, name)) {
+			return sym;
+		}
+	}
+
+	return NULL;
+}
+
 struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name)
 {
 	struct symbol *sym;
@@ -524,7 +541,7 @@ static int elf_add_symbol(struct elf *elf, struct symbol *sym)
 static int read_symbols(struct elf *elf)
 {
 	struct section *symtab, *symtab_shndx, *sec;
-	struct symbol *sym, *pfunc;
+	struct symbol *sym, *pfunc, *file = NULL;
 	int symbols_nr, i;
 	char *coldstr;
 	Elf_Data *shndx_data = NULL;
@@ -597,6 +614,11 @@ static int read_symbols(struct elf *elf)
 
 		if (elf_add_symbol(elf, sym))
 			return -1;
+
+		if (sym->type == STT_FILE)
+			file = sym;
+		else if (sym->bind == STB_LOCAL)
+			sym->file = file;
 	}
 
 	if (opts.stats) {
@@ -626,7 +648,9 @@ static int read_symbols(struct elf *elf)
 				return -1;
 			}
 
-			pfunc = find_symbol_by_name(elf, pname);
+			pfunc = find_local_symbol_by_file_and_name(elf, sym->file, pname);
+			if (!pfunc)
+				pfunc = find_global_symbol_by_name(elf, pname);
 			free(pname);
 
 			if (!pfunc) {
diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h
index 21d8b82..e12c516 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -69,7 +69,7 @@ struct symbol {
 	unsigned int idx, len;
 	unsigned long offset;
 	unsigned long __subtree_last;
-	struct symbol *pfunc, *cfunc, *alias;
+	struct symbol *pfunc, *cfunc, *alias, *file;
 	unsigned char bind, type;
 	u8 uaccess_safe      : 1;
 	u8 static_call_tramp : 1;

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ