PATCH: Add ifunc attribute

classic Classic list List threaded Threaded
56 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
On Wed, Jun 24, 2009 at 2:59 AM, Richard
Guenther<[hidden email]> wrote:

> On Tue, Jun 23, 2009 at 7:19 PM, H.J. Lu<[hidden email]> wrote:
>> Hi,
>>
>> I opened a bug report:
>>
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40528
>>
>> with the third proposal:
>>
>> 3. Ifunc attribute with prototype, but without argument:
>>
>> int
>> __attribute__ ((ifunc))
>> foo (...)
>> {
>>  <return address of foo_{1,2,3}>
>> }
>>
>> We can call foo in the same file. Gcc checks the return value for
>> foo.
>>
>> Any comments?
>
> I don't understand this third proposal.
>
> Richard.
>

We can have

---
static int
foo1 (int x)
{
  return x;
}

int
__attribute__ ((ifunc))
foo (int)
{
  return foo1;
}

int
bar (int i)
{
  return foo (i);
}
---

In the body of an ifunc function, return type is changed to pointer
to function prototype with

/* Get the function return type inside function body.  Return a pointer
   to the function for IFUNC function.  */

static inline tree
function_return_type (const_tree decl)
{
  if (TREE_IFUNC_NAME (DECL_NAME (decl)))
    return build_pointer_type (TREE_TYPE (decl));
  else
    return TREE_TYPE (TREE_TYPE (decl));
}



--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
In reply to this post by Paolo Bonzini-2
On Wed, Jun 24, 2009 at 3:22 AM, Paolo Bonzini<[hidden email]> wrote:

> Richard Guenther wrote:
>>
>> On Tue, Jun 23, 2009 at 7:19 PM, H.J. Lu<[hidden email]> wrote:
>>>
>>> Hi,
>>>
>>> I opened a bug report:
>>>
>>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40528
>>>
>>> with the third proposal:
>>>
>>> 3. Ifunc attribute with prototype, but without argument:
>>>
>>> int
>>> __attribute__ ((ifunc))
>>> foo (...)
>>> {
>>>  <return address of foo_{1,2,3}>
>>> }
>>>
>>> We can call foo in the same file. Gcc checks the return value for
>>> foo.
>>>
>>> Any comments?
>>
>> I don't understand this third proposal.
>
> "int foo (...)" is only declared as a prototype and with the ifunc attribute
> dropped.  The body of the function is actually compiled to .ifunc.foo or
> something like that, with a signature
>
> __typeof(foo) __attribute__ ((ifunc)) .ifunc.foo(void)
>
> and with ".gnu.indirect.function .ifunc.foo" emitted in the assembly instead
> of ".function".
>
> Via some magic mechanism, a further redeclaration of foo is prohibited.
>
> Looks a bit too like DWIM and too little like a specification.  I think I
> prefer option 1, in some cases you may want to call the trampoline and
> having it accessible can help.  With
>
> __typeof (foo) *
> __attribute__ ((ifunc ("foo")))
> foo_ifunc (void)
> {
>  <return address of foo_{1,2,3}>
> }
>
> you could call foo_ifunc if you wish in principle, and the header file only
> has the prototype of foo as expected.

Since foo_ifunc isn't generated, you can't call foo_ifunc.


--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Paolo Bonzini-2

>> __typeof (foo) *
>> __attribute__ ((ifunc ("foo")))
>> foo_ifunc (void)
>> {
>>  <return address of foo_{1,2,3}>
>> }
>>
>> you could call foo_ifunc if you wish in principle, and the header file only
>> has the prototype of foo as expected.
>
> Since foo_ifunc isn't generated, you can't call foo_ifunc.

So I guess mine is the fourth proposal. :-)  Same as 1, but also
generate foo_ifunc, for example via an alias.

However, there is an additional catch.  What happens in option 1 if
foo_ifunc is static?  With mine, foo would not be static but foo_ifunc
would be.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
On Wed, Jun 24, 2009 at 6:16 AM, Paolo Bonzini<[hidden email]> wrote:

>
>>> __typeof (foo) *
>>> __attribute__ ((ifunc ("foo")))
>>> foo_ifunc (void)
>>> {
>>>  <return address of foo_{1,2,3}>
>>> }
>>>
>>> you could call foo_ifunc if you wish in principle, and the header file
>>> only
>>> has the prototype of foo as expected.
>>
>> Since foo_ifunc isn't generated, you can't call foo_ifunc.
>
> So I guess mine is the fourth proposal. :-)  Same as 1, but also generate
> foo_ifunc, for example via an alias.
>

The ifunc function is for dynamic linker and dynamic linker only.
It shouldn't be called by anyone else.

--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Paolo Bonzini-3

