[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20201110161124.lztfgffqh2qrlwwv@treble>
Date: Tue, 10 Nov 2020 10:11:24 -0600
From: Josh Poimboeuf <jpoimboe@...hat.com>
To: Sami Tolvanen <samitolvanen@...gle.com>
Cc: Peter Zijlstra <peterz@...radead.org>,
Jann Horn <jannh@...gle.com>,
the arch/x86 maintainers <x86@...nel.org>,
Masahiro Yamada <masahiroy@...nel.org>,
Steven Rostedt <rostedt@...dmis.org>,
Will Deacon <will@...nel.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
"Paul E. McKenney" <paulmck@...nel.org>,
Kees Cook <keescook@...omium.org>,
Nick Desaulniers <ndesaulniers@...gle.com>,
clang-built-linux <clang-built-linux@...glegroups.com>,
Kernel Hardening <kernel-hardening@...ts.openwall.com>,
linux-arch <linux-arch@...r.kernel.org>,
Linux ARM <linux-arm-kernel@...ts.infradead.org>,
linux-kbuild <linux-kbuild@...r.kernel.org>,
kernel list <linux-kernel@...r.kernel.org>,
linux-pci@...r.kernel.org
Subject: Re: [PATCH v6 22/25] x86/asm: annotate indirect jumps
On Mon, Nov 09, 2020 at 08:48:01PM -0800, Sami Tolvanen wrote:
> On Mon, Nov 9, 2020 at 6:29 PM Josh Poimboeuf <jpoimboe@...hat.com> wrote:
> > How would I recreate all these warnings?
>
> You can reproduce all of these using a normal gcc build without any of
> the LTO patches by running objtool check -arfld vmlinux.o. However,
> with gcc you'll see even more warnings due to duplicate symbol names,
> as Peter pointed out elsewhere in the thread, so I looked at only the
> warnings that objtool also prints with LTO.
>
> Note that the LTO series contains a patch to split noinstr validation
> from --vmlinux, as we need to run objtool here even if
> CONFIG_VMLINUX_VALIDATION isn't selected, so I have not looked at the
> noinstr warnings. The latest LTO tree is available here:
>
> https://github.com/samitolvanen/linux/commits/clang-lto
>
> > Here's the patch for hopefully making the warnings more helpful:
>
> Thanks, I'll give it a try.
Here's the version without the nonsensical debug warning :-)
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 4e1d7460574b..ced7e4754cba 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -217,6 +217,21 @@ struct symbol *find_func_containing(struct section *sec, unsigned long offset)
return NULL;
}
+struct symbol *find_symbol_preceding(struct section *sec, unsigned long offset)
+{
+ struct symbol *sym;
+
+ /*
+ * This is slow, but used for warning messages.
+ */
+ while (1) {
+ sym = find_symbol_by_offset(sec, offset);
+ if (sym || !offset)
+ return sym;
+ offset--;
+ }
+}
+
struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
{
struct symbol *sym;
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index 807f8c670097..841902ed381e 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -136,10 +136,11 @@ 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_symbol_containing(const struct section *sec, unsigned long offset);
+struct symbol *find_func_containing(struct section *sec, unsigned long offset);
+struct symbol *find_symbol_preceding(struct section *sec, unsigned long offset);
struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
unsigned long offset, unsigned int len);
-struct symbol *find_func_containing(struct section *sec, unsigned long offset);
int elf_rebuild_reloc_section(struct elf *elf, struct section *sec);
#define for_each_sec(file, sec) \
diff --git a/tools/objtool/warn.h b/tools/objtool/warn.h
index 7799f60de80a..33da0f2ed9d5 100644
--- a/tools/objtool/warn.h
+++ b/tools/objtool/warn.h
@@ -22,6 +22,8 @@ static inline char *offstr(struct section *sec, unsigned long offset)
unsigned long name_off;
func = find_func_containing(sec, offset);
+ if (!func)
+ func = find_symbol_preceding(sec, offset);
if (func) {
name = func->name;
name_off = offset - func->offset;
Powered by blists - more mailing lists