linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nick Desaulniers <ndesaulniers@google.com>
To: hpa@zytor.com
Cc: Alistair Strachan <astrachan@google.com>,
	Manoj Gupta <manojgupta@google.com>,
	Matthias Kaehlcke <mka@google.com>,
	Greg Hackmann <ghackmann@google.com>,
	sedat.dilek@gmail.com, tstellar@redhat.com,
	LKML <linux-kernel@vger.kernel.org>,
	Kees Cook <keescook@google.com>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	Michal Marek <michal.lkml@markovi.net>,
	Linux Kbuild mailing list <linux-kbuild@vger.kernel.org>
Subject: Re: [clang] stack protector and f1f029c7bf
Date: Wed, 30 May 2018 23:50:28 -0700	[thread overview]
Message-ID: <CAKwvOd=FN0G-zs-DMF3ubs8y9-PDEamfi__P_iv_JgN3bH6qFw@mail.gmail.com> (raw)
In-Reply-To: <CAKwvOdkurUGcSAGjR8_nDRgHLFLj93E1wAA3+O0A+pKPHvzwRA@mail.gmail.com>

On Fri, May 25, 2018 at 3:38 PM Nick Desaulniers
<ndesaulniers@google.com> wrote:
>
> On Fri, May 25, 2018 at 2:06 PM H. Peter Anvin <hpa@zytor.com> wrote:
> > On 05/25/18 13:36, Nick Desaulniers wrote:
> > > On Fri, May 25, 2018 at 10:56 AM <hpa@zytor.com> wrote:
> > >> You need the extern inline in the .h file and the out-of-line .S file
> > > I don't see how you can specify to the linker from assembly source that
> > > this function should be treated as `extern inline`?
> > "extern inline" is a C directive. In the header file you should provide
> > the inlinable implementation (which is already there.) It means that "if
> > you don't want to inline this there is an external implementation
> > available."
>
> oh you put `extern inline` on the definition, not the declaration?! What?!
>
> http://m68hc11.serveftp.org/inline-1.php
>
> in fact documents that trick.  Wow, I've never seen that before.  Seems
> like there's not too many instances in the kernel.
>
> This seems to inline native_save_fl() properly into the call sites, but the
> boot code now fails to link due to multiple definitions when trying link
> the objects from arch/x86/boot/compressed/ into vmlinux.
>
> When disassembling the the arch/x86/boot/compressed/ objects, I can see
> they're pulling in the `extern inline` c versions, but still outlining
> them! (gcc and clang).
>
> That seems to contradict the statement from the above link:
> "In no case is the function compiled on its own, not even if you refer to
> its address explicitly"
>
> This is kind of funny; first we were wondering why native_save_fl was
> getting outlined as a static inline function, which Alistair tracked down
> to the incorrect use as a function pointer. Now I'm playing why is
> native_save_fl getting outlined as an extern inline function.
>
> If I move the .S file to be in arch/x86/kernel/boot/compressed, the boot
> code now links but then paravirt.o fails to link.  Referring to the .S from
> both Makefiles results in multiple definitions that the linker doesn't
> like. (and the boot code still containing outlines).
>
> I don't understand how `extern inline` signals to the linker that "this
> version should be taken if you find no others".  From what I can tell with
> `readelf -a` and `objdump -d`, a function marked `extern inline` vs not
> look similar.
>
> Then again, arch/x86/boot/compressed/Makefile completely resets
> KBUILD_CFLAGS and KBUILD_AFLAGS, which may be problematic (if there's some
> kind of command line flag that affects `extern inline` linkage).

Aha! This (wiping away CFLAGS) was it!  The rules for `extern inline`
for gnu89 and c99 are exactly the opposite! [0][1]

c99: "a function defined extern inline will always, emit an externally
visible function."

but then

gnu89: "gnu89 semantics of inline and extern inline are essentially
the exact opposite of those in C99"

This is elaborated more concisely in [2].

If I add `-std=gnu89` to the KBUILD_CFLAGS for compilation units that
are missing that flag but include irqflags.h, I stop getting multiple
definition linkage errors and link the expected kernel image!

This is something to seriously consider for whoever might ever want to
change the kernel's C standard: that you'll end up flipping the
semantics of `extern inline`.  Sounds like `-fgnu89-inline` compiler
flag or `gnu_inline` attribute could be used to correct such a
situation.

+ KBUILD maintainers and mailing list.

Completely overwriting the KBUILD_CFLAGS from sub directory Makefiles
(using the := operator) has been making me feel uneasy, since we very
carefully try to set the necessary flags for Clang in the top level
Makefile.  In this case, the C standard is different for at least 2
subdirectories, which has implications for at least the above case
with the linkage of `extern inline` functions.

Will do further testing and cut a patch set tomorrow.

[0] https://en.wikipedia.org/wiki/Inline_function#C99
[1] https://en.wikipedia.org/wiki/Inline_function#gnu89
[2] http://blahg.josefsipek.net/?p=529
-- 
Thanks,
~Nick Desaulniers

  reply	other threads:[~2018-05-31  6:50 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-23 22:08 [clang] stack protector and f1f029c7bf Nick Desaulniers
2018-05-24 10:33 ` Sedat Dilek
2018-05-24 18:12   ` Nick Desaulniers
2018-05-24 18:19 ` hpa
2018-05-24 18:24   ` Nick Desaulniers
2018-05-24 18:48     ` Alistair Strachan
2018-05-24 19:49   ` Tom Stellard
2018-05-24 21:33     ` hpa
2018-05-24 18:59 ` hpa
2018-05-24 20:26   ` Nick Desaulniers
2018-05-24 20:52     ` Nick Desaulniers
2018-05-24 21:12       ` Nick Desaulniers
2018-05-24 21:27         ` Nick Desaulniers
2018-05-24 21:56           ` H. Peter Anvin
2018-05-24 21:49         ` H. Peter Anvin
2018-05-24 21:38       ` hpa
2018-05-24 22:05     ` H. Peter Anvin
2018-05-24 22:31       ` Nick Desaulniers
2018-05-24 22:43         ` hpa
2018-05-25 16:27           ` Nick Desaulniers
2018-05-25 16:32             ` hpa
2018-05-25 16:46               ` Nick Desaulniers
2018-05-25 16:53                 ` hpa
2018-05-25 17:31                   ` Nick Desaulniers
2018-05-25 17:35                     ` Tom Stellard
2018-05-25 17:49                       ` Nick Desaulniers
2018-05-25 17:57                         ` hpa
2018-05-25 17:59                         ` Nick Desaulniers
2018-05-25 17:56                     ` hpa
2018-05-25 20:36                       ` Nick Desaulniers
2018-05-25 21:06                         ` H. Peter Anvin
2018-05-25 22:38                           ` Nick Desaulniers
2018-05-31  6:50                             ` Nick Desaulniers [this message]
2018-06-01 17:13                               ` Nick Desaulniers
2018-05-25 16:34             ` hpa
2018-05-25  8:24     ` Sedat Dilek

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='CAKwvOd=FN0G-zs-DMF3ubs8y9-PDEamfi__P_iv_JgN3bH6qFw@mail.gmail.com' \
    --to=ndesaulniers@google.com \
    --cc=astrachan@google.com \
    --cc=ghackmann@google.com \
    --cc=hpa@zytor.com \
    --cc=keescook@google.com \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=manojgupta@google.com \
    --cc=michal.lkml@markovi.net \
    --cc=mka@google.com \
    --cc=sedat.dilek@gmail.com \
    --cc=tstellar@redhat.com \
    --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).