>> So I guess mine is the fourth proposal. :-)  Same as 1, but also generate
>> foo_ifunc, for example via an alias.
>>
>
> The ifunc function is for dynamic linker and dynamic linker only.
> It shouldn't be called by anyone else.

And why? ;-)

Paolo
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Richard Henderson
In reply to this post by Paolo Bonzini-2
On 06/24/2009 03:22 AM, Paolo Bonzini wrote:

> Looks a bit too like DWIM and too little like a specification. I think I
> prefer option 1, in some cases you may want to call the trampoline and
> having it accessible can help. With
>
> __typeof (foo) *
> __attribute__ ((ifunc ("foo")))
> foo_ifunc (void)
> {
> <return address of foo_{1,2,3}>
> }
>
> you could call foo_ifunc if you wish in principle, and the header file
> only has the prototype of foo as expected.

I think I have to agree with you, Paolo.  This example is the sort of
thing I'd expect to actually be writing.


r~
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Richard Biener
On Wed, Jun 24, 2009 at 4:54 PM, Richard Henderson<[hidden email]> wrote:

> On 06/24/2009 03:22 AM, Paolo Bonzini wrote:
>>
>> Looks a bit too like DWIM and too little like a specification. I think I
>> prefer option 1, in some cases you may want to call the trampoline and
>> having it accessible can help. With
>>
>> __typeof (foo) *
>> __attribute__ ((ifunc ("foo")))
>> foo_ifunc (void)
>> {
>> <return address of foo_{1,2,3}>
>> }
>>
>> you could call foo_ifunc if you wish in principle, and the header file
>> only has the prototype of foo as expected.
>
> I think I have to agree with you, Paolo.  This example is the sort of
> thing I'd expect to actually be writing.

You wouldn't call foo_ifunc but maybe one of foo_{1,2,3} directly.  At
least for non-trivial foo_ifunc implementations.

I still fail to see why we need the ifunc argument here though.

__typeof (foo) *
__attribute__((ifunc))
foo_ifunc (void) asm("foo")
{
  <return address of foo_{1,2,3}>
}

works for me.  Adding __attribute__((alias("foo_ifunc"))) should
make an alias available that you could call directly if you really
want to.

Richard.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
In reply to this post by Paolo Bonzini-3
On Wed, Jun 24, 2009 at 7:48 AM, Paolo Bonzini<[hidden email]> wrote:

>
>>> So I guess mine is the fourth proposal. :-)  Same as 1, but also generate
>>> foo_ifunc, for example via an alias.
>>>
>>
>> The ifunc function is for dynamic linker and dynamic linker only.
>> It shouldn't be called by anyone else.
>
> And why? ;-)
>

It is by design.

--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
In reply to this post by Richard Biener
On Wed, Jun 24, 2009 at 8:09 AM, Richard
Guenther<[hidden email]> wrote:

> On Wed, Jun 24, 2009 at 4:54 PM, Richard Henderson<[hidden email]> wrote:
>> On 06/24/2009 03:22 AM, Paolo Bonzini wrote:
>>>
>>> Looks a bit too like DWIM and too little like a specification. I think I
>>> prefer option 1, in some cases you may want to call the trampoline and
>>> having it accessible can help. With
>>>
>>> __typeof (foo) *
>>> __attribute__ ((ifunc ("foo")))
>>> foo_ifunc (void)
>>> {
>>> <return address of foo_{1,2,3}>
>>> }
>>>
>>> you could call foo_ifunc if you wish in principle, and the header file
>>> only has the prototype of foo as expected.
>>
>> I think I have to agree with you, Paolo.  This example is the sort of
>> thing I'd expect to actually be writing.
>
> You wouldn't call foo_ifunc but maybe one of foo_{1,2,3} directly.  At
> least for non-trivial foo_ifunc implementations.
>
> I still fail to see why we need the ifunc argument here though.
>
> __typeof (foo) *
> __attribute__((ifunc))
> foo_ifunc (void) asm("foo")
> {
>  <return address of foo_{1,2,3}>
> }
>
> works for me.  Adding __attribute__((alias("foo_ifunc"))) should
> make an alias available that you could call directly if you really
> want to.
>

Is asm("foo") required for ifunc function?


--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Richard Biener
On Wed, Jun 24, 2009 at 5:19 PM, H.J. Lu<[hidden email]> wrote:

