objtool: Fix noinstr vs KCOV

Since many compilers cannot disable KCOV with a function attribute,
help it to NOP out any __sanitizer_cov_*() calls injected in noinstr
code.

This turns:

12:   e8 00 00 00 00          callq  17 <lockdep_hardirqs_on+0x17>
		13: R_X86_64_PLT32      __sanitizer_cov_trace_pc-0x4

into:

12:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
		13: R_X86_64_NONE      __sanitizer_cov_trace_pc-0x4

Just like recordmcount does.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
Peter Zijlstra
2020-06-12 16:05:26 +02:00
parent fdabdd0b05
commit 0f1441b44e
5 changed files with 46 additions and 1 deletions

View File

@@ -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>
@@ -765,6 +766,24 @@ static int add_call_destinations(struct objtool_file *file)
} else
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.