Messages in this thread | | | Date | Wed, 20 Sep 2017 12:54:05 -0500 | From | Josh Poimboeuf <> | Subject | Re: [PATCH 2/2] x86/asm: Fix inline asm call constraints for clang |
| |
On Tue, Sep 19, 2017 at 08:18:23PM -0500, Josh Poimboeuf wrote: > On Tue, Sep 19, 2017 at 01:45:28PM -0500, Josh Poimboeuf wrote: > > For inline asm statements which have a CALL instruction, we list the > > stack pointer as a constraint to convince GCC to ensure the frame > > pointer is set up first: > > > > static inline void foo() > > { > > register void *__sp asm(_ASM_SP); > > asm("call bar" : "+r" (__sp)) > > } > > > > Unfortunately, that pattern causes clang to corrupt the stack pointer. > > > > There's actually an easier way to achieve the same goal in GCC, without > > causing trouble for clang. If we declare the stack pointer register > > variable as a global variable, and remove the constraint altogether, > > that convinces GCC to always set up the frame pointer before inserting > > *any* inline asm. > > > > It basically acts as if *every* inline asm statement has a CALL > > instruction. It's a bit overkill, but the performance impact should be > > negligible. > > > > Here are the vmlinux .text size differences with the following configs > > on GCC: > > > > - defconfig > > - defconfig without frame pointers > > - Fedora distro config > > - Fedora distro config without frame pointers > > > > defconfig defconfig-nofp distro distro-nofp > > before 9796300 9466764 9076191 8789745 > > after 9796941 9462859 9076381 8785325 > > > > With frame pointers, the text size increases slightly. Without frame > > pointers, the text size decreases, and a little more significantly. > > > > Reported-by: Matthias Kaehlcke <mka@chromium.org> > > Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> > > NAK - kbuild bot is reporting some cases where this patch doesn't force > the frame pointer setup.
So it turns out that for GCC 7, it works as described above: the global register variable results in the frame pointer getting set up before *all* inline asm.
But for GCC 6, it doesn't work that way. The global register variable has no such effect.
So we need both the global register variable *and* the output constraint after all. Will post another patch after some more testing.
-- Josh
| |