> On Wed, Jun 24, 2009 at 8:09 AM, Richard
> Guenther<[hidden email]> wrote:
>> On Wed, Jun 24, 2009 at 4:54 PM, Richard Henderson<[hidden email]> wrote:
>>> On 06/24/2009 03:22 AM, Paolo Bonzini wrote:
>>>>
>>>> Looks a bit too like DWIM and too little like a specification. I think I
>>>> prefer option 1, in some cases you may want to call the trampoline and
>>>> having it accessible can help. With
>>>>
>>>> __typeof (foo) *
>>>> __attribute__ ((ifunc ("foo")))
>>>> foo_ifunc (void)
>>>> {
>>>> <return address of foo_{1,2,3}>
>>>> }
>>>>
>>>> you could call foo_ifunc if you wish in principle, and the header file
>>>> only has the prototype of foo as expected.
>>>
>>> I think I have to agree with you, Paolo.  This example is the sort of
>>> thing I'd expect to actually be writing.
>>
>> You wouldn't call foo_ifunc but maybe one of foo_{1,2,3} directly.  At
>> least for non-trivial foo_ifunc implementations.
>>
>> I still fail to see why we need the ifunc argument here though.
>>
>> __typeof (foo) *
>> __attribute__((ifunc))
>> foo_ifunc (void) asm("foo")
>> {
>>  <return address of foo_{1,2,3}>
>> }
>>
>> works for me.  Adding __attribute__((alias("foo_ifunc"))) should
>> make an alias available that you could call directly if you really
>> want to.
>>
>
> Is asm("foo") required for ifunc function?

No.  You can as well, if you don't have a conflicting declaration,
just write

void *
__attribute__((ifunc))
foo (void)
{
  <return address of foo_{1,2,3}>
}

the asm() was just to allow the header to be visible.

Richard.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Jakub Jelinek
In reply to this post by H.J. Lu-30
On Wed, Jun 24, 2009 at 08:19:17AM -0700, H.J. Lu wrote:

> > I still fail to see why we need the ifunc argument here though.
> >
> > __typeof (foo) *
> > __attribute__((ifunc))
> > foo_ifunc (void) asm("foo")
> > {
> >  <return address of foo_{1,2,3}>
> > }
> >
> > works for me.  Adding __attribute__((alias("foo_ifunc"))) should
> > make an alias available that you could call directly if you really
> > want to.
> >
>
> Is asm("foo") required for ifunc function?

If you have foo prototype in current scope, yes, what's wrong with that
though?

        Jakub
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
On Wed, Jun 24, 2009 at 8:22 AM, Jakub Jelinek<[hidden email]> wrote:

> On Wed, Jun 24, 2009 at 08:19:17AM -0700, H.J. Lu wrote:
>> > I still fail to see why we need the ifunc argument here though.
>> >
>> > __typeof (foo) *
>> > __attribute__((ifunc))
>> > foo_ifunc (void) asm("foo")
>> > {
>> >  <return address of foo_{1,2,3}>
>> > }
>> >
>> > works for me.  Adding __attribute__((alias("foo_ifunc"))) should
>> > make an alias available that you could call directly if you really
>> > want to.
>> >
>>
>> Is asm("foo") required for ifunc function?
>
> If you have foo prototype in current scope, yes, what's wrong with that
> though?
>

Please move ifunc attribute discussion to

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40528

Thanks.


--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Roland McGrath
In reply to this post by Paolo Bonzini-2
I don't see why it should be quite so magical.  That is, I'd prefer the
definition of the address-returner to be more normal.  e.g.:

        static __typeof (foo) *
        foo_ifunc (void)
        {
          return &foo_1;
        }

        __typeof (foo) foo __attribute__ ((ifunc ("foo_ifunc")));

This is more like alias.  The upshot is that there is nothing special about
the definition of foo_ifunc.  It can be static or not as you want, its name
is a normal symbol.  Then the definition of the STT_IFUNC symbol is
separate and refers to that symbol.  Like an alias, it has to be defined in
the same module but the referenced symbol is not otherwise strange.  It can
complain if __typeof (foo) != (__typeof (foo_ifunc) *), but that is all.

If someone wants to make it exported or whatever, that is their business.
There is nothing untoward about it.  The definer of an STT_IFUNC symbol is
responsible for providing an entry point that is appropriate for the
dynamic linker's implicit calls.  But there is no reason at all that this
same entry point cannot have other uses if its author wants it to.


Thanks,
Roland
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Richard Biener
In reply to this post by H.J. Lu-30
On Wed, Jun 24, 2009 at 5:39 PM, H.J. Lu<[hidden email]> wrote:

> On Wed, Jun 24, 2009 at 8:22 AM, Jakub Jelinek<[hidden email]> wrote:
>> On Wed, Jun 24, 2009 at 08:19:17AM -0700, H.J. Lu wrote:
>>> > I still fail to see why we need the ifunc argument here though.
>>> >
>>> > __typeof (foo) *
>>> > __attribute__((ifunc))
>>> > foo_ifunc (void) asm("foo")
>>> > {
>>> >  <return address of foo_{1,2,3}>
>>> > }
>>> >
>>> > works for me.  Adding __attribute__((alias("foo_ifunc"))) should
>>> > make an alias available that you could call directly if you really
>>> > want to.
>>> >
>>>
>>> Is asm("foo") required for ifunc function?
>>
>> If you have foo prototype in current scope, yes, what's wrong with that
>> though?
>>
>
> Please move ifunc attribute discussion to
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40528

