Re: [PATCH 3/6] tracing: Wrap section comparison in tracer_alloc_buffers with COMPARE_SECTIONS

From: Nathan Chancellor
Date: Wed Feb 19 2020 - 14:22:54 EST


On Wed, Feb 19, 2020 at 11:11:19AM -0800, Nick Desaulniers wrote:
> On Wed, Feb 19, 2020 at 10:16 AM Jason Gunthorpe <jgg@xxxxxxxx> wrote:
> >
> > On Wed, Feb 19, 2020 at 09:44:31AM -0800, Nick Desaulniers wrote:
> > > Hey Nathan,
> > > Thanks for the series; enabling the warning will help us find more
> > > bugs. Revisiting what the warning is about, I checked on this
> > > "referring to symbols defined in linker scripts from C" pattern. This
> > > document [0] (by no means definitive, but I think it has a good idea)
> > > says:
> > >
> > > Linker symbols that represent a data address: In C code, declare the
> > > variable as an extern variable. Then, refer to the value of the linker
> > > symbol using the & operator. Because the variable is at a valid data
> > > address, we know that a data pointer can represent the value.
> > > Linker symbols for an arbitrary address: In C code, declare this as an
> > > extern symbol. The type does not matter. If you are using GCC
> > > extensions, declare it as "extern void".
> > >
> > > Indeed, it seems that Clang is happier with that pattern:
> > > https://godbolt.org/z/sW3t5W
> > >
> > > Looking at __stop___trace_bprintk_fmt in particular:
> > >
> > > kernel/trace/trace.h
> > > 1923:extern const char *__stop___trace_bprintk_fmt[];
> >
> > Godbolt says clang is happy if it is written as:
> >
> > if (&__stop___trace_bprintk_fmt[0] != &__start___trace_bprintk_fmt[0])
> >
> > Which is probably the best compromise. The type here is const char
> > *[], so it would be a shame to see it go.
>
> If the "address" is never dereferenced, but only used for arithmetic
> (in a way that the the pointed to type is irrelevant), does the
> pointed to type matter? I don't feel strongly either way, but we seem
> to have found two additional possible solutions for these warnings,
> which is my ultimate goal. Nathan, hopefully those are some ideas you
> can work with to address the additional cases throughout the kernel?
>
> --
> Thanks,
> ~Nick Desaulniers

Yes, thank you for the analysis and further discussion! I have done some
rudimentary printk debugging in QEMU and it looks like these are produce
the same value:

__stop___trace_bprintk_fmt
&__stop___trace_bprintk_fmt
&__start___trace_bprintk_fmt[0]

as well as

__stop___trace_bprintk_fmt != __start___trace_bprintk_fmt
&__stop___trace_bprintk_fmt != &__start___trace_bprintk_fmt
&__stop___trace_bprintk_fmt[0] != &__start___trace_bprintk_fmt[0]

I'll use the second one once I confirm this is true in all callspots
with both Clang and GCC, since it looks cleaner. Let me know if there
are any objections to that.

Cheers,
Nathan