linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
To: Nick Desaulniers <ndesaulniers@google.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Eli Friedman <efriedma@codeaurora.org>,
	Christopher Li <sparse@chrisli.org>,
	Kees Cook <keescook@chromium.org>, Ingo Molnar <mingo@kernel.org>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Arnd Bergmann <arnd@arndb.de>,
	Greg KH <gregkh@linuxfoundation.org>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	Joe Perches <joe@perches.com>,
	Dominique Martinet <asmadeus@codewreck.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] include/linux/compiler*.h: Use feature checking instead of version checks for attributes
Date: Tue, 28 Aug 2018 17:10:31 +0200	[thread overview]
Message-ID: <CANiq72nV_sVGgQuZra2gqOXHnbtCYWZDBMRW=EeeLK3qTL99ew@mail.gmail.com> (raw)
In-Reply-To: <CAKwvOdk3PjNtjMcsXxRVvKLNcT+O_=5D1B7DXNWcwxwcMqdV2w@mail.gmail.com>

Hi Nick,

On Mon, Aug 27, 2018 at 7:48 PM, Nick Desaulniers
<ndesaulniers@google.com> wrote:
> On Mon, Aug 27, 2018 at 10:43 AM Nick Desaulniers
>> > +
>> > +/*
>> > + * Optional attributes: your compiler may or may not support them.
>> > + *
>> > + * To check for them, we use __has_attribute, which is supported on gcc >= 5,
>> > + * clang >= 2.9 and icc >= 17. In the meantime, to support 4.6 <= gcc < 5,
>> > + * we implement it by hand.
>> > + */
>> > +#ifndef __has_attribute
>> > +#define __has_attribute(x) __GCC46_has_attribute_##x
>> > +#define __GCC46_has_attribute_assume_aligned 0
>> > +#define __GCC46_has_attribute_designated_init 0
>> > +#define __GCC46_has_attribute_externally_visible 1
>> > +#define __GCC46_has_attribute_noclone 1
>> > +#define __GCC46_has_attribute_optimize 1
>> > +#define __GCC46_has_attribute_no_sanitize_address 0
>> > +#endif
>
> And a follow up; I'm trying to understand what will happen in the case
> of say gcc 4.9 here.  Were any of these supported between gcc 4.6 and
> 5.0?  If so, then this code will not use them.  It's simpler than
> explicit version checks, but it won't use features that are supported.
>

I addressed that in the email I sent afterwards:

"""
Note that:
  - assume_aligned came with gcc 4.9
  - no_sanitize_address came with gcc 4.8

So if we feel it is important to have them there (before gcc 5), we
would need here a quick version check here.
"""

The idea is that, in the future, whenever gcc 5 or later is the
minimum version, we just get rid of the #ifdef block without touching
the rest of the code :-)

Cheers,
Miguel

