On Fri, Jun 12, 2020 at 4:37 PM Peter Zijlstra <pet...@infradead.org> wrote: > > 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) <pet...@infradead.org>
Acked-by: Dmitry Vyukov <dvyu...@google.com> Thanks! > --- > tools/objtool/arch.h | 2 ++ > tools/objtool/arch/x86/decode.c | 18 ++++++++++++++++++ > tools/objtool/arch/x86/include/arch_elf.h | 6 ++++++ > tools/objtool/check.c | 19 +++++++++++++++++++ > 4 files changed, 45 insertions(+) > > --- a/tools/objtool/arch.h > +++ b/tools/objtool/arch.h > @@ -84,4 +84,6 @@ unsigned long arch_jump_destination(stru > > unsigned long arch_dest_reloc_offset(int addend); > > +const char *arch_nop_insn(int len); > + > #endif /* _ARCH_H */ > --- a/tools/objtool/arch/x86/decode.c > +++ b/tools/objtool/arch/x86/decode.c > @@ -565,3 +565,21 @@ void arch_initial_func_cfi_state(struct > state->regs[16].base = CFI_CFA; > state->regs[16].offset = -8; > } > + > +const char *arch_nop_insn(int len) > +{ > + static const char nops[5][5] = { > + /* 1 */ { 0x90 }, > + /* 2 */ { 0x66, 0x90 }, > + /* 3 */ { 0x0f, 0x1f, 0x00 }, > + /* 4 */ { 0x0f, 0x1f, 0x40, 0x00 }, > + /* 5 */ { 0x0f, 0x1f, 0x44, 0x00, 0x00 }, > + }; > + > + if (len < 1 || len > 5) { > + WARN("invalid NOP size: %d\n", len); > + return NULL; > + } > + > + return nops[len-1]; > +} > --- /dev/null > +++ b/tools/objtool/arch/x86/include/arch_elf.h > @@ -0,0 +1,6 @@ > +#ifndef _OBJTOOL_ARCH_ELF > +#define _OBJTOOL_ARCH_ELF > + > +#define R_NONE R_X86_64_NONE > + > +#endif /* _OBJTOOL_ARCH_ELF */ > --- 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> > @@ -744,6 +745,24 @@ static int add_call_destinations(struct > insn->call_dest = reloc->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 (reloc) { > + reloc->type = R_NONE; > + elf_write_reloc(file->elf, reloc); > + } > + > + 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. > * > >