[llvm-dev] what are the rules about ssp function attributes?

Fāng-ruì Sòng via llvm-dev llvm-dev at lists.llvm.org
Wed Dec 16 21:40:13 PST 2020


On Wed, Dec 16, 2020 at 7:59 PM Andrew Kelley <andrew at ziglang.org> wrote:
>
> On 12/16/20 4:06 PM, Fāng-ruì Sòng wrote:
> > LangRef needs to be clarified. Sent https://reviews.llvm.org/D93422
> >
>
> Thanks for the improved docs!
>
> > The behavior change was due to https://reviews.llvm.org/D91816 . How
> > does Zig end up merging the attributes
> > while the inliner blocks such inlining?
>
> Here is the zig code in question:
>
> fn llshl(r: []Limb, a: []const Limb, shift: usize) void {
>      @setRuntimeSafety(debug_safety);
> ...
>          r[dst_i] = carry | @call(.{ .modifier = .always_inline },
> math.shr, .{
> ...
>
>
> So we have an "always inline" call from a function which has runtime
> safety disabled. Currently, having runtime safety off for a function
> means that it does not get "sspstrong" attribute.

Yes, alwaysinline takes precedence. (Updated my patch to mention this...)

> In this particular code snippet the ideal behavior from zig's
> perspective would be if LLVM allowed the always_inline without the ssp
> attribute, and then did the thing that the new docs mention:
>
>  > If a function with
>  > the ``sspstrong`` attribute is inlined into a function with the
>  > ``ssp`` attribute, the attribute in the caller will upgrade to
>  > ``sspstrong``.
>
> Otherwise, Zig will need to keep track of callees and then recursively
> figure out whether an inline call prevents omitting stack protection
> attributes. Doable, but repeating the work the LLVM pass is already doing.
>
> > If a caller without ssp inlines a callee with ssp:
> >    the caller may alter %gs for its own purposes
> >    and will break the %gs usage in the callee.
> > (This one is required by the Linux kernel).
>
> Wait a minute though, I don't understand why this needs to be the case.
> If a caller without ssp inlines a callee with it, then it seems to me
> that it should remove the ssp attribute from the callee at the callsite.
>
> The %gs/Linux thing makes it sound like ssp is an ABI guarantee rather
> than a safety mechanism.

I think the kernel idea is that the caller (no ssp) may not have set
%gs (during its initialization process), so upgrading from nossp to
ssp
may break the caller.
The kernel thread
https://lore.kernel.org/linux-pm/20200915172658.1432732-1-rkir@google.com/T/#u
is long and I haven't read it through, though....

I think your Zig issue may be an undiscovered bug. Can you file a bug
and attach the .ll file?

The new Clang behavior also disallows a nossp callee from being
inlined into a ssp caller. That makes the rules easier to explain but
I haven't thought very clearly about the implications though.


> I suppose "always inline" should be implemented by zig itself before
> generating LLVM IR, and then it will get to decide how inlining works.
>
> Anyway, thanks for your time and for the information.
> Andrew
>
> >
> > If a ssp caller inlines a callee without ssp:
> >    This one is a bit unclear to me why it needs to have such semantics,
> > probably because
> >    the callee expresses an intention (no ssp) and the caller should respect it.
> >
>


-- 
宋方睿


More information about the llvm-dev mailing list