summaryrefslogtreecommitdiffstats
path: root/tools/objtool/check.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-06-28 10:16:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-06-28 10:16:15 -0700
commit7ecb59a56666506ebb1197f89ca7d587bd83309e (patch)
tree81ad7f30114cd4f2ada4a5631636581f9ff7544e /tools/objtool/check.c
parenta358505d8af3ab43763e1b49549619528783d2bf (diff)
parent0f1441b44e823a74f3f3780902a113e07c73fbf6 (diff)
downloadlinux-stable-7ecb59a56666506ebb1197f89ca7d587bd83309e.tar.gz
linux-stable-7ecb59a56666506ebb1197f89ca7d587bd83309e.tar.bz2
linux-stable-7ecb59a56666506ebb1197f89ca7d587bd83309e.zip
Merge tag 'objtool_urgent_for_5.8_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull objtool fixes from Borislav Petkov: "Three fixes from Peter Zijlstra suppressing KCOV instrumentation in noinstr sections. Peter Zijlstra says: "Address KCOV vs noinstr. There is no function attribute to selectively suppress KCOV instrumentation, instead teach objtool to NOP out the calls in noinstr functions" This cures a bunch of KCOV crashes (as used by syzcaller)" * tag 'objtool_urgent_for_5.8_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: objtool: Fix noinstr vs KCOV objtool: Provide elf_write_{insn,reloc}() objtool: Clean up elf_write() condition
Diffstat (limited to 'tools/objtool/check.c')
-rw-r--r--tools/objtool/check.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index d8eaa7dc53d5..5e0d70a89fb8 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -12,6 +12,7 @@
#include "check.h"
#include "special.h"
#include "warn.h"
+#include "arch_elf.h"
#include <linux/hashtable.h>
#include <linux/kernel.h>
@@ -766,6 +767,24 @@ static int add_call_destinations(struct objtool_file *file)
insn->call_dest = rela->sym;
/*
+ * Many compilers cannot disable KCOV with a function attribute
+ * so they need a little help, NOP out any KCOV calls from noinstr
+ * text.
+ */
+ if (insn->sec->noinstr &&
+ !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) {
+ if (rela) {
+ rela->type = R_NONE;
+ elf_write_rela(file->elf, rela);
+ }
+
+ elf_write_insn(file->elf, insn->sec,
+ insn->offset, insn->len,
+ arch_nop_insn(insn->len));
+ insn->type = INSN_NOP;
+ }
+
+ /*
* Whatever stack impact regular CALLs have, should be undone
* by the RETURN of the called function.
*
@@ -2766,7 +2785,7 @@ int check(const char *_objname, bool orc)
objname = _objname;
- file.elf = elf_open_read(objname, orc ? O_RDWR : O_RDONLY);
+ file.elf = elf_open_read(objname, O_RDWR);
if (!file.elf)
return 1;
@@ -2827,7 +2846,9 @@ int check(const char *_objname, bool orc)
ret = create_orc_sections(&file);
if (ret < 0)
goto out;
+ }
+ if (file.elf->changed) {
ret = elf_write(file.elf);
if (ret < 0)
goto out;