Re: objtool warnings for kernel/trace/trace_selftest_dynamic.o

From: Martin Jambor
Date: Wed Dec 19 2018 - 12:31:21 EST


Hi,

On Tue, Dec 18 2018, Josh Poimboeuf wrote:
> On Tue, Dec 18, 2018 at 01:15:40PM +0100, Martin Jambor wrote:
>> I'm afraid I cannot give an opinion what you should do in this case
>> without understanding the problem better. If you can isolate the case
>> where noclone behaves weirdly into a self-contained testcase, I'd be
>> happy to have a look at it.
>
> I whittled it down to a small test case. It turns out the problem is
> caused by the "__optimize__("no-tracer")" atribute, which is used by our
> __noclone macro:

Wonderful, thanks a lot.

>
> # if __has_attribute(__optimize__)
> # define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
> # else
> # define __noclone __attribute__((__noclone__))
> # endif
>
>
> Here's the test case. Notice it skips the frame pointer setup before
> the call to __sanitizer_cov_trace_pc():
>
>
> $ cat test.c
> __attribute__((__optimize__("no-tracer"))) int test(void)
> {
> return 0;
> }
> $ gcc -O2 -fno-omit-frame-pointer -fsanitize-coverage=trace-pc -c -o test.o test.c

Well, it might not be intuitive but the __optimize__ attribute resets to
-O2 optimization defaults and thus drops -fno-omit-frame-pointer on the
floor, so no wonder there is no frame pointer. This applies to other
optimization options you pass on the command line, for example if you
still compile kernel with -fno-strict-aliasing, you get GCC assuming
strict aliasing in functions marked with your __noclone.

> Apparently we are using "no-tracer" because of:
>
>
> commit 95272c29378ee7dc15f43fa2758cb28a5913a06d
> Author: Paolo Bonzini <pbonzini@xxxxxxxxxx>
> Date: Thu Mar 31 09:38:51 2016 +0200
>
> compiler-gcc: disable -ftracer for __noclone functions
>
> -ftracer can duplicate asm blocks causing compilation to fail in
> noclone functions. For example, KVM declares a global variable
> in an asm like
>
> asm("2: ... \n
> .pushsection data \n
> .global vmx_return \n
> vmx_return: .long 2b");
>
> and -ftracer causes a double declaration.

There is no way for a user to reliably prevent a duplication of an
inline assembly statement. The correct fix is to move such statements
to an assembly files. You have disabled tracer which duplicated it in
your case but other passes might do that too in the future.

The correct fix is to put such assembler snippets into separate assembly
files or, if you for for some reason insist on inline assembly, to use
'%=' inline assembler template format string (it is expanded to a number
that is unique in a compilation unit).

Martin