>> > +
>> > +/*
>> > + * __assume_aligned(n, k): Tell the optimizer that the returned
>> > + * pointer can be assumed to be k modulo n. The second argument is
>> > + * optional (default 0), so we use a variadic macro to make the
>> > + * shorthand.
>> > + *
>> > + * Beware: Do not apply this to functions which may return
>> > + * ERR_PTRs. Also, it is probably unwise to apply it to functions
>> > + * returning extra information in the low bits (but in that case the
>> > + * compiler should see some alignment anyway, when the return value is
>> > + * massaged by 'flags = ptr & 3; ptr &= ~3;').
>> > + */
>> > +#if __has_attribute(assume_aligned)
>> > +#define __assume_aligned(a, ...) __attribute__((assume_aligned(a, ## __VA_ARGS__)))
>> > +#else
>> > +#define __assume_aligned(a, ...)
>> > +#endif
>> > +
>> > +/*
>> > + * Mark structures as requiring designated initializers.
>> > + * https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
>> > + */
>> > +#if __has_attribute(designated_init)
>> > +#define __designated_init __attribute__((designated_init))
>> > +#else
>> > +#define __designated_init
>> > +#endif
>> > +
>> > +/*
>> > + * When used with Link Time Optimization, gcc can optimize away C functions or
>> > + * variables which are referenced only from assembly code.  __visible tells the
>> > + * optimizer that something else uses this function or variable, thus preventing
>> > + * this.
>> > + */
>> > +#if __has_attribute(externally_visible)
>> > +#define __visible __attribute__((externally_visible))
>> > +#else
>> > +#define __visible
>> > +#endif
>> > +
>> > +/* Mark a function definition as prohibited from being cloned. */
>> > +#if __has_attribute(noclone) && __has_attribute(optimize)
>> > +#define __noclone __attribute__((noclone, optimize("no-tracer")))
>> > +#else
>> > +#define __noclone
>> > +#endif
>> > +
>> > +/*
>> > + * Tell the compiler that address safety instrumentation (KASAN)
>> > + * should not be applied to that function.
>> > + * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
>> > + */
>> > +#if __has_attribute(no_sanitize_address)
>> > +#define __no_sanitize_address __attribute__((no_sanitize_address))
>> > +#else
>> > +#define __no_sanitize_address
>> > +#endif
>> > +
>> > +#endif /* __LINUX_COMPILER_ATTRIBUTES_H */
>> > diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
>> > index 3525c179698c..8cd622bedec4 100644
>> > --- a/include/linux/compiler_types.h
>> > +++ b/include/linux/compiler_types.h
>> > @@ -54,6 +54,9 @@ extern void __chk_io_ptr(const volatile void __iomem *);
>> >
>> >  #ifdef __KERNEL__
>> >
>> > +/* Attributes */
>> > +#include <linux/compiler_attributes.h>
>> > +
>> >  /* Compiler specific macros. */
>> >  #ifdef __clang__
>> >  #include <linux/compiler-clang.h>
>> > @@ -78,12 +81,6 @@ extern void __chk_io_ptr(const volatile void __iomem *);
>> >  #include <asm/compiler.h>
>> >  #endif
>> >
>> > -/*
>> > - * Generic compiler-independent macros required for kernel
>> > - * build go below this comment. Actual compiler/compiler version
>> > - * specific implementations come from the above header files
>> > - */
>> > -
>> >  struct ftrace_branch_data {
>> >         const char *func;
>> >         const char *file;
>> > @@ -119,10 +116,6 @@ struct ftrace_likely_data {
>> >   * compilers. We don't consider that to be an error, so set them to nothing.
>> >   * For example, some of them are for compiler specific plugins.
>> >   */
>> > -#ifndef __designated_init
>> > -# define __designated_init
>> > -#endif
>> > -
>> >  #ifndef __latent_entropy
>> >  # define __latent_entropy
>> >  #endif
>> > @@ -140,17 +133,6 @@ struct ftrace_likely_data {
>> >  # define randomized_struct_fields_end
>> >  #endif
>> >
>> > -#ifndef __visible
>> > -#define __visible
>> > -#endif
>> > -
>> > -/*
>> > - * Assume alignment of return value.
>> > - */
>> > -#ifndef __assume_aligned
>> > -#define __assume_aligned(a, ...)
>> > -#endif
>> > -
>> >  /* Are two types/vars the same type (ignoring qualifiers)? */
>> >  #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
>> >
>> > @@ -159,14 +141,6 @@ struct ftrace_likely_data {
>> >         (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
>> >          sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
>> >
>> > -#ifndef __attribute_const__
>> > -#define __attribute_const__    __attribute__((__const__))
>> > -#endif
>> > -
>> > -#ifndef __noclone
>> > -#define __noclone
>> > -#endif
>> > -
>> >  /* Helpers for emitting diagnostics in pragmas. */
>> >  #ifndef __diag
>> >  #define __diag(string)
>> > @@ -186,34 +160,6 @@ struct ftrace_likely_data {
>> >  #define __diag_error(compiler, version, option, comment) \
>> >         __diag_ ## compiler(version, error, option)
>> >
>> > -/*
>> > - * From the GCC manual:
>> > - *
>> > - * Many functions have no effects except the return value and their
>> > - * return value depends only on the parameters and/or global
>> > - * variables.  Such a function can be subject to common subexpression
>> > - * elimination and loop optimization just as an arithmetic operator
>> > - * would be.
>> > - * [...]
>> > - */
>> > -#define __pure                 __attribute__((pure))
>> > -#define __aligned(x)           __attribute__((aligned(x)))
>> > -#define __aligned_largest      __attribute__((aligned))
>> > -#define __printf(a, b)         __attribute__((format(printf, a, b)))
>> > -#define __scanf(a, b)          __attribute__((format(scanf, a, b)))
>> > -#define __maybe_unused         __attribute__((unused))
>> > -#define __always_unused                __attribute__((unused))
>> > -#define __mode(x)              __attribute__((mode(x)))
>> > -#define __malloc               __attribute__((__malloc__))
>> > -#define __used                 __attribute__((__used__))
>> > -#define __noreturn             __attribute__((noreturn))
>> > -#define __packed               __attribute__((packed))
>> > -#define __weak                 __attribute__((weak))
>> > -#define __alias(symbol)                __attribute__((alias(#symbol)))
>> > -#define __cold                 __attribute__((cold))
>> > -#define __section(S)           __attribute__((__section__(#S)))
>> > -
>> > -
>> >  #ifdef CONFIG_ENABLE_MUST_CHECK
>> >  #define __must_check           __attribute__((warn_unused_result))
>> >  #else
>> > @@ -228,18 +174,6 @@ struct ftrace_likely_data {
>> >
>> >  #define __compiler_offsetof(a, b)      __builtin_offsetof(a, b)
>> >
>> > -/*
>> > - * Feature detection for gnu_inline (gnu89 extern inline semantics). Either
>> > - * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics,
>> > - * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not
>> > - * defined so the gnu89 semantics are the default.
>> > - */
>> > -#ifdef __GNUC_STDC_INLINE__
>> > -# define __gnu_inline  __attribute__((gnu_inline))
>> > -#else
>> > -# define __gnu_inline
>> > -#endif
>> > -
>> >  /*
>> >   * Force always-inline if the user requests it so via the .config.
>> >   * GCC does not warn about unused static inline functions for
>> > @@ -254,19 +188,13 @@ struct ftrace_likely_data {
>> >   */
>> >  #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \
>> >         !defined(CONFIG_OPTIMIZE_INLINING)
>> > -#define inline \
>> > -       inline __attribute__((always_inline, unused)) notrace __gnu_inline
>> > +#define inline inline __attribute__((always_inline, unused)) notrace __gnu_inline
>> >  #else
>> > -#define inline inline  __attribute__((unused)) notrace __gnu_inline
>> > +#define inline inline __attribute__((unused)) notrace __gnu_inline
>> >  #endif
>> >
>> >  #define __inline__ inline
>> > -#define __inline inline
>> > -#define noinline       __attribute__((noinline))
>> > -
>> > -#ifndef __always_inline
>> > -#define __always_inline inline __attribute__((always_inline))
>> > -#endif
>> > +#define __inline   inline
>>
>> All of the changes to inline should not be removed, see above.  It's
>> important to make this work correctly regardless of C standard used.
>>
>> >
>> >  /*
>> >   * Rather then using noinline to prevent stack consumption, use
>> > @@ -274,4 +202,11 @@ struct ftrace_likely_data {
>> >   */
>> >  #define noinline_for_stack noinline
>> >
>> > +#ifdef __CHECKER__
>> > +#define __must_be_array(a) 0
>> > +#else
>> > +/* &a[0] degrades to a pointer: a different type from an array */
>> > +#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
>> > +#endif
>> > +
>> >  #endif /* __LINUX_COMPILER_TYPES_H */
>> > --
>> > 2.17.1
>> >
>>
>> With the above changes requested, I'm super happy with the spirit of
>> this patch, and look forward to a v2.  Thanks again Miguel!
>> --
>> Thanks,
>> ~Nick Desaulniers
>
>
>
> --
> Thanks,
> ~Nick Desaulniers

  reply	other threads:[~2018-08-28 15:10 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-26 17:57 [PATCH] include/linux/compiler*.h: Use feature checking instead of version checks for attributes Miguel Ojeda
2018-08-26 18:30 ` Miguel Ojeda
2018-08-26 18:50 ` Joe Perches
2018-08-27 12:33   ` Miguel Ojeda
2018-08-27 17:43 ` Nick Desaulniers
2018-08-27 17:48   ` Nick Desaulniers
2018-08-28 15:10     ` Miguel Ojeda [this message]
2018-08-28 17:05       ` Nick Desaulniers
2018-08-28 20:33         ` Miguel Ojeda
2018-08-28 15:03   ` Miguel Ojeda
2018-08-28 16:53     ` Nick Desaulniers
2018-08-28 20:41       ` Miguel Ojeda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CANiq72nV_sVGgQuZra2gqOXHnbtCYWZDBMRW=EeeLK3qTL99ew@mail.gmail.com' \
    --to=miguel.ojeda.sandonis@gmail.com \
    --cc=arnd@arndb.de \
    --cc=asmadeus@codewreck.org \
    --cc=efriedma@codeaurora.org \
    --cc=geert@linux-m68k.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=joe@perches.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=sparse@chrisli.org \
    --cc=torvalds@linux-foundation.org \
    --cc=yamada.masahiro@socionext.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).