Sorry, but a bug is not the right place for discussion, the mailing list is.

Richard.

> Thanks.
>
>
> --
> H.J.
>
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
In reply to this post by Richard Biener
On Wed, Jun 24, 2009 at 8:20 AM, Richard
Guenther<[hidden email]> wrote:

> On Wed, Jun 24, 2009 at 5:19 PM, H.J. Lu<[hidden email]> wrote:
>> On Wed, Jun 24, 2009 at 8:09 AM, Richard
>> Guenther<[hidden email]> wrote:
>>> On Wed, Jun 24, 2009 at 4:54 PM, Richard Henderson<[hidden email]> wrote:
>>>> On 06/24/2009 03:22 AM, Paolo Bonzini wrote:
>>>>>
>>>>> Looks a bit too like DWIM and too little like a specification. I think I
>>>>> prefer option 1, in some cases you may want to call the trampoline and
>>>>> having it accessible can help. With
>>>>>
>>>>> __typeof (foo) *
>>>>> __attribute__ ((ifunc ("foo")))
>>>>> foo_ifunc (void)
>>>>> {
>>>>> <return address of foo_{1,2,3}>
>>>>> }
>>>>>
>>>>> you could call foo_ifunc if you wish in principle, and the header file
>>>>> only has the prototype of foo as expected.
>>>>
>>>> I think I have to agree with you, Paolo.  This example is the sort of
>>>> thing I'd expect to actually be writing.
>>>
>>> You wouldn't call foo_ifunc but maybe one of foo_{1,2,3} directly.  At
>>> least for non-trivial foo_ifunc implementations.
>>>
>>> I still fail to see why we need the ifunc argument here though.
>>>
>>> __typeof (foo) *
>>> __attribute__((ifunc))
>>> foo_ifunc (void) asm("foo")
>>> {
>>>  <return address of foo_{1,2,3}>
>>> }
>>>
>>> works for me.  Adding __attribute__((alias("foo_ifunc"))) should
>>> make an alias available that you could call directly if you really
>>> want to.
>>>
>>
>> Is asm("foo") required for ifunc function?
>
> No.  You can as well, if you don't have a conflicting declaration,
> just write
>
> void *
> __attribute__((ifunc))
> foo (void)
> {
>  <return address of foo_{1,2,3}>
> }
>
> the asm() was just to allow the header to be visible.
>

Option 3:

static int
foo1 (int x)
{
  return x;
}

int
__attribute__ ((ifunc))
foo (int)
{
  return foo1;
}

int
bar (int i)
{
  return foo (i);
}

supports C++ since we use the same prototype for ifunc function.
The mangled name is the same.


--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Paolo Bonzini-2
> static int
> foo1 (int x)
> {
>  return x;
> }
>
> int
> __attribute__ ((ifunc))
> foo (int)
> {
>  return foo1;
> }
>
> int
> bar (int i)
> {
>  return foo (i);
> }
>
> supports C++ since we use the same prototype for ifunc function.
> The mangled name is the same.

This feels too wrong.  The prototypes are magically changed beyond
what any other attribute does.  Look at what Roland posted.

Paolo
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
On Fri, Jun 26, 2009 at 8:04 AM, Paolo Bonzini<[hidden email]> wrote:

>> static int
>> foo1 (int x)
>> {
>>  return x;
>> }
>>
>> int
>> __attribute__ ((ifunc))
>> foo (int)
>> {
>>  return foo1;
>> }
>>
>> int
>> bar (int i)
>> {
>>  return foo (i);
>> }
>>
>> supports C++ since we use the same prototype for ifunc function.
>> The mangled name is the same.
>
> This feels too wrong.  The prototypes are magically changed beyond
> what any other attribute does.  Look at what Roland posted.
>

How do you propose to support C++?

--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Paolo Bonzini-2
> How do you propose to support C++?

Why wouldn't Roland's proposal work with C++?

Paolo
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

H.J. Lu-30
On Fri, Jun 26, 2009 at 8:47 AM, Paolo Bonzini<[hidden email]> wrote:
>> How do you propose to support C++?
>
> Why wouldn't Roland's proposal work with C++?
>

I am not sure it will work for C++, especially for
member functions.



--
H.J.
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: Add ifunc attribute

Richard Biener
On Fri, Jun 26, 2009 at 6:03 PM, H.J. Lu<[hidden email]> wrote:
> On Fri, Jun 26, 2009 at 8:47 AM, Paolo Bonzini<[hidden email]> wrote:
>>> How do you propose to support C++?
>>
>> Why wouldn't Roland's proposal work with C++?
>>
>
> I am not sure it will work for C++, especially for
> member functions.

asm() with a properly mangled name should work.

Richard.
123