On Mon, Jul 3, 2017 at 6:03 PM, Jeff Law <l...@redhat.com> wrote:
> On 05/29/2017 11:24 PM, Yuri Gribov wrote:
>> On Mon, May 29, 2017 at 8:14 AM, Yuri Gribov <tetra2...@gmail.com> wrote:
>>> Hi all,
>>>
>>> As discussed in
>>> https://sourceware.org/ml/libc-alpha/2017-01/msg00455.html , some
>>> libdl functions rely on return address to figure out the calling
>>> DSO and then use this information in computation (e.g. output of dlsym
>>> depends on which library called it).
>>>
>>> As reported in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66826 this
>>> may break under tailcall optimization i.e. in cases like
>>>
>>>   return dlsym(...);
>>>
>>> Carlos confirmed that they would prefer to have GCC attribute to
>>> prevent tailcalls
>>> (https://sourceware.org/ml/libc-alpha/2017-01/msg00502.html) so there
>>> you go.
>>>
>>> This was bootstrapped on x86_64. Given that this is a minor addition,
>>> I only ran newly added regtests. I hope that's enough (full testsuite
>>> would take a week on my notebook...).
>> Added docs, per Alex's suggestion.
>>
>> -Y
>>
>>
>> 0001-Added-no_tail_call-attribute.patch
>>
>>
>> From 1f4590e7a633c6335512b012578bddba7602b3c9 Mon Sep 17 00:00:00 2001
>> From: Yury Gribov <tetra2...@gmail.com>
>> Date: Sun, 28 May 2017 21:02:20 +0100
>> Subject: [PATCH] Added no_tail_call attribute.
>>
>> gcc/
>> 2017-05-29  Yury Gribov  <tetra2...@gmail.com>
>>
>>       * cgraphunit.c (cgraph_node::expand_thunk): Prevent
>>       tailcalling functions marked with no_tail_call.
>>       * gcc/doc/extend.texi: Document no_tail_call.
>>       * tree-tailcall.c (find_tail_calls): Ditto.
>>       * tree.c (comp_type_attributes): Treat no_tail_call
>>       mismatch as error.
>>
>> gcc/c-family/
>> 2017-05-29  Yury Gribov  <tetra2...@gmail.com>
>>
>>       * c-attribs.c: New attribute.
>>
>> gcc/testsuite/
>> 2017-05-29  Yury Gribov  <tetra2...@gmail.com>
>>
>>       * gcc.dg/pr66826-1.c: New test.
>>       * gcc.dg/pr66826-2.c: New test.
> I think a "no_tail_call" attribute is quite reasonable -- more so than
> some asm hack to prevent tail calling.

Thanks! Frankly I lost my hope on this...

>> ---
>>  gcc/c-family/c-attribs.c         |  1 +
>>  gcc/cgraphunit.c                 |  6 ++++--
>>  gcc/doc/extend.texi              |  7 +++++++
>>  gcc/testsuite/gcc.dg/pr66826-1.c | 14 ++++++++++++++
>>  gcc/testsuite/gcc.dg/pr66826-2.c |  6 ++++++
>>  gcc/tree-tailcall.c              |  4 ++++
>>  gcc/tree.c                       |  7 ++++---
>>  7 files changed, 40 insertions(+), 5 deletions(-)
>>  create mode 100644 gcc/testsuite/gcc.dg/pr66826-1.c
>>  create mode 100644 gcc/testsuite/gcc.dg/pr66826-2.c
>>
>> diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
>> index 695c58c..482db00 100644
>> --- a/gcc/c-family/c-attribs.c
>> +++ b/gcc/c-family/c-attribs.c
>> @@ -345,6 +345,7 @@ const struct attribute_spec c_common_attribute_table[] =
>>                             handle_bnd_instrument, false },
>>    { "fallthrough",         0, 0, false, false, false,
>>                             handle_fallthrough_attribute, false },
>> +  { "no_tail_call",           0, 0, false, true, true, NULL, true },
> Is no_tail_call supposed to be attached to the function's decl or type?
>
> ISTM this is most similar to noclone, noinline, no_icf and friends which
> seem to attach the attribute to the decl rather than to the type.

Glibc people were worried that attribute would be lost when taking a
pointer to function
(https://sourceware.org/ml/libc-alpha/2017-01/msg00482.html). I think
their reasoning was that return address is a shadow argument for
dlsym-like functions so this would cause a (most likely inadvertent)
ABI error.

>>    { NULL,                     0, 0, false, false, false, NULL, false }
>>  };
>>
>> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
>> index 4a949ca..e23fd21 100644
>> --- a/gcc/cgraphunit.c
>> +++ b/gcc/cgraphunit.c
>> @@ -1823,6 +1824,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, 
>> bool force_gimple_thunk)
>>        callees->call_stmt = call;
>>        gimple_call_set_from_thunk (call, true);
>>        gimple_call_set_with_bounds (call, instrumentation_clone);
>> +      no_tail_call_p = lookup_attribute ("no_tail_call", TYPE_ATTRIBUTES 
>> (gimple_call_fntype (call)));
> And I think the answer to the question above potentially impacts this
> chunk of code.  If we were to change the attribute to apply to the decl,
> then you'd need to look at the decl here rather than its type.
>
>
>> index f586edc..30a6fad 100644
>> --- a/gcc/tree-tailcall.c
>> +++ b/gcc/tree-tailcall.c
>> @@ -601,6 +601,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
>>    if (m && POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
>>      return;
>>
>> +  /* See if function does not want to be tailcalled.  */
>> +  if (lookup_attribute ("no_tail_call", TYPE_ATTRIBUTES (gimple_call_fntype 
>> (call))))
>> +    return;
> Similarly and perhaps in other locations as well.
>
> THoughts?
>
> jeff

Reply via email to